android WindowManager可拖动悬浮按钮
16lz
2022-01-09
代码地址
http://git.oschina.net/azure_sword/Sample_AS
可悬浮按钮的两种情况
1.当前页面悬浮
2.所有页面悬浮(包括系统页面)
注:第二种功能需要系统权限
android:name=”android.permission.SYSTEM_ALERT_WINDOW”
/**
* Created by zph on 2016/4/5.
*
* 当前页面悬浮按钮
*/
public class FloatView2 {
private Context c;
public FloatView2(Context c) {
this.c=c;
}
private WindowManager wm;private View view;// 浮动按钮/** * 添加悬浮View * @param paddingBottom 悬浮View与屏幕底部的距离 */public void createFloatView(int paddingBottom) { int w = 100;// 大小 wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE); view = LayoutInflater.from(c).inflate(R.layout.floatview, null); final WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;// 所有程序窗口的“基地”窗口,其他应用程序窗口都显示在它上面。 params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; params.format = PixelFormat.TRANSLUCENT;// 不设置这个弹出框的透明遮罩显示为黑色 params.width = w; params.height = w; params.gravity = Gravity.TOP | Gravity.LEFT; int screenWidth = c.getResources().getDisplayMetrics().widthPixels; int screenHeight = c.getResources().getDisplayMetrics().heightPixels; params.x = screenWidth - w; params.y = screenHeight - w - paddingBottom; view.setBackgroundColor(Color.TRANSPARENT); view.setVisibility(View.VISIBLE); view.setOnTouchListener(new View.OnTouchListener() { // 触屏监听 float lastX, lastY; int oldOffsetX, oldOffsetY; int tag = 0;// 悬浮球 所需成员变量 @Override public boolean onTouch(View v, MotionEvent event) { final int action = event.getAction(); float x = event.getX(); float y = event.getY(); if (tag == 0) { oldOffsetX = params.x; // 偏移量 oldOffsetY = params.y; // 偏移量 } if (action == MotionEvent.ACTION_DOWN) { lastX = x; lastY = y; } else if (action == MotionEvent.ACTION_MOVE) { params.x += (int) (x - lastX) / 3; // 减小偏移量,防止过度抖动 params.y += (int) (y - lastY) / 3; // 减小偏移量,防止过度抖动 tag = 1; wm.updateViewLayout(view, params); } else if (action == MotionEvent.ACTION_UP) { int newOffsetX = params.x; int newOffsetY = params.y; // 只要按钮一动位置不是很大,就认为是点击事件 if (Math.abs(oldOffsetX - newOffsetX) <= 20 && Math.abs(oldOffsetY - newOffsetY) <= 20) { onFloatViewClick(l); } else { tag = 0; } } return true; } }); wm.addView(view, params);}/** * 点击浮动按钮触发事件,需要override该方法 */private View.OnClickListener l;public void onFloatViewClick(View.OnClickListener l) { this.l=l; Toast.makeText(c, "FLOAT", Toast.LENGTH_SHORT).show(); view.setOnClickListener(l);}/** * 将悬浮View从WindowManager中移除,需要与createFloatView()成对出现 */public void removeFloatView() { if (wm != null && view != null) { wm.removeViewImmediate(view);
// wm.removeView(view);//不要调用这个,WindowLeaked
view = null;
wm = null;
}
}
/** * 隐藏悬浮View */public void hideFloatView() { if (wm != null && view != null&&view.isShown()) { view.setVisibility(View.GONE); }}/** * 显示悬浮View */public void showFloatView(){ if (wm != null && view != null&&!view.isShown()) { view.setVisibility(View.VISIBLE); }}
}
/**
* Created by zph on 2016/4/5.
*
* 全系统悬浮按钮
*/
public class FloatView extends ImageView {
private Context c;private float mTouchX;private float mTouchY;private float x;private float y;private int startX;private int startY;private int imgId = R.drawable.ic_launcher;private int controlledSpace = 20;private int screenWidth;private int screenHeight;boolean isShow = false;private OnClickListener mClickListener;private WindowManager windowManager;private WindowManager.LayoutParams windowManagerParams = new WindowManager.LayoutParams();public FloatView(Context context, AttributeSet attrs) { super(context, attrs);}public FloatView(Context c) { super(c); initView(c);}// 初始化窗体public void initView(Context c) { windowManager = (WindowManager) c.getApplicationContext() .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dm=getResources().getDisplayMetrics(); screenWidth = dm.widthPixels; screenHeight = dm.heightPixels; this.setImageResource(imgId); windowManagerParams.type = WindowManager.LayoutParams.TYPE_PHONE; windowManagerParams.format = PixelFormat.RGBA_8888; // 背景透明 windowManagerParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // 调整悬浮窗口至左上角,便于调整坐标 windowManagerParams.gravity = Gravity.LEFT | Gravity.TOP; // 以屏幕左上角为原点,设置x、y初始值 windowManagerParams.x = 0; windowManagerParams.y = screenHeight>>1; // 设置悬浮窗口长宽数据 windowManagerParams.width = WindowManager.LayoutParams.WRAP_CONTENT; windowManagerParams.height = WindowManager.LayoutParams.WRAP_CONTENT;}public void setImgResource(int id) { imgId = id;}@Overridepublic boolean onTouchEvent(MotionEvent event) { x = event.getRawX(); y = event.getRawY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: { mTouchX = event.getX(); mTouchY = event.getY(); startX = (int) event.getRawX(); startY = (int) event.getRawY(); break; } case MotionEvent.ACTION_MOVE: { updateViewPosition(); break; } case MotionEvent.ACTION_UP: { if (Math.abs(x - startX) < controlledSpace && Math.abs(y - startY) < controlledSpace) { if (mClickListener != null) { mClickListener.onClick(this); } }
// Log.i(“tag”, “x=” + x + ” startX+” + startX + ” y=” + y
// + ” startY=” + startY);
if (x <= screenWidth / 2) {
x = 0;
} else {
x = screenWidth;
}
updateViewPosition(); break; } } return super.onTouchEvent(event);}// 隐藏该窗体public void hide() { if (isShow) { windowManager.removeView(this); isShow = false; }}// 显示该窗体public void show() { if (isShow == false) { windowManager.addView(this, windowManagerParams); isShow = true; }}@Overridepublic void setOnClickListener(OnClickListener l) { this.mClickListener = l;}private void updateViewPosition() { // 更新浮动窗口位置参数 windowManagerParams.x = (int) (x - mTouchX); windowManagerParams.y = (int) (y - mTouchY); windowManager.updateViewLayout(this, windowManagerParams); // 刷新显示}
}
实现代码
public class FloatingButActivity extends BaseActivity {
@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_floating_but); floatView(); floatView2();}private FloatView floatView;private void floatView() { floatView = new FloatView(this); floatView.setImageResource(R.drawable.ic_launcher); floatView.show();}private FloatView2 floatView2;private void floatView2() { floatView2 = new FloatView2(this); floatView2.createFloatView(100);}@Overrideprotected void onDestroy() { super.onDestroy(); floatView2.removeFloatView(); floatView.hide();}
}
更多相关文章
- 【android】点击事件穿透解决方案
- Android(安卓)UI编程基础3
- Android跟软键盘的故事
- RadioGroup和RadioButton
- 系出名门Android(5) - 控件(View)之TextView, Button, ImageButt
- android drawing
- Android(安卓)开发实践 ViewGroup 实现左右滑出窗口(二)
- Design Widget
- Android(安卓)设置软键盘搜索键以及监听搜索键点击事件