Android5.0--- Toolbar

原博地址:Android开发:最详细的 Toolbar 开发实践总结

ToolBar的基本使用

这里写图片描述

简介

toolbar是Android5.0时代替actionbar的控件(兼容5.0以下的使用V7中的toolbar),可以设置:导航图标 + App Logo + Title + SubTitle + customView + action menu

导包:

compile 'com.android.support:appcompat-v7:24.2.1'

1 设置导航图标
2 设置app logo
3 设置标题+子标题
4 添加自定义view
5 添加action menu

基本使用 ##

navatigation +app logo + title +subtitle可以进行代码设置,也可以xml中设置

代码中使用

Toolbar toobar = (Toolbar) findViewById(R.id.toobar);

toobar.setNavigationIcon(R.mipmap.ic_drawer_home);
toobar.setLogo(R.mipmap.ic_launcher);
toobar.setTitle("Title");
toobar.setSubtitle("Subtitle");

//menu:
toobar.inflateMenu(R.menu.menu_toobar);

toobar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
  @Override
  public boolean onMenuItemClick(MenuItem item) {
      switch (item.getItemId()) {
          case R.id.menu_ic_search:
              Toast.makeText(context,"ic_search",Toast.LENGTH_SHORT).show();
              break;
          case R.id.menu_ic_notification:
              Toast.makeText(context,"notification",Toast.LENGTH_SHORT).show();

              break;
          case R.id.menu_item1:
              Toast.makeText(context,"menu_item1",Toast.LENGTH_SHORT).show();

              break;
          case R.id.menu_item2:
              Toast.makeText(context,"menu_item2",Toast.LENGTH_SHORT).show();

              break;
      }

      return false;
  }
});

布局中使用

注意:Toolbar的根布局中要使用:xmlns:toobar=”http://schemas.android.com/apk/res-auto” ,不然toolbar的属性值无效,其中toolbar是自定义的,一般定义为app。

activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:toobar="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.cqc.toobardemo01.MainActivity">
        <!--xml设置属性navigationIcon + logo + title + subtitle,需要自定义命名空间 -->
        <!-- xmlns:toobar="http://schemas.android.com/apk/res-auto"-->
        <android.support.v7.widget.Toolbar
            android:id="@+id/toobar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#303F9F"
            toobar:logo="@mipmap/ic_launcher"
            toobar:navigationIcon="@mipmap/ic_drawer_home"
            toobar:popupTheme="@style/Theme.Toolbar.base"
            toobar:subtitle="subtitle"
            toobar:title="Title">

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

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

    </LinearLayout>

menu_toolbar.xml:

    <?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">

    <!--menu 使用showAsAction 需要xmlns:app="http://schemas.android.com/apk/res-auto"-->
     <!--其中 app是自定义的-->

        <item
            android:id="@+id/menu_ic_search"
            android:icon="@mipmap/ic_search"
            android:title="search"
            app:showAsAction="always"/>

        <item
            android:id="@+id/menu_ic_notification"
            android:icon="@mipmap/ic_notifications"
            android:title="notification"
            app:showAsAction="ifRoom"/>

        <item
            android:id="@+id/menu_item1"
            android:title="menu_item1"
            app:showAsAction="ifRoom"/>
        <item
            android:id="@+id/menu_item2"
            android:title="menu_item2"
            app:showAsAction="ifRoom"/>
    </menu>

Toolbar的高级使用

属性

title暂用的空间是这个toolbar剩余的,如果menu过大,会挤压title的空间,title过长的话,会省略显示即“…”,

xml

<android.support.v7.widget.Toolbar
    android:id="@+id/toolBar"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/toolbarBG"
    app:navigationIcon="@mipmap/ic_menu_white"
    app:logo="@mipmap/ic_launcher"
    app:titleMarginStart="10dp"
    app:title="@string/app_name"
    app:titleTextColor="@android:color/white"
    app:titleTextAppearance="@style/ToolbarTitleTextAppearance"
    app:popupTheme="@style/Theme.Toolbar.menu"/>

其它:

android:minHeight="?attr/actionBarSize"
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"

xml + meth

