【问题标题】:Android : Get view Reference to a Menu ItemAndroid:获取对菜单项的视图引用
【发布时间】:2012-01-26 17:01:42
【问题描述】:

我计划在我的应用程序中使用快速操作 UI 模式。 Android Quick Actions UI Pattern 。快速操作窗口需要一个枢轴视图才能坚持。

    quickAction.show(View pivotView);

我打算对菜单项使用快速操作,我可以访问被单击的项。 但问题是我需要从菜单项中引用一个视图,以便我可以将它传递给快速操作。

我如何获得对所选 menuItem 中的视图的引用。

【问题讨论】:

标签: android view menu menuitem quickaction


【解决方案1】:

您可以通过在 xml 中为您的菜单项提供一个 actionViewClass 属性来实现这一点,然后您将能够获得您想要的枢轴视图。代码会是这样的

<item
    android:id="@+id/menu_find"
    android:showAsAction="ifRoom"
    android:actionViewClass="android.widget.ImageButton"
    />

在您的 OnCreateOptionsMenu 中执行此操作

public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    getMenuInflater().inflate(R.menu.menu_search, menu);
    locButton = (ImageButton) menu.findItem(R.id.menu_find).getActionView();
    locButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            createPopup();
            mQuickAction.show(v);
        }
    });
    return true;
}

【讨论】:

  • 非常感谢!我遇到了一个奇怪的问题,即取景器在 android 4.1 上会在操作栏中找到一个微调器,但在 4.2 上它只是返回 null,这解决了它。
  • setOnMenuItemClickListener 对我有帮助,如果你想直接操作菜单项
  • 如果您使用最近的库,请使用 app:actionViewClass。 (res-auto)
【解决方案2】:

老问题,但我遇到了actionViewClass 属性的一些问题。对于以后遇到此问题的任何人...

onOptionsItemSelected 中调用findViewById(R.id.mnu_item) 将返回一个View 锚。

MenuItems 上的QuickActions 不是很好的设计,但我发现它们是实现具有自定义背景的子菜单的最简单方法。

【讨论】:

  • 我猜您需要至少单击一次“menuItem”才能获得“menuItem”“视图”锚点。
  • 对,findViewById() 调用必须在运行时完成
  • 感谢@ASH 如果我们放置 actionViewClass,答案将失败。这很好用。
【解决方案3】:

为其他原因(如我所愿)而想要找到菜单视图项的任何人提供更新。

如果您可以访问和使用 AppCompat 的工具栏,那么您有办法。这不是最有效的方法,但它是我发现访问菜单项视图的最简单方法。

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);

    // Find Menu
    for (int toolbarChildIndex = 0; toolbarChildIndex < toolbar.getChildCount(); toolbarChildIndex++) {
        View view = toolbar.getChildAt(toolbarChildIndex);

        // Found Menu
        if (view instanceof ActionMenuView) {
            ActionMenuView menuView = (ActionMenuView) view;

            // All menu items
            for (int menuChildIndex = 0; menuChildIndex < menuView.getChildCount(); menuChildIndex++) {
                ActionMenuItemView itemView = (ActionMenuItemView) menuView.getChildAt(menuChildIndex);
                // Do something to itemView...
            }
        }
    }
}

【讨论】:

    【解决方案4】:

    在主activity类中,最好重写onOptionsItemSelected(...)方法;应该是这样的:

    public boolean onOptionsItemSelected(MenuItem item) {
      // the id is of type int
      int someId = item.getItemId();
      // can use an if() or switch() statement to check if id is selected
      //a Toast message can be used to show item is selected
    }
    

    【讨论】:

      【解决方案5】:

      为了获取菜单项的参考视图,我们需要这样做,

      @Override
      public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.section, menu);
      
          new Handler().post(new Runnable() {
              @Override
              public void run() {
      
                  final View menuItemView = findViewById(R.id.action_preview);
                  // SOME OF YOUR TASK AFTER GETTING VIEW REFERENCE
      
              }
          });
      
      
          return true;
      }
      

      【讨论】:

      • 最好的方式,无需创建任何自定义视图和setactionview
      • 它太丑了(感谢 api)但这确实是有效的解决方案,非常感谢
      • 在 api 28 中不起作用
      【解决方案6】:

      同样适用于 Android 10 的通用代码

      /**
      * pass toolbar and menu item id, i.e. R.id.menu_refresh
      */
      @Nullable
      @Throws(
          IllegalAccessException::class,
          NoSuchFieldException::class
      )
      fun getMenuItemView(toolbar: Toolbar?, @IdRes menuItemId: Int): View? {
          val mMenuView: Field = Toolbar::class.java.getDeclaredField("mMenuView")
          mMenuView.setAccessible(true)
          val menuView: Any? = mMenuView.get(toolbar)
          (menuView as ViewGroup).children.forEach {
              if(it.id == menuItemId) {
                  return it
              }
          }
          return null
      }
      

      【讨论】:

        【解决方案7】:

        科特林!!

        override fun onCreateOptionsMenu(Menu menu): Boolean {
        
          /*Adding menu items to action bar*/
          menuInflater.inflate(R.menu.main, menu)
        
          /*Getting menu item*/
          val locButton: MenuItem = menu.findItem(R.id.menu_find)
        
          /*Creating click listener*/
          locButton.setOnMenuItemClickListener{
            /*TODO: Handle it*/
            true
          }
        
          return true;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-06-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-06-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多