Android Demo Android ActionBarCompat-ListPopupMenu

示例显示如何使用v7 appcompat库中的PopupMenu显示弹出式菜单。主界面使用V4支持库的ListFragment显示数据列表,当点击列表子项时,在子项下方弹出下拉菜单,并通过设置setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener())监听菜单点击事件,下拉菜单只有一个选项,用于移除该列表子项。

Demo下载地址:https://github.com/googlesamples/android-ActionBarCompat-ListPopupMenu/#readme

PopupMenu API:https://developer.android.google.cn/reference/android/support/v7/widget/PopupMenu

首先看看示例的运行界面:

Android Demo Android ActionBarCompat-ListPopupMenuAndroid Demo Android ActionBarCompat-ListPopupMenu

Demo关键代码在Fragment中,主页面MainActiviy只是包含了Fragment,这里就不贴出来了:

public class PopupFragment extends ListFragment implements View.OnClickListener {

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // 创建页面列表
        ArrayList<String> items = new ArrayList<>();
        for (int i = 0; i < Cheeses.CHEESES.length; i++) {
            items.add(Cheeses.CHEESES[i]);
        }
        // 设置Adapter
        setListAdapter(new PopupAdapter(items));
    }

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        String item = (String) l.getItemAtPosition(position);
        Toast.makeText(getActivity(), "Item Clicked: " + item, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(final View v) {
        // 为确保下拉菜单弹出位置的正确,需要传递一个Runnable对象。因为下拉菜单显示前,View的位置可能不一样(列表子项滚动位置会变)。
        v.post(new Runnable() {
            @Override
            public void run() {
                showPopupMenu(v);
            }
        });
    }

    private void showPopupMenu(View view) {
        final PopupAdapter adapter = (PopupAdapter) getListAdapter();

        // 获得发生点击事件View的Tag
        final String item = (String) view.getTag();

        // 创建一个PopupMenu,并把PopupMenu绑定到对应的view
        PopupMenu popup = new PopupMenu(getActivity(), view);

        // 为PopupMenu绑定布局文件
        popup.getMenuInflater().inflate(R.menu.popup, popup.getMenu());

        // 为下拉菜单设置监听
        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                switch (menuItem.getItemId()) {
                    case R.id.menu_remove:
                        // 把对应列表子项移除
                        adapter.remove(item);
                        return true;
                }
                return false;
            }
        });

        // 显示下拉菜单
        popup.show();
    }

    class PopupAdapter extends ArrayAdapter {

        public PopupAdapter(ArrayList<String> items) {
            super(getActivity(), R.layout.list_item, android.R.id.text1, items);
        }

        @NonNull
        @Override
        public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
            View view = super.getView(position, convertView, parent);
            View popupButton = view.findViewById(R.id.button_popup);
            popupButton.setTag(getItem(position));
            popupButton.setOnClickListener(PopupFragment.this);
            return view;
        }
    }
}

下拉菜单布局文件popup.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:id="@+id/menu_remove"
        android:title="remove" />

</menu>

列表子项布局文件list_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="?attr/listPreferredItemHeight"
    android:orientation="horizontal">

    <TextView
        android:id="@android:id/text1"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:ellipsize="end"
        android:gravity="center_vertical"
        android:maxLines="1"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:textAppearance="?android:attr/textAppearanceMedium" />

    <ImageView
        android:id="@+id/button_popup"
        android:layout_width="56dip"
        android:layout_height="match_parent"
        android:background="?attr/selectableItemBackground"
        android:src="@mipmap/ic_action_settings" />

</LinearLayout>