本文将带您了解关于Android利用WindowManager实现悬浮窗的新内容,同时我们还将为您解释androidwindowmanager悬浮的相关知识,另外,我们还将为您提供关于AndroidA
本文将带您了解关于Android利用WindowManager实现悬浮窗的新内容,同时我们还将为您解释android windowmanager悬浮的相关知识,另外,我们还将为您提供关于Android Activity源码分析--windowmanager屏幕旋转研究、Android EditText 自动拼写检查报错:android.view.WindowManag、Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能、Android ViewManager实例的实用信息。
本文目录一览:- Android利用WindowManager实现悬浮窗(android windowmanager悬浮)
- Android Activity源码分析--windowmanager屏幕旋转研究
- Android EditText 自动拼写检查报错:android.view.WindowManag
- Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能
- Android ViewManager实例
Android利用WindowManager实现悬浮窗(android windowmanager悬浮)
不废话,四步走:
1、首先要声明悬浮窗口权限:
<uses-permission android:name="android.permission.SYstem_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYstem_OVERLAY_WINDOW"/>
2、引导用户打开悬浮窗权限:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
showTip("请先打开悬浮窗权限");
startActivityForResult(new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + getPackageName())), 0);
} else {
//有权限了,可以用service或者直接用第三步开启悬浮窗
}
}
3、初始化悬浮窗:
private void initFloatingWindow() {
if (Settings.canDrawOverlays(this)) {
// 获取WindowManager服务
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
//FloatView为自定义的悬浮窗控件,亦可使用Button、ImageView之类的控件
floatView = new FloatView(getApplicationContext());
// 设置LayoutParam
layoutParams = new WindowManager.LayoutParams();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
// 实现悬浮窗可以移动的属性(把这个值改成其他值可以操作悬浮窗底下的内容)
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
layoutParams.format = PixelFormat.TRANSPARENT;
layoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
layoutParams.gravity = Gravity.CENTER;
layoutParams.x = 0;
layoutParams.y = 0;
//todo
//对你的悬浮窗做一些点击或移动事件的处理
}
}
layoutParams.flags的值选择参考:https://www.jianshu.com/p/c91448e1c7d1
4、显示和隐藏悬浮窗:
//显示悬浮窗(添加悬浮窗控件)
windowManager.addView(floatView, layoutParams);
//隐藏悬浮窗(移除悬浮窗控件)
windowManager.removeView(floatView);
//更新悬浮窗控件布局(对悬浮窗做修改之后调用)
windowManager.updateViewLayout(floatView, layoutParams);
至于悬浮控件的移动,悬浮窗控件设置一个OnTouchListener事件:
floatView.setonTouchListener(new View.OnTouchListener() {
private int x;
private int y;
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
x = (int) event.getRawX();
y = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
int NowX = (int) event.getRawX();
int NowY = (int) event.getRawY();
int movedX = NowX - x;
int movedY = NowY - y;
x = NowX;
y = NowY;
layoutParams.x = layoutParams.x + movedX;
layoutParams.y = layoutParams.y + movedY;
// 更新悬浮窗控件布局
windowManager.updateViewLayout(floatView, layoutParams);
break;
default:
break;
}
return false;
}
});
但是这样实现的却是整屏控制悬浮窗的移动,并不能很好的实现在悬浮窗上面拖动的效果,这个我还得再研究研究,也望各位大佬指点指点。
完。
Android Activity源码分析--windowmanager屏幕旋转研究
注意:鄙人看的是6.0的代码
Activity里面还是调用了WindowManager来显示界面。在activity的738行,有这几行代码
private Window mWindow;
private WindowManager mWindowManager;
/*package*/ View mDecor = null; //这就是activity的主view,我也不知道怎么表达会比较好 = =
平常用的setContentView方法,最终是调用了mWindow来处理的。
public void setContentView(@LayoutRes int layoutResID) {
getWindow().setContentView(layoutResID);
initWindowDecorActionBar();
}
mWindow其实一个 PhoneWindow对象,在6169行的attach方法可是看到它的初始化
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, String referrer, IVoiceInteractor voiceInteractor) {
attachBaseContext(context);
mFragments.attachHost(null /*parent*/);
mWindow = new PhoneWindow(this);//我在这里
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
...
}
其中mWindowManager是通过mWindow来实现初始化
mWindowManager = mWindow.getWindowManager();
接着看看activity是怎么调用mWindowManager来显示界面,在源码第4772行,可以看到一个setVisible方法,这就是activity展示界面的入口吧
public void setVisible(boolean visible) {
if (mVisibleFromClient != visible) {
mVisibleFromClient = visible;
if (mVisibleFromServer) {
if (visible) makeVisible();//我将要展示界面
else mDecor.setVisibility(View.INVISIBLE);
}
}
}
接着看看makeVisible方法是怎么调用mWindowManager来显示界面。没错,其实就是用addview来显示界面。
void makeVisible() {
if (!mWindowAdded) {
ViewManager wm = getWindowManager();
wm.addView(mDecor, getWindow().getAttributes());
mWindowAdded = true;
}
mDecor.setVisibility(View.VISIBLE);
}
为什么activity能通过android:configChanges="orientation|keyboardHidden" ,能保证界面不重建呢,我们可以看到源码还有一个onWindowAttributesChanged方法。
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
// Update window manager if: we have a view, that view is
// attached to its parent (which will be a RootView), and
// this activity is not embedded.
if (mParent == null) {
View decor = mDecor;
if (decor != null && decor.getParent() != null) {
getWindowManager().updateViewLayout(decor, params);
}
}
}
我估计是用了updateViewLayout来刷新页面,单纯看到这里,activity是怎么监听屏幕旋转呢?
Android EditText 自动拼写检查报错:android.view.WindowManag
需要给EditText设置inputtype属性,将自动拼写检查屏蔽掉.
android:inputType="textNoSuggestions"
Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能
由于项目没有设计返回键,一旦进入别的应用,就无法回到桌面。只能通过串口输入input keyevent 4(返回键)来返回桌面,为了方便调试,在Framework 中监听手势,实现返回功能。
在frameworks\base\services\core\java\com\android\server\policy\PhoneWindowManager中有这么一段代码
mSystemGestures = new SystemGesturesPointerEventListener(context, new SystemGesturesPointerEventListener.Callbacks() { @Override public void onSwipeFromTop() { Log.i("gyx","onSwipeFromTop"); if (mStatusBar != null) { requestTransientBars(mStatusBar); } } @Override public void onSwipeFromBottom() { Log.i("gyx","onSwipeFromBottom"); if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) { requestTransientBars(mNavigationBar); } } @Override public void onSwipeFromRight() { Log.i("gyx","onSwipeFromRight"); sendKeyCode(4); Log.i("gyx","sendKeyCode 4"); if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) { requestTransientBars(mNavigationBar); } } @Override public void onSwipeFromLeft() { Log.i("gyx","onSwipeFromLeft"); if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) { requestTransientBars(mNavigationBar); } } @Override public void onFling(int duration) { if (mPowerManagerInternal != null) { mPowerManagerInternal.powerHint( PowerHint.INTERACTION, duration); } } @Override public void onDebug() { // no-op } @Override public void onDown() { mOrientationListener.onTouchStart(); } @Override public void onUpOrCancel() { mOrientationListener.onTouchEnd(); } @Override public void onMouseHoverAtTop() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS; mHandler.sendMessageDelayed(msg, 500); } @Override public void onMouseHoverAtBottom() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS); msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION; mHandler.sendMessageDelayed(msg, 500); } @Override public void onMouseLeaveFromEdge() { mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS); } });
代码中监听了手势操作,其中onSwipeFromRight()
就是当从屏幕的右侧向左滑动时会触发,只要在这里加入返回的功能即可;
实现返回按键的功能代码如下
private void sendKeyCode(final int keyCode) { new Thread(new Runnable() { @Override public void run() { try { // 创建一个Instrumentation对象 Instrumentation inst = new Instrumentation(); // 调用inst对象的按键模拟方法 inst.sendKeyDownUpSync(keyCode); } catch (Exception e) { e.printStackTrace(); } } }).start(); }
总结
到此这篇关于Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能的文章就介绍到这了,更多相关Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
- Android如何监听屏幕旋转
- Android 监听屏幕是否锁屏的实例代码
- Android 屏幕切换监听的实例代码
- 封装的android监听手指左右滑动屏幕的事件类分享
- Android实现屏幕旋转四个方向准确监听
Android ViewManager实例
LinearLayout实现了ViewManager接口。
当LinearLayout调用addView (View view, ViewGroup.LayoutParams params)方法后,LinearLayout中会增加一个子视图,并重新绘制自己。子视图的布局参数是在addView()方法中指定的params。
LinearLayout调用removeView (View view)方法后,LinearLayout会移除view所引用的实例,并重新绘制自己。view必须是LinearLayout中某个子视图对象实例的引用。
LinearLayout调用UpdateViewLayout (View view, ViewGroup.LayoutParams params),会使得view所引用的实例使用params重
ViewManagerDemo.Java如下:
<!-- lang: java -->
packagedev.demo;
importjava.util.LinkedList;
importandroid.app.Activity;
importandroid.content.Context;
importandroid.os.Bundle;
importandroid.view.Gravity;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.view.ViewGroup.LayoutParams;
importandroid.widget.Button;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;
publicclassViewManagerDemoextendsActivity{
/**Calledwhentheactivityisfirstcreated.*/
ButtonaddViewButton;
ButtonremoveViewButton;
LinearLayoutmyLayout;
privateLinkedList<TextView>textViews;
booleanisEdited=false;
Contextcontext;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textViews=newLinkedList<TextView>();
findViews();
setListeners();
context=this;
}
privatevoidfindViews(){
addViewButton=(Button)this.findViewById(R.id.addView);
removeViewButton=(Button)this.findViewById(R.id.removeView);
myLayout=(LinearLayout)this.findViewById(R.id.liLayout);
textViews.addFirst((TextView)this.findViewById(R.id.textView_1));
textViews.addFirst((TextView)this.findViewById(R.id.textView_2));
textViews.addFirst((TextView)this.findViewById(R.id.textView_3));
}
privatevoidsetListeners(){
if(addViewButton!=null){
this.addViewButton.setOnClickListener(newView.OnClickListener(){
publicvoidonClick(Viewv){
TextViewmyTextView=newTextView(context);
myTextView.setText("IamnewTextView.");
myTextView.setGravity(Gravity.CENTER);
textViews.addFirst(myTextView);
myLayout.addView(myTextView,
newViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
//调用addView
if(!isEdited){
isEdited=true;
myLayout.updateViewLayout(textViews.getLast(),
newLinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));
}
}
});
}
if(removeViewButton!=null){
this.removeViewButton.setOnClickListener(newView.OnClickListener(){
publicvoidonClick(Viewv){
TextViewtView=textViews.remove();
myLayout.removeView(tView);//移除View
if(isEdited){
isEdited=false;
myLayout.updateViewLayout(textViews.getLast(),
newLinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
}
}
});
}
}
}
main.xml如下:
<!-- lang: java -->
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/addView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="增加一个TextView"
/>
<Button
android:id="@+id/removeView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除一个TextView"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/liLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextViewNo.1"/>
<TextView
android:id="@+id/textView_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="TextViewNo.2"/>
<TextView
android:id="@+id/textView_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextViewNo.3"/>
</LinearLayout>
</LinearLayout>
移动开发交流群:164427941
今天关于Android利用WindowManager实现悬浮窗和android windowmanager悬浮的讲解已经结束,谢谢您的阅读,如果想了解更多关于Android Activity源码分析--windowmanager屏幕旋转研究、Android EditText 自动拼写检查报错:android.view.WindowManag、Android PhoneWindowManager监听屏幕右侧向左滑动实现返回功能、Android ViewManager实例的相关知识,请在本站搜索。
本文标签: