Menu的详细使用

1.通过加载menu/ xxx.xml文件创建菜单

Activity 每次启动,依次回调 onCreateOptionsMenu、 onPrepareOptionsMenu
onCreateOptionMenu: 只在activity启动时,展示menu调用一次
onPrepareOptionsMenu:在每次展示menu时,都会调用。即第一次在activity启动时,显示menu调用,以后每次点击菜单按钮,都会再次调用

onCreateOptionMenu用于初始化菜单栏,一般是通过加载xml文件,创建菜单

MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.demo1, menu);
return true;

onPrepareOptionsMenu: 在上方法调用之后调用,返回true,显示菜单,false,不显示,在invalidateOptionsMenu之后也会调用,主要用于动态更新菜单栏

官方文档:
- 在 Android 2.3.x 及更低版本中,每当用户打开选项菜单时(按“菜单”按钮),系统均会调用 onPrepareOptionsMenu()

  • 在 Android 3.0 及更高版本中,当菜单项显示在应用栏中时,选项菜单被视为始终处于打开状态。 发生事件时,如果您要执行菜单更新,则必须调用 invalidateOptionsMenu() 来请求系统调用 onPrepareOptionsMenu()

但是根据测试,发现在Android7.0 版本
- 第一次启动,依次执行onCreateOptionMenuinvalidateOptionsMenu 方法
- 每次按菜单按钮,系统只会调用 onPrepareOptionsMenu()
- 而且,如果手动调用invalidateOptionsMenu方法,系统就会依次调用 onCreateOptionMenuinvalidateOptionsMenu 方法

2. 创建浮动上下文菜单

  1. 通过调用 registerForContextMenu(),注册应与上下文菜单关联的 View 并将其传递给 View。
//1.对View组件进行注册 上下文菜单按钮
registerForContextMenu(imageView);
registerForContextMenu(button);
  1. 在 Activity 或 Fragment 中实现 onCreateContextMenu() 方法。
    当注册后的视图收到长按事件时,系统将调用您的 onCreateContextMenu() 方法。在此方法中,您通常可通过扩充菜单资源来定义菜单项。
    注意:如果 Activity 有多个视图,每个视图均提供不同的上下文菜单,则可使用上述方法中的参数View v确定要扩充的上下文菜单。v 对应长按的视图控件。
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();

    if (v.getId() == R.id.context_img) {
        inflater.inflate(R.menu.context_menu, menu);
    } else {
        inflater.inflate(R.menu.context_menu2, menu);
    }
}

3.实现 onContextItemSelected()。
用户点击选择菜单项时,系统将调用此方法,以便您能够执行适当的操作。

@Override
public boolean onContextItemSelected(MenuItem item) {
    AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
    switch (item.getItemId()) {
        case R.id.edit:
            editNote(info.id);
            return true;
        case R.id.delete:
            deleteNote(info.id);
            return true;
        default:
            return super.onContextItemSelected(item);
    }
}

成功处理菜单项后,系统将返回 true。如果未处理菜单项,则应将菜单项传递给超类实现。 如果 Activity 包括片段,则 Activity 将先收到此回调。 通过在未处理的情况下调用超类,系统会将事件逐一传递给每个片段中相应的回调方法(按照每个片段的添加顺序),直到返回 true 或 false 为止。(Activity 和 android.app.Fragment 的默认实现返回 false,因此您始终应在未处理的情况下调用超类。)

3.创建 ActionMode(上下文操作模式)

1. 为单个视图启用上下文模式
  1. 实现 ActionMode.Callback 接口。在其回调方法中,您既可以为上下文操作栏指定操作,又可以响应操作项目的点击事件,还可以处理操作模式的其他生命周期事件。
  2. 当需要显示操作栏时(例如,用户长按视图),请调用 startActionMode()。启用上下文操作模式。
startActionMode() :接收参数:ActionMode.Callback的实现子类,返回ActionMode对象
public class ContextOperate extends AppCompatActivity {
    private Context mContext;
    private ActionMode mActionMode;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_context_operate);
        mContext = this;
        Button button = (Button) findViewById(R.id.context_operate);
        button.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                if (mActionMode != null) {
                    return false;
                }
                mActionMode = startActionMode(mActionModeCallback);
                return true;
            }
        });
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mActionMode != null) {
                    mActionMode.invalidate();
                }
            }
        });
    }

    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
        private static final String TAG = "ContextOperate";
        private int num=0;
        //Called each time the action mode is created
        // 通过startActionMode()、或者 mActionMode.invalidate() 都会创建新的 actionMode,调用该方法
        //但是点击 菜单按钮(三个点),不会触发该方法,只会触发 onPrepareActionMode方法,和浮动上下文菜单类似
        // 加载菜单xml文件, 创建上下文ActionMode
        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            Log.e(TAG, "onCreateActionMode");
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.context_menu2, menu);
            return true;
        }

        // Called each time the action mode is shown. Always called after onCreateActionMode, but
        // may be called multiple times if the mode is invalidated.
        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            Log.e(TAG, "onPrepareActionMode"+(++num));

            menu.add(0, 0, 0, "哈哈"+num);
            return true;   // Return false if nothing is done
        }

        // Called when the user selects a contextual menu item
        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
                case R.id.delete:
                    Toast.makeText(mContext, "按钮_删除", Toast.LENGTH_SHORT).show();
                    // 已经获取到item,现在结束 actionMode了
                    mode.finish();
                    return true;
                case R.id.edit:
                    Toast.makeText(mContext, "按钮_编辑", Toast.LENGTH_SHORT).show();
                    mode.finish();
                    return true;
                default:
                    return false;
            }
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }

    };


}

