• Android Contextual Menus之一:floating context menu


     

    Android Contextual Menus之一:floating context menu

    上下文菜单

      上下文相关的菜单(contextual menu)用来提供影响UI中特定item或者context frame的动作。

      你可以为任何View提供上下文菜单,但是最常见的使用场景是在ListView、GridView或者其他集合类控件中的项目上,这样用户就可以对特定的项目执行一些直接的操作。

      有两种方式来提供上下文相关的动作:

      1.用悬浮上下文菜单( floating context menu)。

      当用户在支持上下文菜单的View上执行长按动作的时候,菜单以一种悬浮列表的方式出现,类似于对话框。

      用户可以每次选择一个菜单项,执行一个上下文相关的动作。

      2.用上下文相关的动作模式(contextual action mode)。

      这种模式是ActionMode的系统实现,在屏幕上方展示一个上下文相关的action bar,里面有一些action items,可以用来执行选定项目的相关动作。

      当这种模式active时,用户可以一次对多个项目执行操作。

     

      注意:虽然contextual action mode是更为推崇的一种方式,但是它是Android 3.0(API Level 11)之后才有的,如果要兼容3.0之前的系统,那就应该用floating context menu。

    创建floating context menu

      提供悬浮上下文菜单的步骤如下:

      1.通过调用registerForContextMenu()方法注册上下文菜单相关的View。

      如果你的activity中用了ListView或者GridView,而且你想其中的每一个item都提供相同的上下文菜单,那么你可以在registerForContextMenu() 中传递这个ListView或GridView。

      2.在Activity或Fragment中实现 onCreateContextMenu()方法。

      当注册过的View接收到长按事件,系统会调用onCreateContextMenu()方法。

      这里你可以定义菜单项,通常是inflate一个菜单资源,比如:

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
                                    ContextMenuInfo menuInfo) {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
    }

      这里MenuInflater允许你通过inflate menu resource来得到一个上下文菜单。

      这个回调方法的参数包含了一个用户选择的View和一个ContextMenu.ContextMenuInfo对象,该对象提供了当前选择的item的一些附加信息。

      如果你的activity有多个views,每个提供不同的上下文菜单,你可以用这些参数来决定当前要inflate那个上下文菜单。

      3.实现onContextItemSelected()方法

      当用户选择了一个菜单项,系统会调用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);
        }
    }

      其中getItemId()方法得到每个菜单项的id值。

     

      当成功处理了一个菜单项之后,返回true。

      如果你没有处理一个菜单项,你应该把这个菜单项转给它的基类实现。

      如果你的activity包含fragment,activity先接收到这个回调。

      当未处理而调用基类实现时,系统会将这个事件传递到每个fragment各自相应的回调方法中,按照fragment添加的顺序,每次一个,直到返回true或者false。

      Activity和Fragment的默认实现都是返回false,所以你应该永远在未处理的时候调用基类实现。

    一个简单的例子

      实现的效果就是长按TextView之后显示一个上下文菜单,含两个菜单项,点击菜单项之后显示Toast。

      Activity代码:

    package com.example.mengdd.hellocontextmenu;
    
    import android.os.Bundle;
    import android.app.Activity;
    import android.view.ContextMenu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ContextMenu.ContextMenuInfo;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class HelloContextMenuMainActivity extends Activity {
    
        private TextView mTextView1 = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_hello_context_menu_main);
    
            mTextView1 = (TextView) findViewById(R.id.textView1);
    
            // 注册要弹出ContextMenu的View
            registerForContextMenu(mTextView1);
    
        }
    
        @Override
        public void onCreateContextMenu(ContextMenu menu, View v,
                ContextMenuInfo menuInfo) {
            // 第二个参数为当前点击的view
    
            super.onCreateContextMenu(menu, v, menuInfo);
    
            MenuInflater inflater = getMenuInflater();
            // 把布局inflate进menu对象
            inflater.inflate(R.menu.context_menu1, menu);
        }
    
        @Override
        public boolean onContextItemSelected(MenuItem item) {
    
            boolean result = false;
            switch (item.getItemId()) {
            case R.id.edit:
    
                Toast.makeText(HelloContextMenuMainActivity.this, "Edit",
                        Toast.LENGTH_LONG).show();
                result = true;
                break;
            case R.id.help:
                Toast.makeText(HelloContextMenuMainActivity.this, "Help",
                        Toast.LENGTH_LONG).show();
                result = true;
                break;
            default:
                result = super.onContextItemSelected(item);
                break;
    
            }
    
            return result;
    
        }
    
    }

      Activity的内容布局:

    <LinearLayout 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:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context=".HelloContextMenuMainActivity" >
    
        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hello_world" />
    
    </LinearLayout>

      Menu的布局:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item
            android:id="@+id/edit"
            android:showAsAction="ifRoom"
            android:title="edit"/>
        <item
            android:id="@+id/help"
            android:title="help"/>
    
    </menu>

    参考资料

      API Guides: Menus->Creating Contextual Menus

      http://developer.android.com/guide/topics/ui/menus.html#context-menu

     

     

  • 相关阅读:
    【Spring】每个程序员都使用Spring(四)——Aop+自定义注解做日志拦截
    倪光南:保护科技人员知识产权是提升企业创新的关键(柳传志,杨元庆没有投入资金和技术,却占了大量股份,在全世界都非常少见)
    凡是能导到线上的都已经尝试过了,现在转化用户成本非常高,到了强者恒强的时代
    MIPS 指令集将在近期开源,RISC-V 阵营慌吗?
    QmlWinExtras
    用css解决Unigui在IE系列浏览器中字体变小的问题(设置UniServeModule的customcss属性)
    uni-app
    .net core consul grpc--系统服务RPC实现通信(一)
    系统间通信——RPC架构设计
    程序是由数据结构属于静态的部分和算法的调用为动态部分构成
  • 原文地址:https://www.cnblogs.com/mengdd/p/3564782.html
Copyright © 2020-2023  润新知