2.2.6 通知类控件 Toast、Menu

本文例程下载:WillFlow_ToastWillFlowMenu

一、什么是Toast?

Toast 也被叫做吐司,是 Android 系统提供的一种非常好的提醒方式,在程序中可以使用它将一些短小的信息通知给用户,它有如下两个特点:

  • Toast 是没有焦点的
  • Toast显示的时间有限过一定的时间就会自动消失
    所以一般来讲Toast的使用并不会影响我们的正常操作,并且它通常不会占用太大的屏幕空间,有着良好的用户体验。
使用Toast的一般步骤:

1、调用Toast的构造器或者makeText()静态方法构造一个Toast对象。
2、调用Toast的方法来设置该消息的提醒方式、页边距等。
3、调用Toast的show()方法将它显示出来。

百闻不如一见:

我们现在就尝试一下如何在活动中使用 Toast。

二、Toast的四种使用方式

首先需要定义一个弹出 Toast 的触发点,那我们就在界面上定义几个按钮,当点击这个按钮的时候弹出对应的 Toast 。然后在 onCreate()方法中添加代码:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        mButton1 = (Button) findViewById(R.id.button1);
        mButton2 = (Button) findViewById(R.id.button2);
        mButton3 = (Button) findViewById(R.id.button3);
        mButton4 = (Button) findViewById(R.id.button4);
        mButton1.setOnClickListener(this);
        mButton2.setOnClickListener(this);
        mButton3.setOnClickListener(this);
        mButton4.setOnClickListener(this);
    }

其布局文件activity_main.xml为:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat 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"
    tools:context="com.wgh.willflow_toast.MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="25dp"
        android:text="默认Toast样式" />

    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="25dp"
        android:text="自定义显示位置效果" />

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="25dp"
        android:text="带图片效果" />

    <Button
        android:id="@+id/button4"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="25dp"
        android:text="完全自定义效果" />

</android.support.v7.widget.LinearLayoutCompat>

在Activity中可以通过 findViewById() 方法获取到在布局文件中定义的元素,这里我们传入 R.id.button1 来得到按钮的实例,这个值是在 R.layout.activity_main.xml 中通过 android:id 属性指定的。

findViewById()方法返回的是一个 View 对象,我们需要向下转型将它转成 Button 对象。得到了按钮的实例之后,我们通过调用 setOnClickListener() 方法为按钮注册一个监听器,点击按钮时就会执行监听器中的 onClick()方法。因此,弹出 Toast 的功能当然是要在onClick()方法中编写了。

Toast 的用法非常简单,通过静态方法 makeText() 创建出一个 Toast 对象,然后调用 show() 将 Toast 显示出来就可以了。这里需要注意的是, makeText() 方法需要传入三个参数。第一个参数是 Context,也就是 Toast 要求的上下文,我们这里直接传入 getApplicationContext() 即可,这是一个全局的Context。第二个参数是 Toast显示的文本内容,第三个参数是 Toast显示的时长,有两个内置常量可以选择Toast.LENGTH_SHORT 和 Toast.LENGTH_LONG。下面给出各个部分的代码:

(1)默认效果

mToast = Toast.makeText(getApplicationContext(), "默认Toast样式", Toast.LENGTH_SHORT);
mToast.show();

(2)自定义显示位置效果

mToast = Toast.makeText(getApplicationContext(),
        "自定义位置Toast", Toast.LENGTH_LONG);
mToast.setGravity(Gravity.CENTER, 0, 0);
mToast.show();

(3)带图片效果

mToast = Toast.makeText(getApplicationContext(),
        "带图片的Toast", Toast.LENGTH_LONG);
mToast.setGravity(Gravity.CENTER, 0, 0);
LinearLayout toastView = (LinearLayout) mToast.getView();
ImageView imageCodeProject = new ImageView(getApplicationContext());
imageCodeProject.setImageResource(R.mipmap.ic_launcher);
toastView.addView(imageCodeProject, 0);
mToast.show();

(4)完全自定义效果

LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.customlayout, null);
ImageView image = (ImageView) layout
        .findViewById(R.id.image);
image.setImageResource(R.mipmap.ic_launcher_round);
TextView title = (TextView) layout.findViewById(R.id.text);
title.setText("Attention");
TextView text = (TextView) layout.findViewById(R.id.text1);
text.setText("完全自定义Toast");
mToast = new Toast(getApplicationContext());
mToast.setGravity(Gravity.CENTER | Gravity.TOP, 0, 666);
mToast.setDuration(Toast.LENGTH_LONG);
mToast.setView(layout);
mToast.show();
其用到的自定义布局customlayout.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="match_parent"
    android:background="@drawable/bg_toast"
    android:orientation="vertical">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />

    <ImageView
        android:id="@+id/image"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@mipmap/ic_launcher_round" />

    <TextView
        android:id="@+id/text1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

