DrawerLayout 与 Horizo​​ntalScrollView 进入内容菜单

Posted

技术标签:

【中文标题】DrawerLayout 与 Horizo​​ntalScrollView 进入内容菜单【英文标题】:DrawerLayout with HorizontalScrollView into content menu 【发布时间】:2014-03-07 09:32:37 【问题描述】:

我的问题很简单。我可以在 DrawerLayout 的内容菜单中使用 Horizo​​ntalScrollView 吗? 我的 DrawerLayout 看起来像这样:

<android.support.v4.widget.DrawerLayout
    android:id="@+id/pnlMenu"
    android:layout_
    android:layout_ >

    <!-- Main content view -->

    <ListView
        android:id="@+id/lst"
        android:layout_
        android:layout_
        android:clickable="true"
        android:fastScrollEnabled="true"
        android:focusable="true"
        android:focusableInTouchMode="true"
        tools:listitem="@layout/item_layout" >
    </ListView>

    <!-- Content of menu -->

    <FrameLayout
        android:id="@+id/drawerFrame"
        android:layout_
        android:layout_
        android:layout_gravity="start"
        android:clickable="true"
        android:background="@color/black" >

        <fragment
            android:id="@+id/frag"
            android:layout_
            android:layout_
            class="com.test.TestFragment" />
    </FrameLayout>
</android.support.v4.widget.DrawerLayout>

在片段内部,我有 Horizo​​ntalScrollView,但是当我尝试触摸它时没有任何反应,因为抽屉布局跟随我的手指。 我认为禁用内容菜单中的触摸事件并仅在单击主要内容视图时使 DrawerLayout 可关闭将解决我的问题。真的吗?如果没有,谁能告诉我该怎么办?

谢谢。

【问题讨论】:

【参考方案1】:

基于此解决方案:https://***.com/a/7258579/452486

我已经能够使HorizontalScrollView 可滚动。 创建一个类扩展DrawerLayout

public class AllowChildInterceptTouchEventDrawerLayout extends DrawerLayout 

    private int mInterceptTouchEventChildId;

    public void setInterceptTouchEventChildId(int id) 
       this.mInterceptTouchEventChildId = id;
    

    public AllowChildInterceptTouchEventDrawerLayout(Context context) 
    super(context);
    

    public AllowChildInterceptTouchEventDrawerLayout(Context context, AttributeSet attrs) 
        super(context, attrs);
    

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) 

        if (mInterceptTouchEventChildId > 0) 
            View scroll = findViewById(mInterceptTouchEventChildId);
            if (scroll != null) 
                Rect rect = new Rect();
                scroll.getHitRect(rect);
                if (rect.contains((int) ev.getX(), (int) ev.getY())) 
                    return false;
                
            
        
        return super.onInterceptTouchEvent(ev);

        
    

并添加要拦截drawerlayout触摸事件的child id

AllowChildInterceptTouchEventDrawerLayout drawerLayout = (AllowChildInterceptTouchEventDrawerLayout) findViewById(R.id.layoutdrawer_id);
drawerLayout.setInterceptTouchEventChildId(R.id.horizontalscrollview_id);

【讨论】:

我没有测试过,但这应该是一个可行的答案,我猜。 这对我有用,但如果像我的一样,您的 ScrollViewinclude 内,请务必以包含为目标。否则它不会触发命中。 我用这个,但我得到了 classCastException【参考方案2】:

最好设置requestDisallowInterceptTouchEvent(true) 标志而不是返回false。当我们有一个HorizontalScrollView 并且在它下面有另一个视图(例如ListView 带有一些菜单项)并且我们从HorizontalScrollView 区域到上述ListView 进行动态手势时,应用程序将因NPE 而崩溃。这种情况发生在您第一次打开应用程序并通过汉堡图标转到DrawerLayout 时。使用这个:

if (rect.contains((int) ev.getX(), (int) ev.getY()))      
    this.requestDisallowInterceptTouchEvent(true);

【讨论】:

【参考方案3】:

如果您想在您的DrawerLayout 中包含HorizontalScrollView,那么到目前为止所有答案的替代策略是在打开抽屉时锁定抽屉。这意味着用户将无法通过滑动关闭抽屉,但 HorizontalScrollView 内部的滚动将按预期工作。

通过调用实现加锁

mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN);

这个电话的一个方便的地方是onDrawerOpened

不幸的是,当用户点击稀松布(屏幕的暗淡部分未被抽屉占用)时,锁定还可以防止抽屉关闭。您需要自己抓住那个水龙头并关闭它,如下所示:

mDrawerLayout.setOnTouchListener(new View.OnTouchListener() 
    @Override
    public boolean onTouch(View v, MotionEvent event) 
        int x = (int) event.getX();
        int drawerWidth = (int)getResources().getDimension(R.dimen.your_drawer_width);
        if (x > drawerWidth) 
            // inside scrim
            mDrawerLayout.closeDrawer();
            return true;
        
        return false;
    
); 

【讨论】:

简单的解决方案。此外,您需要在mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNDEFINED) 关闭抽屉之前将抽屉锁定模式设置为未定义。我发现没有这个抽屉一旦关闭就不会打开

以上是关于DrawerLayout 与 Horizo​​ntalScrollView 进入内容菜单的主要内容,如果未能解决你的问题,请参考以下文章

android ToolBar与DrawerLayout笔记

android 应用架构随笔五(ActionBar与侧滑菜单DrawerLayout)

android官方侧滑菜单DrawerLayout详解

Android 中 DrawerLayout + ViewPager 怎么解决滑动冲突

SwiftUI 列表视图与 GroupedListStyle 和 Horizo​​ntalSizeClass 在 iOS 13.5 上切换到横向模式时定期中断

使用 DrawerLayout 打开 Activity 时如何消除延迟?