【问题标题】:Android NavigationView: How do I handle / disable selection of the header layout?Android NavigationView:如何处理/禁用标题布局的选择?
【发布时间】:2015-07-03 01:37:03
【问题描述】:

我有一个简单的导航抽屉布局设置。我正在使用设计支持库,所以我有一个导航视图,它在支持库的工具栏上方滑动。但是,标题布局正在响应 UI 中的点击。当我点击它时,我得到了出现在标题布局后面的涟漪效应。我该如何执行以下任一操作:

  1. 一起禁用点击交互? (所以不会产生连锁反应)
  2. 响应点击交互。

我似乎找不到任何关于此的文档。

【问题讨论】:

    标签: android navigation-drawer material-design androiddesignsupport


    【解决方案1】:

    我注意到了同样的问题。该组件在内部使用 ListView(下面称为 menuView),遗憾的是没有选项可以禁用标题选择,因为它是硬编码的:

    this.mHeader = (LinearLayout)this.mLayoutInflater.inflate(layout.design_navigation_item_header, this.mMenuView, false);
    this.mMenuView.addHeaderView(this.mHeader);
    this.mMenuView.setAdapter(this.mAdapter);
    this.mMenuView.setOnItemClickListener(this);
    

    再加上 NavigationView 还有一个图标着色错误(在 22.2.0 版本中),我建议暂时不要使用它。

    【讨论】:

    • 你描述的着色错误是什么?
    【解决方案2】:

    这可能是该问题的解决方法:

    View headerView = getLayoutInflater().inflate(R.layout.header_nav, mNavigationView, false);
    mNavigationView.addHeaderView(headerView);
    
    //Use this if you don't want the click listener, 
    //be sure to use the appropriate background color 
    //((ViewGroup) headerView.getParent()).setBackgroundResource(R.color.background_material_light);
    
    //If you want your header to respond to clicks, this should suffice
    headerView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //Open to your implementation
        }
    });
    

    【讨论】:

      【解决方案3】:

      您可以覆盖布局资源“design_navigation_item_header”并添加背景颜色,然后您将看不到波纹。

      <LinearLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="@android:color/white"
          android:orientation="vertical"
          android:paddingBottom="@dimen/navigation_separator_vertical_padding"/>
      

      如果您想响应点击,您可以按 id 查找视图并添加 OnClickListener。

      【讨论】:

        【解决方案4】:

        razzledazzle's post 中获取提示,只需消耗 onClick 作品

        View headerView = LayoutInflater.from(getActivity()).inflate(R.layout.drawer_header_view, menuItemsNavigationView, false);
        
        headerView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Consume input from header view. This disables the ripple effect
            }
        });
        
        menuItemsNavigationView.addHeaderView(headerView);
        

        【讨论】:

          【解决方案5】:

          我刚刚在自己的应用程序中处理了这个问题。 NavigationView 是一个包裹在 ListView 周围的 ScrimInsetsFrameLayout,它显式地忽略(抛出)对列表第一项(即标题)的点击。

          但是,您可以通过使用自己的包装 NavigationView 的 onItemClickListener 来自己检索它们:

              ListView menuList = (ListView) navigationView.getChildAt(0);
              final AdapterView.OnItemClickListener nativeListener = menuList.getOnItemClickListener();
              menuList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                  @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                      if (position == 0) {
                          drawerLayout.closeDrawer(GravityCompat.START);
                          onUserClicked(prefs.getUser());
                      }
                      nativeListener.onItemClick(parent, view, position, id);
                  }
              });
          

          通常情况下,我不赞成这种依赖 Android 小部件内部的方式,但在这种情况下,它是支持库,它与您的应用一起打包和交付。从长远来看,构建自己的自定义导航视图可能会更好,但有时您需要快速修复!

          【讨论】:

            【解决方案6】:

            此页面上的所有解决方案都不适合我,而且可能是有充分理由的。正如 BladeCoder 所接受的答案所说,监听器被硬编码到 NavigationDrawer ListView 中,并且标题视图是 ListView 适配器的第 0 项。如果您想真正禁用它,那么简单地覆盖膨胀标题视图的 onClickListener 将不起作用,因为您需要为 ListView 的适配器项引用 onClickListener 而不仅仅是膨胀视图。

            以下解决方案适用于我禁止单击/点击标题视图,但它不会禁用可聚焦性(例如使用 d-pad 或键盘)。我似乎不知道怎么回事。

                //get the listview within the navigation drawer (0th child)
                ListView menuList = (ListView) mNavigationView.getChildAt(0);
            
                //get the header view (0th item in listview adapter)
                final View headerView = menuList.getAdapter().getView(0, null, null);
            
                if (headerView != null) {
                    headerView.setEnabled(false); //doesn't work, should
                    headerView.setFocusable(false); //doesn't work, should
                    headerView.setFocusableInTouchMode(false); //doesn't work, should
                    headerView.setClickable(false); //doesn't work, should
                    headerView.setOnClickListener(null); //WORKS! works to disallow clicking! is still focusable via keyboard
                }
            

            【讨论】:

              猜你喜欢
              • 2016-11-03
              • 2016-01-16
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多