二、在Activity中使用Menu

手机毕竟和电脑不同,它的屏幕空间非常有限,因此充分地利用屏幕空间在手机界面设计中就显得非常重要了。如果你的Activity中有大量的菜单需要显示,这个时候界面设计就会比较尴尬,因为仅这些菜单就可能占用屏幕将近三分之一的空间,这该怎么办呢?不用担心,Android 给我们提供了一种方式,可以让菜单都能得到展示的同时,还能不占用过多屏幕的空间。

Android中的菜单有如下几种:
  • OptionMenu:
    选项菜单,Android中最常见的菜单,通过Menu键来调用。
  • SubMenu:
    子菜单,Android中点击子菜单将弹出一个显示子菜单项的悬浮框, 子菜单不支持嵌套,即不能包括其他子菜单。
  • ContextMenu:
    上下文菜单,通过长按某个视图组件后出现的菜单,该组件需注册上下文菜单。

(1)选项菜单(OptionMenu)

可以重写的几个方法:
  • onCreateOptionsMenu:调用OptionMenu,在这里完成菜单初始化。
  • onOptionsItemSelected:菜单项被选中时触发,这里完成事件处理。
  • onOptionsMenuClosed:菜单关闭会调用该方法。
  • onPrepareOptionsMenu:选项菜单显示前会调用该方法, 可在这里进行菜单的调整(动态加载菜单列表)。
  • onMenuOpened:选项菜单打开以后会调用这个方法。
使用流程的两种方式:
  • 直接通过编写菜单XML文件,然后调用:getMenuInflater().inflate(R.menu.menu_main, menu);加载菜单。
  • 通过代码动态添加。
百闻不如一见:
代码实现:
  • MainActivity.java:
public class MainActivity extends AppCompatActivity {

    private TextView mTv_test;
    private TextView mTv_context;
    private Button mBtn_show_menu;

    // 定义不同颜色的菜单项的标识:
    final private int RED = 0;
    final private int GREEN = 1;
    final private int BLUE = 2;
    final private int SUBMENU = 3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
    }

    private void initView() {
        mTv_test = (TextView) findViewById(R.id.tv_test);
        mTv_context = (TextView) findViewById(R.id.tv_context);
        mBtn_show_menu = (Button) findViewById(R.id.btn_show_menu);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        menu.add(1, RED, 1, "红色");
        menu.add(1, GREEN, 2, "绿色");
        menu.add(1, BLUE, 3, "蓝色");
        SubMenu subMenu = menu.addSubMenu(1, SUBMENU, 4, "启动程序");
        subMenu.setHeaderIcon(R.mipmap.ic_launcher);
        subMenu.setHeaderTitle("请选择您要启动的应用程序");
        MenuItem menuItem = subMenu.add("查看WillFlow");
        menuItem.setIntent(new Intent(this, WillFlowActivity.class));
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case RED:
                mTv_test.setTextColor(Color.RED);
                break;
            case GREEN:
                mTv_test.setTextColor(Color.GREEN);
                break;
            case BLUE:
                mTv_test.setTextColor(Color.BLUE);
                break;
        }
        return super.onOptionsItemSelected(item);
    }

上述的代码非常简单,给大家演示了Android 5.0的中OptionMenu(选项菜单)中动态添加菜单以及事件处理,根据id判断用户点击的是哪一项,然后执行对应的操作即可。

除此之外,我们还可以采用绑定监听器的方式来监听菜单点击事件,即通过重写 setOnMenuItemClickListener() 方法来处理菜单的单击事件,但是一般来讲,通过重写 onOpentionsItemSelected() 会更加便捷,因为所有的事件处理代码都控制在该方法之内,只需要判断到底单击了哪个菜单项就行了,而通过为每个菜单项绑定事件监听器的方法则会使代码显得更加臃肿,因此一般并不推荐为每个菜单项分别绑定监听器。

(2)上下文菜单(ContextMenu)

Android 用 ContextMenu 来代表上下文菜单,为 Android 应用开发上下文菜单与开发选项菜单的方法基本相似,因为 ContextMenu 继承了卖牛,因此程序可以用相同的方法为他添加菜单项。

使用的流程:
  • 重写onCreateContextMenu()方法。
  • 使用registerForContextMenu()方法为view组件注册上下文菜单,参数是View。
  • 重写onContextItemSelected()方法为菜单项指定事件监听器。
