Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView

时间:2022-09-09 08:14:59

Snackbar

Snackbar提供了一个介于Toast和AlertDialog之间轻量级控件,它可以很方便的提供消息的提示和动作反馈。
Snackbar的使用与Toast的使用基本相同:
Snackbar.make(view, Snackbar comes out, Snackbar.LENGTH_LONG)
                        .setAction(Action, new View.OnClickListener() {

@Override

public void onClick(View v) {

Toast.makeText(

MainActivity.this,

Toast comes out,

Toast.LENGTH_SHORT).show();

}

}).show();

需要注意的是,这里我们把第一个参数作为Snackbar显示的基准元素,而设置的Action也可以设置多个。(画线区域为snackbar显示样子)
Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView

Toolbar
Toolbar是应用的内容的标准工具栏,可以说是Actionbar的升级版,两者不是独立关系,要使用Toolbar还是得跟 ActionBar扯上关系的。相比Actionbar Toolbar最明显的一点就是变得很*,可随处放置,因为它是作为一个ViewGroup来定义使用的,所以单纯使用ActionBar已经稍显过时 了,它的一些方法已被标注过时。

Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView

从左到右分别是我们前面提及到的导航栏图标,App的logo,标题和子标题,自定义控件以及ActionMenu 。

那么它怎么使用呢,首先我们一样要用到v7的支持包,然后定义程序的主题样式,在style里得先把Actionbar去掉,有点像欲想练功,必先自宫的感觉啊。如下:

/res/values/styles.xml

<style name="AppBaseTheme" parent="Theme.AppCompat.Light.NoActionBar">

<!-- toolbar(actionbar)颜色 -->

<item name="colorPrimary">#4876FF</item>

<!-- 状态栏颜色 -->

<item name="colorPrimaryDark">#3A5FCD</item>

<!-- 窗口的背景颜色 -->

<item name="android:windowBackground">@android:color/white</item>

<!-- SearchView -->

<item name="searchViewStyle">@style/MySearchViewStyle</item>  
   <!-- 底部导航栏颜色 -->  
      <item name="android:navigationBarColor">#4876FF</item> 
   </style>

去除Actionbar最简单的方法就是直接继承NoActionBar的主题了。颜色的属性说明,还是下面这张图最清楚了: 
Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView
SearchView在AppCompat中提供了更强的可定制性和更多的样式可供设置,不过一般我们用默认的就行。
toolbar属性:
Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView

Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView
使用代码:
mToolbar = (Toolbar) findViewById(R.id.toolbar);

// toolbar.setLogo(R.drawable.ic_launcher);

mToolbar.setTitle("Rocko");// 标题的文字需在setSupportActionBar之前,不然会无效

// toolbar.setSubtitle("副标题");

setSupportActionBar(mToolbar);

/* 这些通过ActionBar来设置也是一样的,注意要在setSupportActionBar(toolbar);之后,不然就报错了 */

// getSupportActionBar().setTitle("标题");

// getSupportActionBar().setSubtitle("副标题");

// getSupportActionBar().setLogo(R.drawable.ic_launcher);

/* 菜单的监听可以在toolbar里设置,也可以像ActionBar那样,通过Activity的onOptionsItemSelected回调方法来处理 */

mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {

@Override

public boolean onMenuItemClick(MenuItem item) {

switch (item.getItemId()) {

case R.id.action_settings:

Toast.makeText(MainActivity.this, "action_settings", 0).show();

break;

case R.id.action_share:

Toast.makeText(MainActivity.this, "action_share", 0).show();

break;

default:

break;

}

return true;

}

});  
上面关键的一点就是setSupportActionBar(mToolbar);把Toolbar当做ActionBar给设置了。menu还是可以像ActionBar一样用和处理的。

有几个代码里面需要注意的地方:

· 我们在使用 Toolbar 时候需要先隐藏掉系统原先的导航栏,网上很多人都说给Activity设置一个NoActionBar的Theme。但个人觉得有点小题大做了,所以这里 我直接在BaseActivity中调用 supportRequestWindowFeature(Window.FEATURE_NO_TITLE) 去掉了默认的导航栏(注意,我的BaseActivity是继承了AppCompatActivity的,如果是继承Activity就应该调用 requestWindowFeature(Window.FEATURE_NO_TITLE));

· 如果你想修改标题和子标题的字体大小、颜色等,可以调用 setTitleTextColor setTitleTextAppearance

setSubtitleTextColor  setSubtitleTextAppearance 这些API;

· 自定义的View位于 title subtitle 和 actionmenu 之间,这意味着,如果 title 和 subtitle 都在,且actionmenu选项 太多的时候,留给自定义View的空间就越小;

