android----侧边栏(DrawerLayout)(完美解决只能在边缘滑出)

一步一步
第一步: 创建空项目

image.png

第二步: 修改布局文件





    
        
    


    
        
    


此时app效果图为:


cebianlan_demo.gif

可以看到只能从边缘触发侧边栏, 想要类似qq侧边栏, 可以从中间滑出来, 网上有大部分有两种方法, 一种反射修改mEdgeSize的值来实现, 另一种通过activity事件分发配合mDrawerLayout.opDrawer(GravityCompat.START)来实现, 后者必须手指离开屏幕才能触发, 体验不好, 我们这里用第一种方法, 通过反射修改mEdgeSize的值

在onCreate()方法里进行编写

    DrawerLayout mDrawerLayout;//根布局
    LinearLayout mLinearLayout;//侧边栏布局
    View mContent;//主页面布局

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //--------------------START--------------------------------
        mDrawerLayout = findViewById(R.id.drawer_layout_root);//获取根布局
        mLinearLayout = findViewById(R.id.drawer_start);//获取侧边栏布局
        mContent = mDrawerLayout.getChildAt(0);//获取主页面布局, 可以看到主页面布局是父布局的第一个子布局, 可以这样获得, 也可以定义id

        try {
            Field leftDraggerField = mDrawerLayout.getClass().getDeclaredField("mLeftDragger");//通过反射获得DrawerLayout类中mLeftDragger字段
            leftDraggerField.setAccessible(true);//私有属性要允许修改
            ViewDragHelper vdh = (ViewDragHelper) leftDraggerField.get(mDrawerLayout);//获取ViewDragHelper的实例, 通过ViewDragHelper实例获取mEdgeSize字段
            Field edgeSizeField = vdh.getClass().getDeclaredField("mEdgeSize");//依旧是通过反射获取ViewDragHelper类中mEdgeSize字段, 这个字段控制边缘触发范围
            edgeSizeField.setAccessible(true);//依然是私有属性要允许修改
            int edgeSize = edgeSizeField.getInt(vdh);//这里获得mEdgeSize真实值
            Log.d("AAA", "mEdgeSize: "+edgeSize);//这里可以打印一下看看值是多少

            //Start 获取手机屏幕宽度,单位px
            Point point = new Point();
            getWindowManager().getDefaultDisplay().getRealSize(point);
            //End 获取手机屏幕

            Log.d("AAA", "point: "+point.x);//依然可以打印一下看看值是多少
            edgeSizeField.setInt(vdh, Math.max(edgeSize, point.x));//这里设置mEdgeSize的值!!!,Math.max函数取得是最大值,也可以自己指定想要触发的范围值,如: 500,注意单位是px
            //写到这里已经实现了,但是你会发现,如果长按触发范围,侧边栏也会弹出来,而且速度不太同步,稳定

            //Start 解决长按会触发侧边栏
            //长按会触发侧边栏是DrawerLayout类的私有类ViewDragCallback中的mPeekRunnable实现导致,我们通过反射把它置空
            Field leftCallbackField = mDrawerLayout.getClass().getDeclaredField("mLeftCallback");//通过反射拿到私有类ViewDragCallback字段
            leftCallbackField.setAccessible(true);//私有字段设置允许修改
            ViewDragHelper.Callback vdhCallback = (ViewDragHelper.Callback) leftCallbackField.get(mDrawerLayout);//ViewDragCallback类是私有类,我们返回类型定义成他的父类
            Field peekRunnableField = vdhCallback.getClass().getDeclaredField("mPeekRunnable");//我们依然是通过反射拿到关键字段,mPeekRunnable
            peekRunnableField.setAccessible(true);//不解释了
            //定义一个空的实现
            Runnable nullRunnable = new Runnable(){
                @Override
                public void run() {

                }
            };
            peekRunnableField.set(vdhCallback, nullRunnable);//给mPeekRunnable字段置空
            //End 解决长按触发侧边栏

        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        //--------------------END--------------------------------
    }

至此侧边栏边缘问题解决,与当前版本qq侧边栏一样


cebianlan_demo_finish.gif

原文链接:
完美开启DrawerLayout全屏手势侧滑 - (jianshu.com)
以上解决方案搬的是评论中 Febers 的评论!!!

你可能感兴趣的:(android----侧边栏(DrawerLayout)(完美解决只能在边缘滑出))