xml属性对应的方法含义
android:background=setBackGround(int resId)整个Toolbar的背景色
app:navigationIcon=setNavigationIcon(int resId)导航栏图标
app:logo=setLogo(int resId)Toolbar的logo(通常与navigationIcon的间距过大)
app:title=setTitle(String title)标题
app:titleTextColor=setTitleTextColor(int color)字体颜色
app:titleTextAppearance=setTitleTextAppearance(int style)style:字体大小+颜色
app:titleMargin=”“setTitleMargin(int margin)间距
app:titleMarginStart=setTitleMarginStart(int margin)左间距
app:titleMarginEnd=”“setTitleMarginEnd(int margin)右间距
app:titleMarginTop=”“setTitleMarginTop(int margin)上间距
app:titleMarginBottom=”“setTitleMarginBottom(int margin)下间距
app:subtitle=”subtitle”setSubtitle(String subtitle)子标题内容
app:subtitleTextColor=”“setSubtitleTextColor(int clolor)子标题文字颜色
toobar:subtitleTextAppearance=”“setSubtitleTextAppearance(Context context,int style)子标题style:文字大小+颜色
app:popupTheme=”“toolbar.setPopupTheme(int resId)menu的Style:字体大小和颜色

Title + SubTitle 的Style

Toolbar的title和subTitle的字体大小在xml中无法直接设置,必须通过style中的android:textSize=属性更改字体大小。

<!--Toobar的字体style-->
<!-- parent="Base.TextAppearance.AppCompat.Title"也可以-->
<style name="ToolbarTitleTextAppearance" parent="Base.TextAppearance.Widget.AppCompat.Toolbar.Title">
    <item name="android:textSize">18sp</item>
</style>
//颜色
toobar.setTitleTextColor(0x33fb4804);
toobar.setSubtitleTextColor(0xBB000000);
//style:字体大小+颜色
toobar.setTitleTextAppearance(context,android.support.annotation.StyleRes int resId);
toobar.setSubtitleTextAppearance(context,android.support.annotation.StyleRes int resId);
<!--toolbar 设置action menu-->
<style name="Theme.Toolbar.base" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="actionMenuTextColor">#fb4804</item><!--无效-->
    <item name="android:textColorPrimary">#fb4804</item>
    <item name="android:textSize">25sp</item><!--menu的字体-->
    <item name="android:colorBackground">@color/mtrl_white_100</item><!--menu的背景色-->
</style>

在xml中引用:

app:popupTheme="@style/Theme.Toolbar.base"

其他

app:popupTheme="@style/AppTheme.PopupOverlay"
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
<?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">

<!--menu 使用showAsAction 需要xmlns:app="http://schemas.android.com/apk/res-auto"-->
 <!--其中 app是自定义的-->

    <item
        android:id="@+id/menu_ic_search"
        android:icon="@mipmap/ic_search"
        android:title="search"
        app:showAsAction="always"/>

    <item
        android:id="@+id/menu_ic_notification"
        android:icon="@mipmap/ic_notifications"
        android:title="notification"
        app:showAsAction="ifRoom"/>

    <item
        android:id="@+id/menu_item1"
        android:title="menu_item1"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/menu_item2"
        android:title="menu_item2"
        app:showAsAction="ifRoom"/>
</menu>

2种方式填充menu?

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

或者

toobar.inflateMenu(R.menu.menu_toobar);

为什么在Fragment中调用onCreateOptionsMenu(Menu menu, MenuInflater inflater)无效?

原因
通过查看该方法源码,我们在其方法注释中看到着了一句

For this method to be called, you must have first called {@link #setHasOptionsMenu}

也就是在fragment中如果想给actionbar或者toolbar添加menu,必须先调用setHasOptionsMenu(),一般在oncreate()方法中调用。
这里写图片描述
解决:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setHasOptionsMenu(true);
}


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

2种方式点击menu

