2.2.6 通知类控件 Toast、Menu

作者: 常思行 | 来源:发表于2018-05-31 14:16 被阅读16次

    本文例程下载: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菜单的效果。

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

    相关文章

      网友评论

        本文标题:2.2.6 通知类控件 Toast、Menu

        本文链接:https://www.haomeiwen.com/subject/heyqsftx.html