博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ToolBar
阅读量:6292 次
发布时间:2019-06-22

本文共 6739 字,大约阅读时间需要 22 分钟。

ToolBar比ActionBar更加可控,自由。因此,Google 逐渐使用ToolBar来代替ActionBar。

转载请标明出处

使用ToolBar

1.要引入appCompat_v7支持

2.主题设置为NoActionBar

在style.xml文件中

给应用设置该主题 上面的style中有两个风格: 1、
@style/MySearchView
是在toolbar上面添加搜索框,所以还要再声明一个style,即搜索框的style。
//Android自带的搜索框 

 

2、<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>是设置溢出菜单的风格。

false
//背景色
@android:color/holo_blue_dark
//文字颜色
@android:color/white
//溢出菜单宽度
wrap_content
//溢出菜单高度
wrap_content

如图便可见溢出菜单,关于菜单配置接下来会讲

 

记住别忘了还要gradle里声明依赖

dependencies {    compile fileTree(dir: 'libs', include: ['*.jar'])    testCompile 'junit:junit:4.12'    compile 'com.android.support:appcompat-v7:21.0.3'}

 

界面布局

 

请记得用 support v7 里的 toolbar,不然然只有 API Level 21 也就是 Android 5.0 以上的版本才能使用。

 

程序代码:

 
toolbar=(Toolbar) findViewById(R.id.toolbar);toolbar.setTitle("主标题");toolbar.setSubtitle("副标题");toolbar.setLogo(R.mipmap.ic_launcher);setSupportActionBar(toolbar);//把toolbar当成actionBar使用 toolbar.setNavigationIcon(R.drawable.ab_android);

 

这边要留意的是setNavigationIcon需要放在 setSupportActionBar之后才会生效。

 

菜单配置

 

 结果图:

 

我们来讲解一下上面xml文件中的一些属性:

    • orderInCategory
    • 设置菜单项的排列顺序,必须设置大于等于0的整数值。数值小的排列在前,如果值相等,则按照xml中的顺序展现。
    • title
      菜单项的标题。
    • icon
      菜单项的图标。
    • showAsAction
      该属性有五个值,可以混合使用。
      • always
        总是显示在Toolbar上。
      • ifRoom
        如果Toolbar上还有空间,则显示,否则会隐藏在溢出列表中。
      • never
        永远不会显示在Toolbar上,只会在溢出列表中出现。
      • withText
        文字和图标一起显示。
      • collapseActionView
        声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。一般要配合ifRoom一起使用才会有效。

 

接下来在程序中重写onCreateOptionsMenu,加载菜单

@Override    public boolean onCreateOptionsMenu(Menu menu)    {        getMenuInflater().inflate(R.menu.memu_prac_toolbar,menu);        return true;    }

 

菜单单击事件

@Override    public boolean onOptionsItemSelected(MenuItem item)    {        switch (item.getItemId())        {            case R.id.action_error_ques:                startActivity(new Intent(MainActivity.this, ErrorActivity.class));                break;            case R.id.action_collected_ques:                startActivity(new Intent(MainActivity.this, CollectedActivity.class));                break;            default:                return false;        }        return true;    }

 

有时候会出现一个棘手的问题,那就是溢出菜单没法显示图标,我们可以用反射机制来解决该问题,代码如下:

/**     * 运用反射机制解决toolBar溢出菜单无法显示图标的问题     * @param view     * @param menu     * @return     */    @Override    protected boolean onPrepareOptionsPanel(View view, Menu menu) {        if (menu != null) {            if (menu.getClass().getSimpleName().equals("MenuBuilder")) {                try{                    Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);                    m.setAccessible(true);                    m.invoke(menu, true);                } catch (Exception e) {                    Log.e(getClass().getSimpleName(), "onMenuOpened...unable to set icons for overflow menu", e);                }            }        }        return super.onPrepareOptionsPanel(view, menu);    }

 

我们再假设一个场景:mainActivity里面有一个ViewPager和一个toolbar,ViewPager里面有几个Fragment,当fragment切换的时候要动态改变toolbar的菜单,那么我们应该怎么做呢?

我们都知道,我们在建立actionbar或是toolbar的时候,都会默认的实现两个方法,分别是onCreateOptionsMenu和onOptionsItemSelected,这两个方法,前面的是建立菜单,后面的对选中的菜单进行操作。onCreateOptionsMenu只会在第一次初始化菜单时调用,其后就不在运行了,也就是说它只一次加载完之后,就不会再动了,所以我们没法通过这个方法来改变toolbar的菜单。

Android给我们提供了一个onPrepareOptionsMenu(Menu menu)方法,我们可以在里面动态改变菜单,然后通过判断viewPager滑动到第几页,通过invalidateOptionsMenu()动态调用该方法。

