Android学习第2篇——APP三种菜单详解

一、Android的Menu简介
Android系统的Menu主要有三种,OptionsMenu、ContextMenu、PopupMenu。以及菜单下面二级菜单SubMenu。

二、菜单的创建和使用

1、ContextMenu的创建和使用

ContextMenu针对在Activity的View中的所有控件,在长按View控件达到2秒钟弹出一个菜单项。

效果图:


实现方式:

①在Activity的OnCreate()方法中对Button按钮或者整个活动页面添加菜单响应监听:

//长按弹出上下文菜单的Button
Button contextMenu = (Button) findViewById(R.id.contextMenu);
//长按页面弹出上下文菜单
View view = findViewById(R.id.theLayout);
contextMenu.setOnCreateContextMenuListener(this);//为Button单独实现ContextMenu
this.registerForContextMenu(view);//长按页面空白地方会弹出Menu

因为Activity已经实现了OnCreateContextMenuListener,所以要在Activity中重写该类的一些方法:

②创建菜单

    //方法2,因为activity已经实现了OnCreateContextMenuListener,所以只需要重写onCreateContextMenu()方法
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {//这里是ContextMenu参数
        setContextMenuIconEnable(menu, true);//设置菜单的Icon图标可见,这个方法后面详解,针对Android高版本的菜单图标显示的方法
        menu.add(1, 2, 1, "添加").setIcon(android.R.drawable.ic_menu_add);
        menu.add(1, 3, 2, "删除").setIcon(android.R.drawable.ic_menu_delete);
        SubMenu m = menu.addSubMenu(0, 4, 3, "子菜单").setIcon(android.R.drawable.ic_media_next);
        m.add(0, 41, 0, "子菜单项1");
        m.add(0, 42, 0, "子菜单项2");
        m.add(0, 43, 0, "子菜单项3");
        super.onCreateContextMenu(menu, v, menuInfo);
    }

③菜单关闭

    @Override
    public void onContextMenuClosed(Menu menu) {
        Toast.makeText(this,"关闭",Toast.LENGTH_SHORT).show();
        super.onContextMenuClosed(menu);
    }

④菜单被点击

 @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 2:
                Toast.makeText(this, "添加", Toast.LENGTH_SHORT).show();
                break;
            case 3:
                Toast.makeText(this, "删除", Toast.LENGTH_LONG).show();
                break;
            default:
                break;
        }
        return super.onContextItemSelected(item);
    }

ContextMenu菜单实现很简单

2、OptionsMenu的创建和使用

OptionsMenu在页面的标题栏的右侧创建一个菜单按钮,前提是菜单栏可以显示的时候才有,否则会被隐藏。点击按钮弹出OptionsMenu菜单。

效果图:



实现方式:

因为Activity活动本身支持OptionsMenu菜单,所以,我们只需要在Activity里面实现其方法即可

①创建菜单的方法

     * 当标题栏存在时,实现该方法则在标题栏出现Menu按钮,不实现则没有这个按钮
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {//这里是Menu
        //下面这个方法针对OptionsMenu和PopupMenu的图标显示设置,稍后讲解
        setOptionsAndPopupMenuIconEnable(menu, true);
        menu.add(0, 5, 1, "添加1").setIcon(android.R.drawable.ic_menu_add);
        //add()方法返回的是MenuItem对象,调用其setIcon()方法,为相应MenuItem设置Icon
        menu.add(0, 6, 2, "删除1").setIcon(android.R.drawable.ic_menu_delete);
        return super.onCreateOptionsMenu(menu);
    }

