62.悬浮所有页面之上、可拖拽的交互按钮FloatDragView
来源:互联网 发布:淘宝usa商城假货 编辑:程序博客网 时间:2024/05/23 18:12
转载请注明出处 http://blog.csdn.net/qq_31715429/article/details/77895842
本文出自:猴菇先生的博客
一个项目在开发的过程中,网络请求一般使用的是测试地址,开发完成可能还有仿真环境地址,然后是正式地址。那么在开发和测试的过程中,就需要动态切换请求地址。这就需要一个类似Spinner的下拉框来完成这个功能,一开始我是写在Main页面,就一个简单的Spinner,但是限制是如果跳转到更深层次的页面,就切换不了链接地址了。这就需要使用WindowManager创建一个view,使之悬浮于所有activity之上,随时随地切换地址。效果如下:
有没有萌化你的少女心啊,哈哈。。
代码已上传至 https://github.com/MonkeyMushroom/FloatDragView
图片来自iconfont,仅供学习交流使用,不得用于商业用途。
1.创建一个FloatDragViewManager来管理WindowManager添加删除view
public class FloatDragViewManager implements FloatDragView.OnClickListener, FloatDragView.OnScrollListener { private WindowManager mWindowManager; private WindowManager.LayoutParams mFdvParams; private Context mContext; public void showFloatDragView() { mContext = BaseApplication.getInstance(); mWindowManager = (WindowManager) mContext.getSystemService(WINDOW_SERVICE); mFloatDragView = new FloatDragView(mContext);//是一个自定义的可拖拽的view,下面会写 mFloatDragView.setOnClickListener(this); mFloatDragView.setOnScrollListener(this); mFloatDragView.setText(mUrlArr[0]); mFdvParams = new WindowManager.LayoutParams(); mFdvParams.type = WindowManager.LayoutParams.TYPE_PHONE;//级别在activity之上 mFdvParams.format = PixelFormat.TRANSPARENT;//背景透明 mFdvParams.gravity = Gravity.LEFT | Gravity.TOP;//位置 mFdvParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; mFdvParams.width = WindowManager.LayoutParams.WRAP_CONTENT;//宽高 mFdvParams.height = WindowManager.LayoutParams.WRAP_CONTENT; mWindowManager.addView(mFloatDragView, mFdvParams); }}
别忘了要有权限
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
并在设置中也要找到该应用,打开悬浮窗权限。
我在Main页中显示悬浮窗:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mManager = new FloatDragViewManager(); mManager.showFloatDragView(); }
这时就应该可以看见了。
2.点击悬浮窗显示一个RecyclerView,提供点击事件改变链接地址:
private RecyclerView mSpinnerRv; private WindowManager.LayoutParams mRvParams; private String[] mUrlArr = new String[]{"测试", "正式", "仿真"}; private boolean mIsSpinnerShow;//列表是否显示的状态 @Override public void onClick() { if (mSpinnerRv == null) { mSpinnerRv = new RecyclerView(mContext); mSpinnerRv.setBackgroundResource(R.drawable.corner_cyan_bg); mSpinnerRv.setLayoutManager(new LinearLayoutManager(mContext)); mSpinnerRv.addOnItemTouchListener(new OnItemClickListener() { @Override public void onSimpleItemClick(BaseQuickAdapter adapter, View view, int position) { mFloatDragView.setText(mUrlArr[position]); Constant.BASE_URL = Constant.URL_ARR[position]; Toast.makeText(mContext, Constant.BASE_URL, Toast.LENGTH_SHORT).show(); mWindowManager.removeView(mSpinnerRv);//移除列表 mIsSpinnerShow = false; } }); mSpinnerRv.setAdapter(new DataAdapter()); } if (mIsSpinnerShow) {//移除列表 mWindowManager.removeView(mSpinnerRv); } else {//添加列表 mRvParams = new WindowManager.LayoutParams(); mRvParams.type = WindowManager.LayoutParams.TYPE_PHONE; mRvParams.gravity = Gravity.LEFT | Gravity.TOP; mRvParams.format = PixelFormat.TRANSPARENT; mRvParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; mRvParams.x = mFdvParams.x;//列表位置在FloatDragView之下 mRvParams.y = mFdvParams.y + mFloatDragView.getHeight(); mRvParams.width = mFloatDragView.getWidth(); mRvParams.height = WindowManager.LayoutParams.WRAP_CONTENT; mWindowManager.addView(mSpinnerRv, mRvParams); } mIsSpinnerShow = !mIsSpinnerShow; }
这时就已经可以实现点击切换地址了,但是不能拖动的话会挡住其他view
3.FloatDragView实现拖拽:
private float mTouchX; private float mTouchY; private float mStartX; private float mStartY; @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getRawX(); float y = event.getRawY() - getStatusBarHeight(getContext()); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mTouchX = event.getX(); mTouchY = event.getY(); mStartX = x; mStartY = y; break; case MotionEvent.ACTION_MOVE: if (mOnScrollListener != null) { mOnScrollListener.onScroll((int) (x - mTouchX), (int) (y - mTouchY)); } break; case MotionEvent.ACTION_UP: mTouchX = mTouchY = 0; if (Math.abs(x - mStartX) < 5 && Math.abs(y - mStartY) < 5) {// 用于区别是滑动了还是点击了 if (mOnClickListener != null) { mOnClickListener.onClick(); } } break; } return true; } /** * 滑动监听,供外部调用 */ public void setOnScrollListener(OnScrollListener onScrollListener) { mOnScrollListener = onScrollListener; } public interface OnScrollListener { void onScroll(int x, int y); }
在manager中:
/** * 滑动监听,动态改变按钮和列表的位置 */ @Override public void onScroll(int x, int y) { mFdvParams.x = x; mFdvParams.y = y; mWindowManager.updateViewLayout(mFloatDragView, mFdvParams);//更新位置 if (mIsSpinnerShow) {//如果列表显示的话 mRvParams.x = mFdvParams.x; mRvParams.y = mFdvParams.y + mFloatDragView.getHeight(); mWindowManager.updateViewLayout(mSpinnerRv, mRvParams); } }
4.最后在FloatDragViewManager中添加消除view的方法:
public void removeFloatDragView() { mWindowManager.removeView(mFloatDragView); if (mSpinnerRv != null && mIsSpinnerShow) { mWindowManager.removeView(mSpinnerRv); } }
在Main中调用:
@Override protected void onDestroy() { super.onDestroy(); mManager.removeFloatDragView(); }
代码已上传至 https://github.com/MonkeyMushroom/FloatDragView
- 62.悬浮所有页面之上、可拖拽的交互按钮FloatDragView
- 让组件悬浮所有页面之上
- 按钮操作DIV的打开与关闭(div悬浮于页面之上)
- 页面置顶的悬浮按钮
- 保持在所有窗口前方的悬浮按钮
- WindowManager——悬浮在所有app之上
- 令按钮悬浮在(手机)页面底部的方法
- 悬浮按钮和可交互提示
- Android自定义可拖拽的悬浮按钮---DragFloatingActionButton
- 实现可拖拽移动的悬浮按钮
- 悬浮的按钮
- 悬浮按钮的实现
- Android 可拖拽悬浮按钮
- jQuery_悬浮按钮控制页面滚动
- jq实现页面悬浮置顶按钮
- 基于Window的悬浮按钮
- Material风格的悬浮按钮
- 可拖动的悬浮按钮
- SNEC2017第十一届上海国际太阳能光伏展会刊(参展商名录)
- 如何优化tomcat配置(从内存、并发、缓存4个方面)优化
- 数据结构与算法(Python)
- ImportError:DLL load failed:找不到指定的程序
- linux下splint检测C语言代码质量
- 62.悬浮所有页面之上、可拖拽的交互按钮FloatDragView
- 推荐系统的常用算法
- centos7.2下安装mysql5.7,使用rpm包安装
- WebSocket 是什么原理?为什么可以实现持久连接?
- 跨域问题
- vptr指针
- 多台服务器日志查看
- CVE-2017-9805:Struts2 REST插件远程执行命令漏洞(S2-052) 分析报告
- Antenna Magus Professional