如何在MenuItem上设置长按一下监听器(在NavigationView上)?

时间:2016-06-18 16:16:10

标签: android android-menu android-navigationview

如何在MenuItem上设置长按一下监听器?

我试过了this answer,但这个方法对我来说并不存在。任何解决方案?

代码:

Menu menu = navigationView.getMenu();
MenuItem menuItem = menu.findItem(R.id.menu_item);

// TODO set a long click listener on the menuItem.
menuItem.setOnLongClickListener(...); // Method does not exist, any other solutions?

编辑:我不想设置自定义ActionView,我想要整个MenuItem的长按一下监听器,而不需要自定义视图。

6 个答案:

答案 0 :(得分:6)

许多方法中的一种(假设我们使用工具栏) - 这个例子应该让您了解如何实现长按工具栏按钮:

class MyActivity extends Activity {    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        /** get menu inflater */
        MenuInflater menuInflater = getMenuInflater();
        /** Inflate the menu
         * this adds items to the action bar if it is present. */
        menuInflater.inflate(R.menu.menu_home, menu);
        /** find interesting item */
        MenuItem item = menu.findItem(R.id.itemId);
        /** set action view */
        item.setActionView(new ImageButton(this)); // this is a Context.class object
        /** set listener  on action view */
        item.getActionView().setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return false;
            }
        });

        return super.onCreateOptionsMenu(menu);
    }
}
方法 onCreateOptionsMenu中的

- 或者当你可以获得菜单项引用时的任何其他方法(省略步骤1-2)

  1. 创建菜单/例如通过inflate
  2. 获取菜单项
  3. 创建动作视图,例如ImageButton
  4. 在操作视图上设置长按侦听器
  5. 在菜单项上设置操作视图
  6. 上面我设置了一个动作视图然后我从菜单项中取回并设置了监听器(顺序无论是否也可以这样):

    ImageButton imageButton = new ImageButton(Context);
    imageButton.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    return false;
                }
            });
    item.setActionView(imageButton);
    

    PS。您还可以在xml中将图像视图设置为菜单项上的属性:

     <item
        ... 
        android:actionViewClass="android.widget.ImageButton"
     />
    
    then you can get the action view by cast 
    
       View menuItemActionView = menu.findItem(R.id.itemId).getActionView();
       if(menuItemActionView != null 
                && ImageButton.class.isAssignableFrom(menuItemActionView.getCLass())) {
            ImageButton imageButton = (ImageButton) menuItemActionView;
       }
    
      

    但是,您只需将长按侦听器设置为操作视图,而不是整个项目。 - SuperThomasLab

    - 不在单个元素上设置操作视图在这种情况下,您更改菜单项的默认视图(到ImageButton小部件) - 操作视图可以是简单或复杂的视图类型< / p>

      

    但是如果您不想更改视图,但保留默认视图呢? - SuperThomasLab

    示例(通过设置布局更改侦听器,这是使用布局树观察器>的许多的一种方式):

        private View.OnLongClickListener onLongClickListener = new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                return false;
            }
        };
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            /** get menu inflater */
            MenuInflater menuInflater = getMenuInflater();
            /** Inflate the menu
             * this adds items to the action bar if it is present. */
            menuInflater.inflate(R.menu.menu_home, menu);
            /** geta menu item using findItem(int itemid) */
            MenuItem item = menu.findItem(R.id.itemLogOut);
            /** check if we have item */
            if(item!=null) {
                /** try get its action view */
                View actionView = item.getActionView();
                 /** check if action view is already set? */
                if(actionView==null) {
                    /** get item id  to comparte later in observer listener*/
                    final int itemId = item.getItemId();
                    /** if not set on top most window an layout changes listener */
                    getWindow().getDecorView()
                               .addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                        @Override
                        public void onLayoutChange(View v, int left, int top, int right, 
                          int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                               /** try get view by id we have stored few line up */
                               View viewById = v.getRootView().findViewById(itemId);
                               /** check if we have any result */
                               if(viewById!=null) {
                                    /** set our listener */                     
                                    viewById.setOnLongClickListener(onLongClickListener);
                                    /** remove layout observer listener */
                                    v.removeOnLayoutChangeListener(this);
                               }
                        }
                    });
                } else {
                    /** if set we can add our on long click listener */
                    actionView.setOnLongClickListener(onLongClickListener);
                }
            }
      } 
    
      

    我尝试了OnLayoutChangeListener,但它仍然无法正常工作。 - SuperThomasLab

    是的, - 但我知道为什么它不适合你的情况??? - 在我的示例中,如果菜单视图布局,我们检查是否布置了视图项而不是该更改,然后检查菜单是否包含项

    这是您学习的工作代码:

    https://github.com/c3ph3us/LongClickOnMenuItem

    回复其他评论:

      

    @ SuperThomasLab对我来说,为什么setOnLongClickListener(...)方法不适合你并不明显。 - Hossein Seifi

    @HosseinSeifi - 看看android.view.MenuItem界面 - 它没有提供这样的方法 - 所以对于优秀的程序员来说这应该是显而易见的:)为什么他无法达到实现类方法。