②点击菜单按钮时候触发方法

    //在点击OptionsMenu菜单按钮的时候触发,onPrepareOptionsPanel()这个方法先于onPrepareOptionsMenu()执行
    @Override
    protected boolean onPrepareOptionsPanel(View view, Menu menu) {
        Toast.makeText(this, "onPrepareOptionsPanel...", Toast.LENGTH_SHORT).show();
        return super.onPrepareOptionsPanel(view, menu);
    }
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        /**
         * 在onCreateOptionsMenu执行后,菜单被显示前调用;如果菜单已经被创建,则在菜单显示前被调用。 同样的,
         * 返回true则显示该menu,false 则不显示; (可以通过此方法动态的改变菜单的状态,比如加载不同的菜单等) TODO
         * Auto-generated method stub
         */
        Toast.makeText(this, "menu没出来时,处理方法自己定义即可", Toast.LENGTH_SHORT).show();
        return super.onPrepareOptionsMenu(menu);
    }

③当菜单的菜单项被点击的时候的响应函数

    //当OptionItem被选择的时候
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case 5:
                Toast.makeText(this, "添加1", Toast.LENGTH_SHORT).show();
                break;
            case 6:
                Toast.makeText(this, "删除1", Toast.LENGTH_LONG).show();
                break;
            case R.id.add_item:
                Toast.makeText(this, "add", Toast.LENGTH_LONG).show();
                break;
            case R.id.remove_item:
                Toast.makeText(this, "remove", Toast.LENGTH_LONG).show();
                break;
            default:
                break;
        }
        return super.onOptionsItemSelected(item);
    }
④当菜单被关闭的时候(还存在问题)
    //没有测试出结果,以为是菜单关闭时候,以下三种结果不是
    //每次菜单被关闭时调用. (菜单被关闭有三种情形,menu按钮被再次点击、back按钮被点击或者用户选择了某一个菜单项)
    @Override
    public void onOptionsMenuClosed(Menu menu) {
        Toast.makeText(this, "关闭222222", Toast.LENGTH_SHORT).show();
        super.onOptionsMenuClosed(menu);
    }

3、PopupMenu菜单的创建和使用

PopupMenu菜单是通过点击View组件的时候触发Activity相应函数,从而新建PopupMenu菜单

效果图:

实现方式:

①为控件添加属性如下:

android:onClick="popUpMenu"

②在Activity中添加对应函数

    public void popUpMenu(View view) {
        /**
         * 第一个参数上下文对象
         * 第二个参数为锚点,何谓锚点?就是你这个弹出式菜单以哪个view为标准弹出,
         * 如果在这个view的下面有空间就在这个view下面的空间弹出,如果没有空间就
         * 在此view的上面弹出
         */
        PopupMenu popupMenu = new PopupMenu(this, view);
        setOptionsAndPopupMenuIconEnable(popupMenu.getMenu(), true);//显示Menu的图标方法,稍后详解
        /**
         * 第一个参数为菜单布局文件
         * 第二个参数为Menu对象,通过getMenu()获得。
         */
        getMenuInflater().inflate(R.menu.menu, popupMenu.getMenu());
        /**
         * 要想显示必须调用.show()方法
         */
        //弹出菜单的点击事件也没有回调事件,需要自己设置监听事件onMenuItemCilckListener(),
        //并在其中实现逻辑,代码如下:
        //值得注意的是最后的返回值,这个涉及到view的事件分发。简单的意思就是,返回true代码消耗这次点击事件,
        //事件不会继续传播,如果返回false则事件会继续传播的。
        //比如这个弹出菜单的又设置了setOnDismissListener这个事件,
        //那么如果返回true,则这个事件不起作用,返回false则点击事件处理完后,这个事件还会起作用。
        //但是亲测true好像没有用
        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                Toast.makeText(MainActivity.this, menuItem.getTitle().toString(), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
        popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
            @Override
            public void onDismiss(PopupMenu popupMenu) {
                Toast.makeText(MainActivity.this, "PopupMenu的Dismiss", Toast.LENGTH_SHORT).show();
            }
        });
        popupMenu.setGravity(Gravity.BOTTOM);//没有用
        popupMenu.show();
    }

上面可以看出关于PopupMenu菜单的所有的实现以及点击按钮事件都在这个方法内完成。

三、关于菜单的创建说明

1、add方法的参数解析