Alt text

3. 为ListView 创建上下文模式
  1. 实现 AbsListView.MultiChoiceModeListener 接口,并使用 setMultiChoiceModeListener() 为视图组设置该接口。在侦听器的回调方法中,您既可以为上下文操作栏指定操作,也可以响应操作项目的点击事件,还可以处理从 ActionMode.Callback 接口继承的其他回调。
  2. 使用 CHOICE_MODE_MULTIPLE_MODAL 参数调用 setChoiceMode()。
public class ListActivityMenu extends AppCompatActivity {
    private static final String TAG = "ListActivityMenu";
    private Context mContext = ListActivityMenu.this;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.list_view_menu);
        String[] str = {
                "张三1", "李四2", "王五3", "张三4", "李四5", "王五6", "张三7", "李四8",
                "王五9", "张三10", "李四11", "王五12", "张三13", "李四14", "王五15"
        };
        ArrayAdapter<String> adapter = new ArrayAdapter<>(ListActivityMenu.this, android.R.layout.simple_list_item_1, str);
        final ListView listView = (ListView) findViewById(R.id.list_view_menu);
        listView.setAdapter(adapter);
        mContext = this;

        listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        listView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
            //当出现 ActionMode以后,点击列表中的每一项,该项就会被设置成选中 checked =true,再次点击就会变成 false
            @Override
            public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) {
                Toast.makeText(mContext, "position" + position + "changed," + checked, Toast.LENGTH_SHORT).show();
                // 如何获取被点击的 ListView内部的子项Item
 /*               if (checked) {
                    item.setBackgroundColor(getResources().getColor(R.color.colorItemBack));
                }else{
                    item.setBackgroundColor(getResources().getColor(android.R.color.background_light));
                }*/
            }

            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                MenuInflater inflater = getMenuInflater();
                inflater.inflate(R.menu.context_menu2, menu);
                return true;
            }

            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                return true;
            }

            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.delete:
                        Toast.makeText(mContext, "按钮_删除", Toast.LENGTH_SHORT).show();
                        // 已经获取到item,现在结束 actionMode了

                        deleteSelected();
                        mode.finish();
                        return true;
                    case R.id.edit:
                        Toast.makeText(mContext, "按钮_编辑", Toast.LENGTH_SHORT).show();
                        mode.finish();
                        return true;
                    default:
                        return false;
                }
            }

            // 如何删除ListView内部的 子项
            public void deleteSelected() {
                SparseBooleanArray array = listView.getCheckedItemPositions();
                Toast.makeText(mContext, array.toString(), Toast.LENGTH_SHORT).show();

                Log.e(TAG, "deleteSelected" + array.size());

                for (int i = 0; i < array.size(); i++) {
                    int key = array.keyAt(i);
                    boolean res = array.get(key);
                    Log.e(TAG, key + "==>" + res);
                }

            }

            @Override
            public void onDestroyActionMode(ActionMode mode) {

            }


        });
    }


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个详细Android 设置 Menu 背景的示例: 1. 首先,在 res/menu 目录下创建一个新的菜单布局文件,例如 my_menu.xml,内容如下: ```xml <menu xmlns:android="http://schemas.android.com/apk/res/android"> <item android:id="@+id/menu_item" android:title="My Menu Item" android:icon="@drawable/my_icon" android:showAsAction="always" android:titleCondensed="Item" android:actionLayout="@layout/my_action_layout" android:background="@drawable/my_menu_background" /> </menu> ``` 这里我们设置了菜单项的 id、标题、图标、显示位置、缩略标题、自定义布局和背景。 2. 接下来,创建一个自定义背景资源文件,例如 my_menu_background.xml,保存到 res/drawable 目录下,内容如下: ```xml <shape xmlns:android="http://schemas.android.com/apk/res/android"> <solid android:color="#FF0000" /> <corners android:radius="4dp" /> </shape> ``` 这里我们设置了背景色为红色,圆角半径为 4dp。 3. 最后,在 Activity 中加载菜单并显示: ```java @Override public boolean onCreateOptionsMenu(Menu menu) { // 加载菜单布局文件 getMenuInflater().inflate(R.menu.my_menu, menu); return true; } ``` 这里我们使用 getMenuInflater().inflate() 方法来加载菜单布局文件,然后返回 true 表示菜单已经成功创建。在这个方法中,系统会自动调用菜单项的 onCreateActionView() 方法来创建自定义布局,这里我们可以不用管它。 运行应用程序,点击菜单按钮,即可看到自定义背景的菜单项了。 希望这个示例可以帮助你理解如何在 Android 中设置菜单的背景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值