答案 1 :(得分:1)

解决方案

这根本不是完美的,但是仍然比每个人的建议都要好,因为它适用于整个项目布局,而不仅适用于actionview的部分

通知:

  1. 我仅在MaterialComponents library中对其进行了测试 1.1.0-alpha08,所以我不能保证它将来会正常工作
  2. 我已经asked devs to provide better API为此,但我 不知道他们是否会成功
  3. index是项目的位置,但是它还包含以下位置:HeaderLayout,divider,Category(子菜单标题)

好吧,这是代码:

val navigationView = findViewById(R.id.navigation_view)
val navigationRecycler = navigationView[0] as RecyclerView //core-ktx extension for ViewGroup
val navigationLayoutManager = navigationRecycler.layoutManager as LinearLayoutManager
val navigationAdapter = navigationRecycler.adapter

if(navigationAdapter != null) {
    navigationRecycler.post { // this line is important
        for(index in 0 until navigationAdapter.itemCount) {
            val item = navigationLayoutManager.findViewByPosition(index)
            item?.setOnLongClickListener {
                Toast.makeText(this, "finally!", Toast.LENGTH_SHORT).show()
                true
            }
        }
    }
}

答案 2 :(得分:1)

您可以这样做:

        val homeTab = bottomNavigationView.findViewById<BottomNavigationItemView>(R.id.navigation_home) 
        //R.id.navigation_home id of navigation menu items you provided in menu file for BottomNavigationView

        homeTab.setOnLongClickListener {
              Toast.makeText(this@MainActivity,"Home Long clicked!",Toast.LENGTH_LONG).show()
              true
    }

答案 3 :(得分:0)

你可以这样做:

action_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:support="http://schemas.android.com/apk/res-auto" >

<item
    android:id="@+id/item1"
    support:showAsAction="always">
</item>

custom_action_view.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="10dp"
    android:paddingRight="5dp" >

<ImageButton
    android:id="@+id/customActionItem"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerVertical="true"
    android:background="@drawable/abc_item_background_holo_dark"
    android:src="@drawable/bulb_icon" />

</RelativeLayout>

和菜单inflater代码如下:

public boolean onCreateOptionsMenu(Menu menu) {
    // TODO Auto-generated method stub
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.action_menu, menu);     

    final MenuItem item1= menu.findItem(R.id.item1);
    MenuItemCompat.setActionView(item1, R.layout.custom_action_view);
    View vItem1= MenuItemCompat.getActionView(item1);

    final ImageButton customActionItem= (ImageButton) vItem1.findViewById(R.id.customActionItem);
    customActionItem.setOnLongClickListener(new OnLongClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            // do something here
        }
    });

    return super.onCreateOptionsMenu(menu);
}

答案 4 :(得分:0)

mBottomNavigationView.findViewById(menuItemId).setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return true;
    }
});

答案 5 :(得分:0)

出于answer的疯狂,这里略有不同,以菜单为目标。我也不认为这是稳定的,感觉像是一道险峻的景象,但将其嵌套在尝试中,保持冷静并继续前进:)

function changeData(e: any) {}