zoukankan      html  css  js  c++  java
  • ToolBar

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

    转载请标明出处http://www.cnblogs.com/tangZH/p/7850572.html

    使用ToolBar

    1.要引入appCompat_v7支持

    2.主题设置为NoActionBar

    在style.xml文件中

    <style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
            <!--ToolBar颜色-->
            <item name="colorPrimary">@color/colorBlack</item>
            <!--状态栏颜色-->
            <item name="colorPrimaryDark">@color/colorBlack</item>
            <!--窗口的背景色-->
            <item name="android:windowBackground">@color/colorWhite</item>
            <!--add searchView-->
            <item name="searchViewStyle">@style/MySearchView</item>
            <item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
    </style>
    给应用设置该主题

    上面的style中有两个风格:
    1、<item name="searchViewStyle">@style/MySearchView</item>是在toolbar上面添加搜索框,所以还要再声明一个style,即搜索框的style。
    //Android自带的搜索框
    <style name="MySearchView" parent="Widget.AppCompat.SearchView"/>

     

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

    <style name="OverflowMenuStyle" parent="Widget.AppCompat.Light.PopupMenu.Overflow">
            <!--把该属性改为false即可使menu位置位于toolbar之下-->
            <item name="overlapAnchor">false</item>
    //背景色 <item name="android:colorBackground">@android:color/holo_blue_dark</item> //文字颜色 <item name="android:textColor">@android:color/white</item> //溢出菜单宽度 <item name="android:dropDownWidth">wrap_content</item> //溢出菜单高度 <item name="android:dropDownHeight">wrap_content</item> </style>

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

     

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

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

    界面布局

    <android.support.v7.widget.Toolbar
      android:id="@+id/toolbar"
      android:layout_height="?attr/actionBarSize"
      android:layout_width="match_parent" >
    </android.support.v7.widget.Toolbar>

    请记得用 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 version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context=".MainActivity">
        <item
            android:id="@+id/action_search"
            android:orderInCategory="80"
            android:title="@string/tv_search"
            app:actionViewClass="android.support.v7.widget.SearchView"
            app:showAsAction="ifRoom"
            />
        <item
            android:id="@+id/action_share"
            android:orderInCategory="90"
            android:title="@string/tv_share"
            app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
            app:showAsAction="ifRoom"
            />
        <item
            android:id="@+id/action_error_ques"
            android:orderInCategory="100"
            android:title="@string/tv_error_ques"
            app:showAsAction="never"
            android:icon="@mipmap/error_prac_icon"
    
            />
        <item
            android:id="@+id/action_collected_ques"
            android:orderInCategory="110"
            android:title="@string/tv_collection_ques"
            app:showAsAction="never"
            android:icon="@mipmap/memu_colle_prac_icon"
            />
    </menu>

     结果图:

    我们来讲解一下上面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://i.cnblogs.com/EditPosts.aspx?postid=7850572

    
    
  • 相关阅读:
    「UVA12293」 Box Game
    「CF803C」 Maximal GCD
    「CF525D」Arthur and Walls
    「CF442C」 Artem and Array
    LeetCode lcci 16.03 交点
    LeetCode 1305 两棵二叉搜索树中的所有元素
    LeetCode 1040 移动石子直到连续 II
    LeetCode 664 奇怪的打印机
    iOS UIPageViewController系统方法崩溃修复
    LeetCode 334 递增的三元子序列
  • 原文地址:https://www.cnblogs.com/tangZH/p/7850572.html
Copyright © 2011-2022 走看看