· 导航图标和 app logo 的区别在哪?如果你只设置 导航图标(or app logo)和 title subtitle,会发现 app logo 和 title subtitle 的间距比较小,看起来不如 导航图标 与 它们两搭配美观;

· Toolbar和其他控件一样,很多属性设置方法既支持代码设置,也支持在xml中设置(这里也是最最最最最坑爹的地方,如何坑爹法,请接着往下看);

Action Menu Item 的文字颜色设置无效

系统默设置了ActionMenu每个Item的文字颜色和大小,像ToolbarActivity在Google原生5.1系统下默认效果就是下面这样的:
Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView
此时,如果我有需求要改变一下item文字颜色,应该怎么破?我按照网上比较普遍的解决方案,做了如下两步的修改操作:

在styles.xml中自定义一个Theme,并设置 actionMenuTextColor 属性(注意:不是 android:actionMenuTextColor )

<style name="Theme.ToolBar.Base" parent="Theme.AppCompat.Light.NoActionBar">

<item name="actionMenuTextColor">@color/color_red</item>

</style>

在布局文件的Toolbar中设置popupTheme(注意:是toolbar:xxx,不是android:xxx)

<android.support.v7.widget.Toolbar

android:id="@+id/toolbar"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@color/color_0176da"

toolbar:popupTheme="@style/Theme.ToolBar.Base">

<!--自定义控件-->

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Clock" />

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

运行之后,文字的颜色的并没有发生任何改变。说好的改变颜色呢…..找来找去,最后再 * 找到一个还不错的解决方案,就是把上面的的 actionMenuTextColor 属性换成 android:textColorPrimary 即可解决,最终得到下面的运行效果。

Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView
成功修改 actionmenu item 文字的颜色
这种方法也有一个小缺点,如果我把自定义控件换成Button,你会发现Button默认的文字颜色也变成了红色。所以,此处如果有朋友有更好的解决方案,请留言赐教。

如果你想要修改 ActionMenu Item 的文字大小,也可以在theme中设置加上如下设置

<item name="android:textSize">20sp</item>

以上就是目前使用 Toolbar 一些比较折腾的坑,感觉 Google 对 Toolbar 这些坑,还可以进一步优化优化。

TabLayout

应用中通过Tab在不同视图中间切换对于材料设计而言并非一个新的概念,他们等同于主页的*导航模式或者在应用内组织不同群组的内容,如图。

Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView

TabLayout既实现了固定的选项卡 - view的宽度平均分配,也实现了可滚动的选项卡 - view宽度不固定同时可以横向滚动。

选项卡可以在程序中动态添加:
    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
     tabLayout.addTab(tabLayout.newTab().setText(tab1));         tabLayout.addTab(tabLayout.newTab().setText(tab2));         tabLayout.addTab(tabLayout.newTab().setText(tab3));

但大部分时间我们都不会这样用,通常滑动布局都会和ViewPager配合起来使用,所以,我们需要ViewPager来帮忙:

mViewPager = (ViewPager) findViewById(R.id.viewpager);

// 设置ViewPager的数据等

setupViewPager();

TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);

tabLayout.setupWithViewPager(mViewPager);

通过一句话setupWithViewPager,我们就把ViewPager和TabLayout结合了起来。

可以调整两个属性来显示 TabLayout:

  app:tabMode - 如果你想在屏幕上显示出每个单独的 tab,就设置 tab 为 fixed 的, 。它适合只有少数 tab 的时候,但是如果有很多的 tab 的时候这是一个完全错误的选择。在这种情况下你是不确定所有的 tab 是否能很好的在同一时间显示出来的。所以,你可以设置这个属性为 scrollable 让用户去滚动 tab,就像 Google Play Store 那样。

  app:tabGravity - 如果你想要分配所有的可用空间给每个 tab,就设置这个属性为 fill。如果你想要所有的 tab 在屏幕的中间,就设置这个属性为 center。请注意,如果 tabMode 是设置成 scrollable 的,则这个属性将会被忽略。

如下图
Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView

NavigationView
NavigationView在MD设计中非常重要,之前Google也提出了使用DrawerLayout来实现导航抽屉。
这次,在support library中,Google提供了NavigationView来实现导航菜单界面。
Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView

之前Google在V4包中推出自己的 DrawerLayout作为抽屉侧滑菜单,标准使用方法可以参考 google 原生态 抽屉式侧滑菜单 Android DrawerLayout 布局的使用介绍。
当时的官方布局是这样的:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/drawer_layout"

android:layout_width="match_parent"

