长按Android菜单项?

p4tfgftt  于 2023-03-21  发布在  Android
关注(0)|答案(4)|浏览(218)

是否可以长按某个菜单项来执行某个操作?我尝试在长按某个菜单项时显示下拉菜单。
下面是菜单xml

<item
    android:id="@+id/add_item"
    android:icon="@drawable/ic_add_black_24dp"
    android:showAsAction="ifRoom"
    android:title="Add Item">
</item>

<item
    android:id="@+id/open_menu"
    android:icon="@drawable/ic_menu_black_24dp"
    android:showAsAction="ifRoom|withText"
    android:title="Open Menu">
</item>

我希望在长按第一项时显示下拉菜单

yv5phkfx

yv5phkfx1#

您可以使用HandlerRunnable执行此操作。在run()方法中,获取所需MenuItemView,并将onLongClick侦听器设置为View

以下是工作代码:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            final View view = findViewById(R.id.add_item);

            if (view != null) {
                view.setOnLongClickListener(new View.OnLongClickListener() {
                    @Override
                    public boolean onLongClick(View v) {

                        // Do something...

                        Toast.makeText(getApplicationContext(), "Long pressed", Toast.LENGTH_SHORT).show();
                        return true;
                    }
                });
            }
        }
    });

    return super.onCreateOptionsMenu(menu);
}

输出:

drkbr07n

drkbr07n2#

轻松使用Kotlin(并保持与其他图标相同的风格):

fun MenuItem.onMenuItemLongClickListener(menu: Menu, function: () -> (Unit)) {
    setActionView(R.layout.view_action_button)
    actionView.find<ImageButton>(R.id.item).setImageDrawable(icon)
    actionView.setOnLongClickListener {
        function()
        true }
    actionView.setOnClickListener { menu.performIdentifierAction(itemId, 0) }
}

view_action_button.xml

<?xml version="1.0" encoding="utf-8"?>

<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/item"
    style="?android:attr/actionButtonStyle"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

用法:

menu.findItem(R.id.your_item).onMenuItemLongClickListener(menu) { anyFunction() }

只需更改R.id.your_itemanyFunction()

uurity8g

uurity8g3#

下面是您问题的另一个解决方案。我使用了res/menu/menu.xml中的一个菜单,如下所示:

<menu xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/action_send"
        android:orderInCategory="100"
        android:title="@string/send_menu"
        app:showAsAction="always" />
</menu>

这是我的活动类,我在菜单项中添加了一个imagebutton,并为其设置了一个图像资源,Backgrod设置为null,以使menuItem透明。

public class MyActivity extends AppCompatActivity {
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu, menu);
        MenuItem item = menu.findItem(R.id.action_send);
        ImageButton imageButton = new ImageButton(this);
        imageButton.setImageResource(R.drawable.ic_send_white_24dp);
        imageButton.setBackground(null);
        item.setActionView(imageButton);
        item.getActionView().setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                Log.d("Send Button", "Long pressed");
                Toast.makeText(MainActivity.this, "Send button long pressed", Toast.LENGTH_LONG).show();
                onSendMenuItemLongClick();
                return true;
            }
        });

        item.getActionView().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onSendMenuItemClick(item);
            }
        });

        return super.onCreateOptionsMenu(menu);
    }

    private void onSendMenuItemLongClick() {

    }

    private void onSendMenuItemClick(MenuItem item) {
        Toast.makeText(this, "Send button clicked", Toast.LENGTH_LONG).show();
    }
}
o8x7eapl

o8x7eapl4#

Remie's answer非常适合我,谢谢!
在我的例子中,用MenuHost实现到Fragment中。

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val menuHost: MenuHost = requireActivity() as MenuHost
        menuHost.addMenuProvider(
            object : MenuProvider {
                override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
                    menuInflater.inflate(R.menu.your_menu, menu)
                    menu.findItem(R.id.your_item_id_in_your_menu_resource).setOnTextTapEventListener(
                        onTap = { /** do something **/ },
                        onLongTap = { /** do something **/ },
                    )
                }

                override fun onMenuItemSelected(menuItem: MenuItem): Boolean {
                    return when (menuItem.itemId) {
                        // Not required because it was overwritten in onTap above. 
                        // When you call `menu.performIdentifierAction` in `actionView.setOnClickListener, you can handle here, maybe.
                        // R.id.your_item_id_in_your_menu_resource -> { }
                        android.R.id.home -> {
                            findNavController().navigateUp()
                            true
                        }
                        else -> false
                    }
                }
            },
            viewLifecycleOwner
        )

    }

这是我受Remie's answer启发对MenuItem进行的扩展。

import android.view.MenuItem
import com.google.android.material.button.MaterialButton

fun MenuItem.setOnTextTapEventListener(
    onTap: () -> Unit,
    onLongTap: () -> Unit,
) {
    setActionView(R.layout.your_action_view)
    // It's enough to use `this.title` in "my" case.
    actionView.findViewById<MaterialButton>(R.id.menu_action_text_button).text = this.title 
    actionView.setOnLongClickListener {
        onLongTap.invoke()
        true
    }
    actionView.setOnClickListener {
        onTap.invoke()
    }
}

相关问题