设为首页 加入收藏

TOP

Android6.0 源码修改之 仿IOS添加全屏可拖拽浮窗返回按钮(一)
2019-08-30 07:27:50 】 浏览:85
Tags:Android6.0 源码 修改 IOS 添加 全屏可 返回 按钮

前言

之前写过屏蔽系统导航栏功能的文章,具体可看Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar

在某些特殊定制的版本中要求完全去掉导航栏,那么当用户点进一些系统自带的应用界面如设置、联系人等,就没法退出了,虽然可以在actionBar中添加back按钮,但总不能每一个app都去添加吧。所以灵机一动我们就给系统添加一个全屏可拖拽的浮窗按钮,点击的时候处理返回键的逻辑。它大概长这样(审美可能丑了点,你们可以自由发挥)

在这里插入图片描述
图1 最终效果图

思路分析

  1. 通过分析之前的NavigationBar代码,发现系统是通过WindowManager添加View的方式来实现,此处我们也可以模拟这种方法来添加
  2. 添加悬浮窗以后监听触摸事件,跟随手指移动重新修改view的layoutParam
  3. 松手后获取当前X坐标,小于屏幕width的一半则平移归位至屏幕左边
  4. 添加系统的返回按键功能

一、添加悬浮窗

private void showFloatingWindow() {
    DisplayMetrics outMetrics = new DisplayMetrics();
    mWindowManager.getDefaultDisplay().getMetrics(outMetrics);
    screenWidth = outMetrics.widthPixels;
    screenHeight = outMetrics.heightPixels;

    layoutParams = new WindowManager.LayoutParams();
    layoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
    layoutParams.format = PixelFormat.RGBA_8888;
    layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
    layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
    layoutParams.width = 100;
    layoutParams.height = 100;
    layoutParams.x = 200;
    layoutParams.y = 200;

    button = new ImageButton(mContext);
    button.setBackground(mContext.getResources().getDrawable(R.drawable.fab_background));//系统通讯录里的蓝色圆形图标
    button.setImageResource(R.drawable.ic_sysbar_back);//系统本身的back图标
    mWindowManager.addView(button, layoutParams);
    isShowFloatingView = true;
}

代码很简单,就是通过windowManager添加一个ImageButton,宽高都是100的,位置在屏幕左上角为原点的200,200。需要注意的是因为我们是在源码里添加,而且是M的版本,所以type为WindowManager.LayoutParams.TYPE_PHONE。如果是在普通的app里注意事项可参考这篇

二、添加触摸事件监听

button.setOnTouchListener(new FloatingOnTouchListener());

private class FloatingOnTouchListener implements View.OnTouchListener {
    private int lastX;
    private int lastY;

    @Override
    public boolean onTouch(View view, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                isDrag = false;
                lastX = (int) event.getRawX();
                lastY = (int) event.getRawY();
                break;

            case MotionEvent.ACTION_MOVE:
                isDrag = true;
                int nowX = (int) event.getRawX();
                int nowY = (int) event.getRawY();
                int movedX = nowX - lastX;
                int movedY = nowY - lastY;
                lastX = nowX;
                lastY = nowY;
                layoutParams.x = layoutParams.x + movedX;
                layoutParams.y = layoutParams.y + movedY;
                //获取当前手指移动的x和y,通过updateViewLayout方法将改变后的x和y设置给button
                mWindowManager.updateViewLayout(view, layoutParams);
                break;

            case MotionEvent.ACTION_UP:
                if (isDrag) {
                    log("lastX=" + lastX + "  screenWidth=" + screenWidth);
                    //手指抬起时,判断是需要滑动到屏幕左边还是屏幕右边
                    if (lastX >= screenWidth / 2) {
                        setAnimation(view, lastX, screenWidth);
                    } else {
                        setAnimation(view, -lastX, 0);
                    }
                }
                break;
        }
        //返回true则消费事件,返回false则传递事件,此处特殊处理是为了和点击事件区分
        return isDrag || view.onTouchEvent(event);
    }

三、添加抬起滑动归位动画

private void setAnimation(final View view, int fromX, int toX) {
        final ValueAnimator animator = ValueAnimator.ofInt(fromX, toX);
        if (Math.abs(fromX) < screenWidth / 4 || fromX > screenWidth * 3 / 4)
            animator.setDuration(300);
        else
            animator.setDuration(600);

        animator.setInterpolator(new LinearInterpolator());
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}
            @Override
            public void onAnimationEnd(Animator animation) {
                l
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Android新手引导库推荐 下一篇Android app去掉https签名校验

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目