//        add()方法的四个参数,依次是:
//        1、组别,如果不分组的话就写Menu.NONE,
//        2、Id,这个很重要,Android根据这个Id来确定不同的菜单
//        3、顺序,哪个菜单项在前面由这个参数的大小决定
//        4、文本,菜单项的显示文本
        menu.add(0, 5, 1, "添加1").setIcon(android.R.drawable.ic_menu_add);

2、通过布局文件创建菜单

①新建布局文件,在res资源目录下新建一个menu资源文件夹,选择类型就是menu。然后在menu文件下面新建一个menu.xml文件,这个名字可以自己取。下面包含了二级菜单的创建。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/add_item"
        android:icon="@android:drawable/ic_menu_add"
        android:title="Add" />
    <item
        android:id="@+id/remove_item"
        android:icon="@android:drawable/ic_popup_reminder"
        android:title="Remove" />
    <item
        android:id="@+id/item_china"
        android:orderInCategory="100"
        android:title="中国">
        <menu>
            <item
                android:id="@+id/item_beijing"
                android:orderInCategory="200"
                android:title="北京"/>
            <item
                android:id="@+id/item_shanghai"
                android:orderInCategory="200"
                android:title="上海"/>
        </menu>
    </item>
</menu>

②通过资源文件新建菜单

getMenuInflater().inflate(R.menu.menu, Menu);

通过该方法直接将meun.xml的菜单解析到Menu实例中。

四、关于菜单图片的显示问题

Android的4.0之前,设置图标是默认显示的,但是4.0之后,就不在默认了。现在针对三种菜单Menu的图标显示方法如下