android:layout_height="match_parent" >

<!-- the main content view -->

<FrameLayout

android:id="@+id/frame_content"

android:layout_width="match_parent"

android:layout_height="match_parent" >

</FrameLayout>

<!-- the navigetion view -->

<ListView

android:id="@+id/drawer_list"

android:layout_width="240dp"

android:layout_height="match_parent"

android:layout_gravity="start"

android:background="#9999cc"

android:choiceMode="singleChoice"

android:divider="@android:color/transparent"

android:dividerHeight="0dp" >

</ListView>

</android.support.v4.widget.DrawerLayout>

其实这次谷歌只是将上面的ListView布局替换成NavigationView了。简化了之前ListView写适配器的繁琐。

如今布局改成如下:

<android.support.v4.widget.DrawerLayout

xmlns:android='http://schemas.android.com/apk/res/android'

xmlns:app='http://schemas.android.com/apk/res-auto'

android:layout_width='match_parent'

android:layout_height='match_parent'

android:fitsSystemWindows='true'>

<!-- your content layout -->

<android.support.design.widget.NavigationView

android:layout_width='wrap_content'

android:layout_height='match_parent'

android:layout_gravity='start'

app:headerLayout='@layout/drawer_header'

app:menu='@menu/drawer'/>

</android.support.v4.widget.DrawerLayout>

其中最重要的就是这两个属性:
app:headerLayout //给NavigationView添加头部布局 
app:menu //给NavigationView添加menu菜单布局
通过这两个属性,我们可以非常方便的指定导航界面的头布局和菜单布局:

其中NavigationView 中的 android:layout_gravity=”start” 属性来控制抽屉菜单从哪边滑出,一般“start ”从左边滑出,“end”从右边滑出。

app:headerLayout布局如下:

<?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="200dp"

android:background="@drawable/img1"

android:gravity="center"

android:orientation="vertical">

<ImageView

android:layout_width="125dp"

android:layout_height="125dp"

android:scaleType="centerCrop"

android:src="@drawable/image" />

<TextView

android:layout_marginTop="15dp"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="CSDN废墟的树博客"

android:textColor="@android:color/white" />

</LinearLayout>

app:menu 布局如下:

<?xml version="1.0" encoding="utf-8"?>

<menu xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent">

<group

android:checkableBehavior="single"

android:title="Home items">

<item

android:id="@+id/nav_blog"

android:icon="@drawable/ic_account_balance_black_24dp"

android:title="博客地址" />

<item

android:id="@+id/nav_ver"

android:icon="@drawable/ic_error_outline_black_36dp"

android:title="版本信息" />

<item

android:id="@+id/nav_about"

android:icon="@drawable/ic_error_outline_black_36dp"

android:title="关于我" />

</group>

<item android:title="Sub items">

<menu>

<item

android:id="@+id/sub_exit"

android:icon="@drawable/ic_power_settings_new_black_36dp"

android:title="退出应用" />

<item

android:id="@+id/sub_switch"

android:icon="@drawable/ic_settings_applications_black_36dp"

android:title="切换主题" />

</menu>

</item>

</menu>

代码中控制NavigationView

private void initNavigationView(){

navigationView = (NavigationView) findViewById(R.id.navigationView);

drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

//设置侧滑菜单选择监听事件

navigationView.setNavigationItemSelectedListener(new  NavigationView.OnNavigationItemSelectedListener() {

@Override

public boolean onNavigationItemSelected(MenuItem menuItem) {

menuItem.setChecked(true);

//关闭抽屉侧滑菜单

drawerLayout.closeDrawers();

return true;

}

});

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

if (item.getItemId() == android.R.id.home){

//打开抽屉侧滑菜单

drawerLayout.openDrawer(GravityCompat.START);

}

return super.onOptionsItemSelected(item);

}

关于NavigationView中item的字体颜色和icon选中状态颜色是去当前主题theme中的

<--正常状态下字体颜色和icon颜色-->

<item name="android:textColorPrimary">@android:color/darker_gray</item>

<--选中状态icon的颜色和字体颜色-->

<item name="colorPrimary">@color/accent_material_light</item>