/**     * 根据memuPosition的值来选择加载的菜单     * @param menu     * @return     */    @Override    public boolean onPrepareOptionsMenu(Menu menu)    {        menu.clear();        MenuInflater inflater=this.getMenuInflater();        switch (memuPosition)        {            case 0:            case 3:                inflater.inflate(R.menu.memu_prac_toolbar,menu);//答题界面的toolbar菜单                 //如果只是想动态隐藏或者显示菜单控件的话可以用下面的方法。                 //menu.findItem(R.id.search_button).setVisible(true);                 //menu.findItem(R.id.scan_button).setVisible(true);                 //menu.findItem(R.id.setting_button).setVisible(false);                 break;            case 1:                inflater.inflate(R.menu.memu_stu_toolbar,menu);//学习界面的toolbar菜单                break;            case 2:                inflater.inflate(R.menu.memu_forum_toolbar,menu);//论坛界面的toolbar菜单                break;            default:                break;        }        return super.onPrepareOptionsMenu(menu);    }

 

 

 我们要先清除之前的菜单,不然它会在之前的菜单基础上继续添加。

 

在viewPager滑动的时候进行判断,然后调用。

if(myViewPager.getCurrentItem()!=0){     myViewPager.setCurrentItem(0);     toolbar.setTitle(re.getString(R.string.tv_answer));     memuPosition=0; //标识位于第几页     invalidateOptionsMenu();//重新加载菜单}

 注意要调用invalidateOptionsMenu()或者supportInvalidateOptionMenu()方法。

 既然已经用onPrepareOptionsMenu(Menu menu)来加载菜单了,那么activity中的 

@Override    public boolean onCreateOptionsMenu(Menu menu)    {        getMenuInflater().inflate(R.menu.memu_prac_toolbar,menu);        return true;    } 可以不写,因为该方法便是来加载菜单的。 出了上面所将的这些,toolbar还有一些坑,那就是在fragment中使用的时候,继续上面的场景,我们再增加一种场景,那就是需要在fragment中响应菜单的点击事件,我们应该怎么做呢? 我们可以在fragment里面重写onOptionsItemSelected(MenuItem item),例如下面代码:
@Override    public boolean onOptionsItemSelected(MenuItem item)    {        switch (item.getItemId())        {            case R.id.action_vertical_arrangement:                //设置recycleView的布局方式为竖直线性布局                recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));                break;            case R.id.action_horizontal_arrangement:                //设置recycleView的布局方式为网格布局                recyclerView.setLayoutManager(new GridLayoutManager(getContext(),2));                break;            default:                return super.onOptionsItemSelected(item);        }        return true;    }

  不过有一点需要很注意,那就是必须在onCreate里写上setHasOptionsMenu(true),这样子onOptionsItemSelected(MenuItem item)才有效。点击事件是由Activity的onOptionsItemSelected(MenuItem item)传进来的(事件分发)。

 

 

如果我们要在fragment中加载菜单,那么可以在fragment中重写onCreateOptionsMenu(Menu menu, MenuInflater inflater)

 

 

@Override    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)    {        inflater.inflate(R.menu.memu_stu_toolbar,menu);        super.onCreateOptionsMenu(menu, inflater);    }

 

 

 

注意该方法与Activity中的public boolean onCreateOptionsMenu(Menu menu)是不一样的,activity中的有返回值。一样的必须在onCreate里写上setHasOptionsMenu(true),fragment里面的onCreateOptionsMenu(Menu menu, MenuInflater inflater)才会生效。

程序会先调用activity的public boolean onCreateOptionsMenu(Menu menu),再调用fragment里onCreateOptionsMenu(Menu menu, MenuInflater inflater),如果fragment中没有对menu进行清除,那么fragment里的菜单会在Activity外的菜单基础上添加上去。

 

以上便是本人就项目过程中遇到的问题对toolbar的总结,以后要是遇到其他问题会继续补充。

 

转载请标明出处

 

 

 

转载于:https://www.cnblogs.com/tangZH/p/7850572.html

你可能感兴趣的文章
Why I Began
查看>>
同一台电脑上Windows 7和Ubuntu 14.04的CPU温度和GPU温度对比
查看>>
js数组的操作
查看>>
springmvc Could not write content: No serializer
查看>>
Python系语言发展综述
查看>>
新手 开博
查看>>
借助开源工具高效完成Java应用的运行分析
查看>>
163 yum
查看>>
第三章:Shiro的配置——深入浅出学Shiro细粒度权限开发框架
查看>>
80后创业的经验谈(转,朴实但实用!推荐)
查看>>
让Windows图片查看器和windows资源管理器显示WebP格式
查看>>
我的友情链接
查看>>
vim使用点滴
查看>>
embedded linux学习中几个需要明确的概念
查看>>
mysql常用语法
查看>>
Morris ajax
查看>>
【Docker学习笔记(四)】通过Nginx镜像快速搭建静态网站
查看>>
ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
查看>>
<转>云主机配置OpenStack使用spice的方法
查看>>
java jvm GC 各个区内存参数设置
查看>>