在安卓系统中如何进行长按菜单操作?

5

能否通过长按菜单项来执行某些操作? 我试图在长按某个项目时显示一个下拉菜单。

这是菜单的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>

我希望在长按第一个项目时出现下拉菜单,以便选择其他选项。
4个回答

9
你可以使用 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);
}

输出:

在此输入图片描述


1

使用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()

0

这里是另一个解决方案,回答您的问题。 我在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添加到菜单项中,并为其设置了图像资源。背景设置为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();
    }
}

0

Remie的回答对我来说非常完美。谢谢!

在我的情况下,将其实现到带有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
        )


    }

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

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()
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接