Android Fragments 使片段在导航抽屉打开时可点击

6mw9ycah  于 2022-11-24  发布在  Android
关注(0)|答案(3)|浏览(141)

我的问题如下:我在平板电脑的横向模式下锁定了导航抽屉菜单setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN),但我需要右侧的片段处于活动状态,这样我就可以在导航始终打开的情况下单击它。但我不知道如何操作。请帮助。

mec1mxoz

mec1mxoz1#

您需要执行以下操作:
1.通过设置透明颜色禁用布局淡入淡出:

drawer.setScrimColor(Color.TRANSPARENT);

1.锁定抽屉

drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);

1.创建一个自定义抽屉类,允许在锁定模式下单击:

public class CustomDrawer extends DrawerLayout {

    public CustomDrawer(Context context) {
        super(context);
    }

    public CustomDrawer(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomDrawer(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        View drawer = getChildAt(1);

        if (getDrawerLockMode(drawer) == LOCK_MODE_LOCKED_OPEN && ev.getRawX() > drawer.getWidth()) {
            return false;
        } else {
            return super.onInterceptTouchEvent(ev);
        }
    }

}

1.在xml中使用此类:

<com.example.myapplication.CustomDrawer
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!-- The main content view -->
    </FrameLayout>
    <ListView android:layout_width="100dp"
              android:layout_height="match_parent"
              android:layout_gravity="start"
              android:background="#111"/>
</com.example.myapplication.CustomDrawer>
hk8txs48

hk8txs482#

这是一个棘手的问题。当抽屉打开时,它会拦截触发抽屉关闭的触摸事件。为了防止这种情况发生,您需要将DrawerLayout子类化并覆盖onInterceptTouchEvent方法:

public class CustomDrawerLayout extends DrawerLayout
{
    private View rightView;
    private int mTouchSlop;

    public CustomDrawerLayout (Context context)
    {
        this(context, null);
    }

    public CustomDrawerLayout (Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public CustomDrawerLayout (Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(ViewConfiguration.get(context));
    }

    public void setRightView (View v)
    {
        this.rightView = v;
    }

    @Override
    public boolean onInterceptTouchEvent (MotionEvent ev)
    {
        boolean result = super.onInterceptTouchEvent(ev);

        if (rightView != null && isDrawerOpen(rightView))
        {
            DrawerLayout.LayoutParams layoutParams = (DrawerLayout.LayoutParams) rightView.getLayoutParams();

            if (layoutParams.gravity == Gravity.END)
            {
                // This is true when the position.x of the event is happening on the left of the drawer (with gravity END)
                if (ev.getX() < rightView.getX() && ev.getX() > mTouchSlop)
                {
                    result = false;
                }
            }
        }

        return result;
    }
}

这是我在右边抽屉上的代码。我相信你可以把它应用到左边的抽屉上。你可能还想禁用阴影:

mDrawerLayout.setScrimColor(Color.TRANSPARENT);
ycl3bljg

ycl3bljg3#

感谢@Simas的解决方案!
我发现如果用户点击的项目离drawerView很近,使用ev.rawX是不合适的。此外,我添加了其他重力检查来确定拦截。

class ContentTouchableDrawer @JvmOverloads constructor(
    context: Context, attrs: AttributeSet? = null
) : DrawerLayout(context, attrs) {

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        val drawer: View = getChildAt(1)
        logt("drawer : $drawer")
        logt("drawer : width = ${drawer.width}")
        logt("drawer : x = ${drawer.x}")
        logt("drawer : eventRawX = ${ev.rawX}")
        logt("drawer : eventX = ${ev.x}")

        val drawerGravity = (drawer.layoutParams as LayoutParams).gravity
        val result = when(drawerGravity){
            Gravity.RIGHT, GravityCompat.END -> ev.x < drawer.x
            Gravity.LEFT, GravityCompat.START -> ev.x > drawer.width
            //Gravity.NO_GRAVITY
            else -> false
        }

        return if (getDrawerLockMode(drawer) == LOCK_MODE_LOCKED_OPEN && result) {
            false
        } else {
            super.onInterceptTouchEvent(ev)
        }
    }

}

相关问题