1、针对ContextMenu菜单

    // 经过试验ContextMenu有效,对OptionMenu无效
    private void setContextMenuIconEnable(Menu menu, boolean enable) {
        if (menu != null) {
            //com.android.internal.view.menu.ContextMenuBuilder,这是菜单menu的实体类
            Log.d("AAA", menu.getClass().getName().toString());
            try {
                //这是ContextMenu加载菜单的Builder,com.android.internal.view.menu.MenuBuilder
                Class<?> clazz = Class.forName("com.android.internal.view.menu.MenuBuilder");
                Method m = clazz.getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                Log.d("aaa", m.toString());
                m.setAccessible(true);
                //MenuBuilder实现Menu接口,创建菜单时,传进来的menu其实就是MenuBuilder对象(java的多态特征)
                m.invoke(menu, enable);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

2、针对PopupMenu和OptionsMenu菜单

   //这是针对OptionsMenu和PopupMenu菜单的设置Icon图标可见的方法
    private void setOptionsAndPopupMenuIconEnable(Menu menu, boolean enable) {
        if (menu != null) {
            Log.d("BBB", menu.getClass().getName().toString());
            if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
                try {
                    //这是OptionMenu加载菜单的Builder,android.support.v7.view.menu.MenuBuilder
                    //Class clazz = Class.forName("android.support.v7.view.menu.MenuBuilder");
                    Method m = menu.getClass().getDeclaredMethod(
                            "setOptionalIconsVisible", Boolean.TYPE);
                    m.setAccessible(true);
                    m.invoke(menu, enable);
                } catch (Exception e) {
                }
            }
        }
    }




  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 新闻app是一款基于Android平台的小型项目应用程序,它主要用于展示各类新闻内容,为用户提供便捷的阅读体验。该项目的源码包含了应用程序的基本框架和功能实现,方便开发者进行二次开发和定制。 新闻app的源码主要包含以下几个方面的内容: 1. 用户界面设计:源码中包含了新闻app的界面布局和样式,开发者可以根据自己的需要进行修改和美化。用户界面通常包括新闻列表、新闻详情页、分类标签等,开发者可以自由设计并添加其他功能模块。 2. 数据获取与展示:源码中实现了与服务器进行数据交互的功能,通过网络请求获取新闻数据,并在界面上展示出来。开发者可以根据需要修改数据请求接口和解析方式,实现与自己的服务器交互。 3. 新闻分类与搜索:源码中提供了新闻分类和搜索功能的实现,用户可以根据自己的兴趣和需求选择不同的新闻分类进行浏览,也可以通过搜索关键词进行精确定位。 4. 用户交互与分享:源码中包含了用户的登录注册功能和新闻内容的分享功能,用户可以通过登录账号进行个性化设置和收藏喜欢的新闻内容,也可以将新闻分享到社交媒体上与他人交流。 总之,新闻app源码是一个基础框架,开发者可以在此基础上进行二次开发和定制,根据自己的需求添加功能模块和美化界面,实现自己独特的新闻应用。 ### 回答2: Android新闻App是一个基于Android平台开发的小型项目,它的主要功能是提供最新的新闻内容给用户,并且用户可以进行浏览、搜索和分享等操作。下面是这个项目的一些关键特点和所需的源码组成部分: 1. 特点: - 用户界面友好,交互性强,提供舒适的浏览体验; - 支持实时更新,提供最新的新闻内容; - 具备搜索功能,方便用户查找感兴趣的新闻; - 支持新闻分享功能,方便用户将新闻分享给朋友; - 具备图文混排的能力,可以展示新闻的文字和图片。 2. 源码组成部分: - 主界面布局代码:定义了App的整体布局结构,包括顶部导航栏、底部工具栏和新闻显示区域等。 - 数据源代码:负责获取新闻数据,可以通过API接口获取最新的新闻内容,也可以从本地数据库获取已缓存的新闻数据。 - 新闻列表适配器代码:用于将新闻数据展示在界面上,包括标题、描述和图片等。 - 新闻详情界面代码:用于显示单新闻的详细内容,包括标题、正文和相关图片等。 - 搜索功能代码:实现了按关键字搜索新闻的功能,可以在已有的新闻数据中进行筛选。 - 分享功能代码:集成了社交媒体的分享SDK,方便用户将新闻内容分享给朋友。 - 图片加载和缓存代码:处理了新闻中的图片加载和本地缓存,提高了图片加载速度和用户体验。 通过以上的源码组成部分,可以完成一个基本的新闻App,用户可以在界面上浏览最新的新闻内容,进行搜索和分享操作。这个小项目可以帮助开发者理解Android开发框架和开发方式,提高编码能力和UI设计能力。 ### 回答3: 新闻app是基于Android平台开发的一个小型应用程序,可以提供用户各种最新的新闻资讯。以下是关于这个项目的源码介绍。 该项目源码主要由Java语言编写,使用了Android Studio作为开发工具。代码结构清晰,包含了主要的几个模块。 1. 用户界面模块:这个模块负责显示新闻列表和新闻详情等信息,主要包含布局文件和相应的逻辑代码。列表界面使用RecyclerView控件展示新闻列表,详情界面使用WebView展示新闻内容。 2. 网络请求模块:这个模块负责与后台服务器进行数据交互,使用了Android的HttpURLConnection类来发送请求和接收响应。请求参数可以根据实际需要进行修改,例如可以根据新闻类别进行请求。 3. 数据解析模块:这个模块负责解析从服务器返回的JSON格式的数据,转换成Java对象供应用程序使用。可以使用Android提供的JSON解析库,如Gson。 4. 数据存储模块:这个模块负责缓存新闻数据,以提高应用程序的响应速度。可以使用SharedPreferences或SQLite数据库来存储新闻数据。同时也可以使用图片缓存库,如Glide或Picasso来缓存新闻图片。 5. 用户交互模块:这个模块负责处理用户的交互行为,例如点击新闻列表项跳转到新闻详情界面,下拉刷新获取最新数据等。可以使用Android提供的相关控件和事件监听器来实现用户交互。 除了以上几个主要的模块,还可以根据需要添加其他功能,例如搜索栏、分享按钮等。 总体来说,这个新闻app的源码提供了一个完整的开发框架,初学者可以通过阅读和理解源码来学习Android应用程序的开发流程和一些常用技术。同时,也可以根据实际需求进行二次开发,添加新的功能和改进用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值