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

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

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

    <!-- Main content view -->

    <ListView
        android:id="@+id/lst"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        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_width="300dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:clickable="true"
        android:background="@color/black" >

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

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

谢谢。

【问题讨论】:

    标签: android touch-event drawerlayout


    【解决方案1】:

    基于此解决方案:https://stackoverflow.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) 关闭抽屉之前将抽屉锁定模式设置为未定义。我发现没有这个抽屉一旦关闭就不会打开
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 2014-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多