toobar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
  @Override
  public boolean onMenuItemClick(MenuItem item) {
      switch (item.getItemId()) {
          case R.id.menu_ic_search:
              Toast.makeText(context,"ic_search",Toast.LENGTH_SHORT).show();
              break;
      return false;
  }

或者:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

怎么设置Title与Logo的间距 ?

XML:
app:titleMarginStart="10dp"

代码:
toolbar.setTitleMarginStart(int margin);

怎么让title居中?

title居中,使用属性app:title="Title",实现不了,通过给Toolbar设置子View,让其居中来实现。但是这样的话,调用toolbar.setTitle("修改个人信息");无效。

<TextView
    android:id="@+id/tv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:text="text"/>

为了解决这个bug,我们需要将TextView的宽改为wrap_content,android:layout_gravity="center"

<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="?attr/actionBarSize"
    android:background="@color/primary">

    <TextView
        android:id="@+id/toolbar_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:singleLine="true"
        android:textColor="@color/white"
        android:textSize="20sp" />
</android.support.v7.widget.Toolbar>

点击事件

navatigation 的点击事件,menu的点击事件
app logo + title +subtitle 没有点击事件

toobar.setNavigationOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View view) {

                   Toast.makeText(context,"NavigationIcon",Toast.LENGTH_SHORT).show();
       }
});


toobar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
       @Override
       public boolean onMenuItemClick(MenuItem item) {
           switch (item.getItemId()) {
               case R.id.menu_ic_search:
                   Toast.makeText(context,"ic_search",Toast.LENGTH_SHORT).show();
                   break;
               case R.id.menu_ic_notification:
                   Toast.makeText(context,"notification",Toast.LENGTH_SHORT).show();

                   break;
               case R.id.menu_item1:
                   Toast.makeText(context,"menu_item1",Toast.LENGTH_SHORT).show();

                   break;
               case R.id.menu_item2:
                   Toast.makeText(context,"menu_item2",Toast.LENGTH_SHORT).show();

                   break;
           }

           return false;//改成true也可以,为什么??
       }
   });

将ActionBar改成Toolbar

Activity:

public Toolbar initToolbar(String title) {
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    toolbar.setTitle(title);
    setSupportActionBar(toolbar);
    android.support.v7.app.ActionBar actionBar = getSupportActionBar();
    if (actionBar != null) {
        actionBar.setDisplayHomeAsUpEnabled(true);
    }
    return toolbar;
}

fragment:

((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);

点击下载源码

在Toolbar上设置SearchView

这里写图片描述
如果用系统的view,那么使用actionViewClass,当然,也可以自定义layout,这时就需要用actionLayout

menu_main.xml

<?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">

    <!--android:actionViewClass="android.widget.SearchView"  activity继承自V7包的AppCompatActivity,那么就必须使用V7下的SearchView-->
    <item
        android:id="@+id/app_bar_search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        android:icon="@drawable/ic_search_black_24dp"
        app:showAsAction="ifRoom|collapseActionView"
        android:title="Search"/>
</menu>

获取SearchView和设置缩放监听:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    //获取 SearchView
    MenuItem searchItem = menu.findItem(R.id.app_bar_search);

    MenuItemCompat.OnActionExpandListener onActionExpandListener = new MenuItemCompat.OnActionExpandListener() {
        @Override
        public boolean onMenuItemActionExpand(MenuItem item) {
            ToastUtil.showShortToast(context, "expand");
            return true;
        }

        @Override
        public boolean onMenuItemActionCollapse(MenuItem item) {
            ToastUtil.showShortToast(context, "collapse");
            return true;
        }
    };

    MenuItemCompat.setOnActionExpandListener(searchItem, onActionExpandListener);

    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);//过时
    return true;
}

在toolbar内部添加子view,左侧会有空白

参考:使用Toolbar/ActionBar自定义布局时,左侧/右侧有一段无法使用
如图:
这里写图片描述
修改方法,给toolbar添加参数:

app:contentInsetStart="0dp"

当然,也有另一个属性

app:contentInsetRight="0dp"
 <android.support.v7.widget.Toolbar
   android:id="@+id/toolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    android:layout_gravity="bottom"
    app:contentInsetStart="0dp"
    app:contentInsetRight="0dp"
    app:layout_collapseMode="pin">

    <android.support.design.widget.TabLayout
        android:id="@+id/tabLayout"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:layout_margin="0dp"
        android:background="#f00"
        app:tabGravity="center"
        app:tabMode="scrollable"/>
</android.support.v7.widget.Toolbar>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值