Android M 控件:Snackbar、Toolbar、TabLayout、NavigationView的更多相关文章

  1. 【转】Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

    Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用 分类: Android UI ...

  2. 【Android - 控件】之MD - NavigationView的使用

    NavigationView是Android 5.0新特性——Material Design中的一个布局控件,可以结合DrawerLayout使用,让侧滑菜单变得更加美观(可以添加头部布局). Nav ...

  3. Android 开源控件与常用开发框架开发工具类

    Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...

  4. android 基础控件(EditView、SeekBar等)的属性及使用方法

        android提供了大量的UI控件,本文将介绍TextView.ImageView.Button.EditView.ProgressBar.SeekBar.ScrollView.WebView ...

  5. Android基本控件之Menus

    在我们的手机中有很多样式的菜单,比如:我们的短信界面,每条短信,我们长按都会出现一个菜单,还有很多的种类.那么现在,我们就来详细的讨论一下安卓中的菜单 Android的控件中就有这么一个,叫做Menu ...

  6. Android:控件布局(相对布局)RelativeLayout

    RelativeLayout是相对布局控件:以控件之间相对位置或相对父容器位置进行排列. 相对布局常用属性: 子类控件相对子类控件:值是另外一个控件的id android:layout_above-- ...

  7. Android:控件布局(线性布局)LinearLayout

    LinearLayout是线性布局控件:要么横向排布,要么竖向排布 决定性属性:必须有的! android:orientation:vertical (垂直方向) .horizontal(水平方向) ...

  8. 矩阵&comma; 矩阵 &comma; Android基础控件之ImageView

    天下文章大家抄,以下所有内容,有来自copy,有来自查询,亦有自己的总结(目的是总结出自己的东西),所以说原创,不合适,说是转载也不恰当,所以我称之为笔记,可惜没有此分类选项,姑且不要脸一点,选择为原 ...

  9. Android给控件添加触摸回调

    Android给控件添加触摸回调 脑补一个场景,一个页面点击某个按钮会弹出PopupWindow,然后点击PopupWindow以外的任意位置关闭 效果图 实现方法 可以在布局的最外层容器监听触摸事件 ...

  10. Android 基本控件相关知识整理

    Android应用开发的一项重要内容就是界面开发.对于用户来说,不管APP包含的逻辑多么复杂,功能多么强大,如果没有提供友好的图形交互界面,将很难吸引最终用户.作为一个程序员如何才能开发出友好的图形界 ...

随机推荐

  1. Linux 下应用程序最大打开文件数的理解和修改

    运行在Linux系统上的Java程序运行了一段时间后出现"Too many open files"的异常情况. 这种情况常见于高并发访问文件系统,多线程网络连接等场景.程序经常访问 ...

  2. POJ 3469&Tab;Dual Core CPU 最大流

    划分成两个集合使费用最小,可以转成最小割,既最大流. //#pragma comment(linker, "/STACK:1024000000,1024000000") #incl ...

  3. Thymeleaf模板引擎使用

    Thymeleaf模板引擎使用 什么是Thymeleaf Thymeleaf是一个Java库.它是一个XML / XHTML / HTML5模板引擎,能够在模板文件上应用一组转换,将程序产生的数据或者 ...

  4. js-异常处理语句

    程序运行过程中难免会出错,出错后的运行结果往往是不正确的,因此运行时出错的程序通常被强制中止.运行时的错误统称为异常,为了能在错误发生时得到一个处理的机会,JavaScript提供了异常处理语句.包含 ...

  5. LeetCode Game of Life

    原题链接在这里:https://leetcode.com/problems/game-of-life/ 题目: According to the Wikipedia's article: " ...

  6. HTTP API 设计指南&lpar;中文版&rpar; restfull

    http://www.css88.com/archives/5121 目录 基础 总是使用TLS 在Accepts头中带上版本号 通过Etags支持缓存 用Request-Ids追踪请求 用Range ...

  7. jQuery的toggle&lpar;&rpar;的自动触发真烦人

    jQuery的toggle()方法应该是在鼠标点击后才会触发,现在的问题是在ready加载后就自动触发了,怎么回事呢? 答案是jQuery的版本问题,在1.9以后的版本toggle()就存在这个问题, ...

  8. pycharm 配置svn

    1.找到本地svn.exe 2.配置svn路径 3.输入svn路径,然后会进行密码校验 问题 本地的TortoiseSVN在bin目录没有发现svn.exe 原因: 安装TortoiseSVN的时候 ...

  9. Azure系列1&period;1&period;2 —— 用于 IntelliJ 的 Azure 工具包的登录说明

    (文中大部分内容(95%)Azure官网上有,我只是把我自己实际操作中遇到的问题在这里阐述一下.) 先决条件 若要完成文章中的步骤,需要安装用于 IntelliJ 的 Azure 工具包,该工具包需要 ...

  10. &lpar;转&rpar;sqlmap用户手册

    原文地址:http://drops.wooyun.org/papers/143 http://192.168.136.131/sqlmap/mysql/get_int.php?id=1 当给sqlma ...