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

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 转笔实在是不会怎么办 滑板l轴承沾水了怎么办 暗影格斗3闪退怎么办 暗影格斗3文档被删怎么办 dnf手残党偷学技能学不了怎么办 打篮球没热身膝盖酸痛是怎么办 无线路由器lan口少怎么办? 电脑ip设置乱了怎么办 监控拍我我偷钱怎么办 网吧上网密码忘记了怎么办 比熊犬晚上叫怎么办 刚买的狗一直叫怎么办 酒驾罚款2年没交怎么办 法院判罚款没有钱怎么办 有人朝你吐口水怎么办 孕妇用了六神花露水怎么办 出车祸人不赔钱怎么办 交通事故对方保险不签字怎么办 肇事车主联系不上怎么办 商标被别人申请无效宣告怎么办 淘宝上传宝贝没有品牌怎么办 萌虎白卡借款2000逾期了怎么办 最里面的牙齿烂了怎么办 金龙沉底不游怎么办 龙鱼尾巴烂了怎么办 微博忘了登录名和密码怎么办 新浪微博密码忘了怎么办 vivo手机用户密码忘了怎么办 微博登录名忘记了怎么办 微信忘记密码钱怎么办 微信密码申诉失败怎么办 微博密码被盗了怎么办 对公密码器丢了怎么办 手机qq忘记旧密码怎么办 qq旧密码忘记了怎么办 微博账户密码忘记了怎么办 三星盖乐世s3忘记密码了怎么办 微博登录密码忘记了怎么办 助学贷款密码忘了怎么办 助学贷款的密码忘了怎么办 助学贷款登录密码忘了怎么办