编程知识 购物 网址 新闻 笑话 | 软件 日历 阅读 图书馆 China
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
vbs/VBScript DOS/BAT hta htc python perl 游戏相关 VBA 远程脚本 ColdFusion ruby专题 autoit seraphzone PowerShell linux shell Lua Golang Erlang 其它教程 CSS/HTML/Xhtml html5 CSS XML/XSLT Dreamweaver教程 经验交流
站长资讯 .NET新手 ASP.NET C# WinForm Silverlight WCF CLR WPF XNA VisualStudio ASP.NET-MVC .NET控件开发 EntityFramework WinRT-Metro Java C++ PHP Delphi Python Ruby C语言 Erlang Go Swift Scala R语言 Verilog 其它语言 架构设计 面向对象 设计模式 领域驱动 Html-Css JavaScript jQuery HTML5 SharePoint GIS技术 SAP OracleERP DynamicsCRM K2 BPM 信息安全 企业信息 Android开发 iOS开发 WindowsPhone WindowsMobile 其他手机 敏捷开发 项目管理 软件工程 SQLServer Oracle MySQL NoSQL 其它数据库 Windows7 WindowsServer Linux
   -> Android开发 -> ToolBar -> 正文阅读

[Android开发]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
  Android开发 最新文章
Android动态权限申请
使用Kotlin,抛弃findViewById
.net程序员做的第一个安卓APP
Android学习笔记
计算机毕业设计源码分享
计算机毕业设计源码分享
ELF Format 笔记(一)—— 概述
Fragment学习笔记
Android复制Assets目录下的文件到指定目录
Android网络请求框架AsyncHttpClient实例详
上一篇文章           查看所有文章
加:2017-11-18 23:30:30  更:2017-11-18 23:30:33 
 
360图书馆 软件开发资料 购物精选 新闻资讯 Chinese Culture 三丰软件 开发 中国文化 阅读网 日历 万年历 2019年9日历
2019-9-20 1:31:56
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  编程知识