相关代码:
  • MainActivity.java
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        registerForContextMenu(mTv_context);
  }
    @Override
    // 重写上下文菜单的创建方法
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
        // 子菜单:
        MenuInflater inflator = new MenuInflater(this);
        inflator.inflate(R.menu.menu_sub, menu);
        super.onCreateContextMenu(menu, v, menuInfo);
    }

    // 上下文菜单被点击是触发该方法
    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.one:
                Toast.makeText(MainActivity.this,"你点击了子菜单一",Toast.LENGTH_SHORT).show();
                break;
            case R.id.two:
                item.setCheckable(true);
                Toast.makeText(MainActivity.this,"你点击了子菜单二",Toast.LENGTH_SHORT).show();
                break;
            case R.id.three:
                Toast.makeText(MainActivity.this,"你点击了子菜单三",Toast.LENGTH_SHORT).show();
                item.setCheckable(true);
                break;
        }
        return true;
    }
  • 菜单对应的布局文件menu_sub.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/submenu" android:title="子菜单使用演示1">
        <menu>
            <group android:checkableBehavior = "none">
                <item android:id="@+id/one" android:title = "子菜单一"/>
                <item android:id="@+id/two" android:title = "子菜单二"/>
                <item android:id="@+id/three" android:title = "子菜单三"/>
            </group>
        </menu>
    </item>

    <item android:id="@+id/submenu1" android:title="子菜单使用演示2">
        <menu>
            <group android:checkableBehavior="none">
                <item android:id="@+id/blue" android:title="@string/font_blue"/>
                <item android:id="@+id/green" android:title="@string/font_green"/>
                <item android:id="@+id/red" android:title="@string/font_red"/>
            </group>
        </menu>
    </item>

    <group android:checkableBehavior="none">
        <item android:id="@+id/blue1" android:title="@string/font_blue"/>
        <item android:id="@+id/green1" android:title="@string/font_green"/>
        <item android:id="@+id/red1" android:title="@string/font_red"/>
    </group>
</menu>

(3)弹出式菜单(PopupMenu)

PopupMenu代表弹出式菜单,它是一个类似于PopupWindow的东西,它可以非常方便的在指定view的下面显示一个弹出菜单,就像ActionBar溢出菜单的效果,默认情况下PopupMenu会显示在该组件的下方,也就是说我们也可以制定它显示到某个控件的上方。它的菜单选项可以来自于menu资源并且可增加多个菜单项,因此非常方便。

PopupMenu创建步骤:

1、调用new PopupMenu(Context context,View anchor)创建下拉菜单,anchor代表要激发该弹出菜单的组件。
2、调用MenuInflater的inflate()方法将菜单资源填充到PopupMenu中。
3、调用PopupMenu的show()方法显示弹出式菜单。

我们在按钮点击事件中做操作:
  • MainActivity.java
mBtn_show_menu.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        PopupMenu popup = new PopupMenu(MainActivity.this, mBtn_show_menu);
        popup.getMenuInflater().inflate(R.menu.menu_pop, popup.getMenu());
        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()){
                    case R.id.lpig:
                        Toast.makeText(MainActivity.this,"WillFlow",Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.bpig:
                        Toast.makeText(MainActivity.this,"大叨安卓",Toast.LENGTH_SHORT).show();
                        break;
                }
                return true;
            }
        });
        popup.show();
    }
});

上面的程序中我们创建了一个PopupMenu对象,然后指定将该R.menu.menu_pop菜单资源文件填充到PopupMenu中并指定显示在mBtn_show_menu的下方,这样即可实现当用户单击界面按钮时弹出Popup菜单的效果。

感谢优秀的你跋山涉水看到了这里,不如关注下让我们永远在一起!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,922评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,591评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,546评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,467评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,553评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,580评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,588评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,334评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,780评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,092评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,270评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,925评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,573评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,194评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,437评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,154评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • http://developer.android.youdaxue.com/guide/topics/ui/men...
    acc8226阅读 1,185评论 0 3
  • 前言 星光不问赶路人,时间不负有心人。 选项菜单和子菜单 Android应用中的菜单默认是看不见的,只有当用户按下...
    olaH阅读 676评论 0 3
  • 本节引言: 本章给大家带来的是Android中的Menu(菜单),而在Android中的菜单有如下几种: Opti...
    侯蛋蛋_阅读 8,854评论 0 10
  • 标注:本文为个人学习使用,仅做自己学习参考使用,请勿转载和转发2018-06-28: 初稿,已经是晚上了,才开始学...
    努力学习的安同学阅读 221评论 0 1
  • 一直想抽时间把些较为基础的控件统一系统化抽取出来形成Demo,方便记录以及解答,以下是项目的效果,如果有欠缺的,欢...
    AnandLin阅读 33,176评论 2 27