转:http://blog.csdn.net/jdsjlzx/article/details/41441083

前言

我们都知道Marterial Design是Google推出的全新UI设计规范,如果对其不太了解的可以看下:Material design非官方中文指导手册 ,或者我的前面几篇Material Design的译文,相比之前Google在Android Holo风格上平平淡淡的表现不同,Material Design现在是被Google所比较重视的。在推出这门全新设计语言后,Android上自家的应用很快就使用Material Design全新设计了,如Play商店,Google Map,Google+,比较新的Inbox等;Web上的视觉体验也是很Material的,最有帮助的当属这个了Material Design的官方介绍(自备梯子)了;IOS方面的Google应用也在慢慢推进中。所以作为一个Android开发者怎么能不紧跟Google的步伐呢,下面就来通过Toolbar和Palette这两个在API21后推出的东西,当然Google已经把它们放到到v7库里了,使用Material Design来设计App当然不仅限于这两个方面了,前面的Material Design的译文已经清楚知道怎么去全面设计。除了Toolbar和Palette这篇文章还会介绍在Toolbar下使用Drawer,以及 Android L中的RecyclerView 、CardView 、Palette的使用。

  

Toolbar

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

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

<resources xmlns:android="http://schemas.android.com/apk/res/android">  <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>  </style>  <style name="AppTheme" parent="@style/AppBaseTheme"></style>  <style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView">  <!--  Background for the search query section (e.g. EditText)  <item name="queryBackground">...</item>  Background for the actions section (e.g. voice, submit)  <item name="submitBackground">...</item>  Close button icon  <item name="closeIcon">...</item>  Search button icon  <item name="searchIcon">...</item>  Go/commit button icon  <item name="goIcon">...</item>  Voice search button icon  <item name="voiceIcon">...</item>  Commit icon shown in the query suggestion row  <item name="commitIcon">...</item>  Layout for query suggestion rows  <item name="suggestionRowLayout">...</item>  -->  </style>  </resources>  

<resources xmlns:android="http://schemas.android.com/apk/res/android">  <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>  </style>  <style name="AppTheme" parent="@style/AppBaseTheme"></style>  <style name="MySearchViewStyle" parent="Widget.AppCompat.SearchView">  <!--  Background for the search query section (e.g. EditText)  <item name="queryBackground">...</item>  Background for the actions section (e.g. voice, submit)  <item name="submitBackground">...</item>  Close button icon  <item name="closeIcon">...</item>  Search button icon  <item name="searchIcon">...</item>  Go/commit button icon  <item name="goIcon">...</item>  Voice search button icon  <item name="voiceIcon">...</item>  Commit icon shown in the query suggestion row  <item name="commitIcon">...</item>  Layout for query suggestion rows  <item name="suggestionRowLayout">...</item>  -->  </style>  </resources>  

去除Actionbar最简单的方法就是直接继承NoActionBar的主题了。颜色的属性说明,还是下面这张图最清楚了:

另外,SearchView在AppCompat中提供了更强的可定制性和更多的样式可供设置,不过一般我们用默认的就行。

还有我们可以在values-v21给API21的系统版本设置默认的底部导航栏默认的颜色:

/res/values-v21/styles.xml

[html] view plaincopy
  1. <resources xmlns:android="http://schemas.android.com/apk/res/android">
  2. <style name="AppTheme" parent="@style/AppBaseTheme">
  3. <!-- 底部导航栏颜色 -->
  4. <item name="android:navigationBarColor">#4876FF</item>
  5. </style>
  6. </resources>
[html] view plaincopy
  1. <resources xmlns:android="http://schemas.android.com/apk/res/android">
  2. <style name="AppTheme" parent="@style/AppBaseTheme">
  3. <!-- 底部导航栏颜色 -->
  4. <item name="android:navigationBarColor">#4876FF</item>
  5. </style>
  6. </resources>

设置好主题的下一步工作:
在xml的layout中定义一个Toolbar:

/layout/toolbar.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res/com.example.toolbar"
  4. android:id="@+id/toolbar"
  5. android:layout_width="match_parent"
  6. android:layout_height="wrap_content"
  7. android:background="?attr/colorPrimary"
  8. android:minHeight="?attr/actionBarSize"
  9. app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
  10. app:theme="@style/ThemeOverlay.AppCompat.ActionBar" >
  11. </android.support.v7.widget.Toolbar>
[html] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res/com.example.toolbar"
  4. android:id="@+id/toolbar"
  5. android:layout_width="match_parent"
  6. android:layout_height="wrap_content"
  7. android:background="?attr/colorPrimary"
  8. android:minHeight="?attr/actionBarSize"
  9. app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
  10. app:theme="@style/ThemeOverlay.AppCompat.ActionBar" >
  11. </android.support.v7.widget.Toolbar>

我们把toolbar作为一个独立的布局xml,方便在其他布局里include进去。可以看到我们在这里是可以设置Toolbar的属性的,初上面的外还有以下的属性,都是见名知意的就不一一说明了。

然后在activity的布局里把它include进去就行了,当然一般把它放到最上面了,有需要你是可以把它放到中间、底部或其它位置的,可见它的自由度是很高的。在下一步呢就到代码了,在onCreate中:

[java] view plaincopy
  1. mToolbar = (Toolbar) findViewById(R.id.toolbar);
  2. // toolbar.setLogo(R.drawable.ic_launcher);
  3. mToolbar.setTitle("Rocko");// 标题的文字需在setSupportActionBar之前,不然会无效
  4. // toolbar.setSubtitle("副标题");
  5. setSupportActionBar(mToolbar);
  6. /* 这些通过ActionBar来设置也是一样的,注意要在setSupportActionBar(toolbar);之后,不然就报错了 */
  7. // getSupportActionBar().setTitle("标题");
  8. // getSupportActionBar().setSubtitle("副标题");
  9. // getSupportActionBar().setLogo(R.drawable.ic_launcher);
  10. /* 菜单的监听可以在toolbar里设置,也可以像ActionBar那样,通过Activity的onOptionsItemSelected回调方法来处理 */
  11. mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
  12. @Override
  13. public boolean onMenuItemClick(MenuItem item) {
  14. switch (item.getItemId()) {
  15. case R.id.action_settings:
  16. Toast.makeText(MainActivity.this, "action_settings", 0).show();
  17. break;
  18. case R.id.action_share:
  19. Toast.makeText(MainActivity.this, "action_share", 0).show();
  20. break;
  21. default:
  22. break;
  23. }
  24. return true;
  25. }
  26. });
[java] view plaincopy
  1. mToolbar = (Toolbar) findViewById(R.id.toolbar);
  2. // toolbar.setLogo(R.drawable.ic_launcher);
  3. mToolbar.setTitle("Rocko");// 标题的文字需在setSupportActionBar之前,不然会无效
  4. // toolbar.setSubtitle("副标题");
  5. setSupportActionBar(mToolbar);
  6. /* 这些通过ActionBar来设置也是一样的,注意要在setSupportActionBar(toolbar);之后,不然就报错了 */
  7. // getSupportActionBar().setTitle("标题");
  8. // getSupportActionBar().setSubtitle("副标题");
  9. // getSupportActionBar().setLogo(R.drawable.ic_launcher);
  10. /* 菜单的监听可以在toolbar里设置,也可以像ActionBar那样,通过Activity的onOptionsItemSelected回调方法来处理 */
  11. mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
  12. @Override
  13. public boolean onMenuItemClick(MenuItem item) {
  14. switch (item.getItemId()) {
  15. case R.id.action_settings:
  16. Toast.makeText(MainActivity.this, "action_settings", 0).show();
  17. break;
  18. case R.id.action_share:
  19. Toast.makeText(MainActivity.this, "action_share", 0).show();
  20. break;
  21. default:
  22. break;
  23. }
  24. return true;
  25. }
  26. });

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

res/menu/main.xml

[html] view plaincopy
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:app="http://schemas.android.com/apk/res-auto"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. tools:context=".MainActivity" >
  5. <item
  6. android:id="@+id/ab_search"
  7. android:orderInCategory="80"
  8. android:title="action_search"
  9. app:actionViewClass="android.support.v7.widget.SearchView"
  10. app:showAsAction="ifRoom"/>
  11. <item
  12. android:id="@+id/action_share"
  13. android:orderInCategory="90"
  14. android:title="action_share"
  15. app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
  16. app:showAsAction="ifRoom"/>
  17. <item
  18. android:id="@+id/action_settings"
  19. android:orderInCategory="100"
  20. android:title="action_settings"
  21. app:showAsAction="never"/>
  22. </menu>
[html] view plaincopy
  1. <menu xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:app="http://schemas.android.com/apk/res-auto"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. tools:context=".MainActivity" >
  5. <item
  6. android:id="@+id/ab_search"
  7. android:orderInCategory="80"
  8. android:title="action_search"
  9. app:actionViewClass="android.support.v7.widget.SearchView"
  10. app:showAsAction="ifRoom"/>
  11. <item
  12. android:id="@+id/action_share"
  13. android:orderInCategory="90"
  14. android:title="action_share"
  15. app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
  16. app:showAsAction="ifRoom"/>
  17. <item
  18. android:id="@+id/action_settings"
  19. android:orderInCategory="100"
  20. android:title="action_settings"
  21. app:showAsAction="never"/>
  22. </menu>

这一步时候程序的样子:
   PS.  Genymotion可以用5.0的模拟器了

可以感觉到这样是不是和ActionBar没什么区别呢。诶,左边的菜单图标怎么出来的呢,其实上面还没处理到,他就是Navigation drawer了,使用新版本的v4、v7库的drawer明显的一点是它带了一个酷酷的交互动画(请看最后的gif图)。那么使用Toolbar之后又怎么去在Toolbar中使用drawer呢。下面当然也是跟着代码来.

/layout/activity_main.xml

[html] view plaincopy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. tools:context="com.example.toolbar.MainActivity" >
  7. <include layout="@layout/toolbar" />
  8. <android.support.v4.widget.DrawerLayout
  9. android:id="@+id/drawer"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent" >
  12. <!-- 内容界面 -->
  13. <LinearLayout
  14. android:layout_width="match_parent"
  15. android:layout_height="match_parent"
  16. android:orientation="vertical" >
  17. <com.example.toolbar.widget.PagerSlidingTabStrip
  18. android:id="@+id/tabs"
  19. android:layout_width="match_parent"
  20. android:layout_height="48dip" >
  21. </com.example.toolbar.widget.PagerSlidingTabStrip>
  22. <android.support.v4.view.ViewPager
  23. android:id="@+id/pager"
  24. android:layout_width="match_parent"
  25. android:layout_height="match_parent" >
  26. </android.support.v4.view.ViewPager>
  27. </LinearLayout>
  28. <!-- 侧滑菜单内容 -->
  29. <LinearLayout
  30. android:id="@+id/drawer_view"
  31. android:layout_width="match_parent"
  32. android:layout_height="match_parent"
  33. android:layout_gravity="start"
  34. android:background="@drawable/drawer"
  35. android:orientation="vertical"
  36. android:padding="8dp" >
  37. <TextView
  38. android:layout_width="match_parent"
  39. android:layout_height="match_parent" />
  40. </LinearLayout>
  41. </android.support.v4.widget.DrawerLayout>
  42. </LinearLayout>
[html] view plaincopy
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. android:orientation="vertical"
  6. tools:context="com.example.toolbar.MainActivity" >
  7. <include layout="@layout/toolbar" />
  8. <android.support.v4.widget.DrawerLayout
  9. android:id="@+id/drawer"
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent" >
  12. <!-- 内容界面 -->
  13. <LinearLayout
  14. android:layout_width="match_parent"
  15. android:layout_height="match_parent"
  16. android:orientation="vertical" >
  17. <com.example.toolbar.widget.PagerSlidingTabStrip
  18. android:id="@+id/tabs"
  19. android:layout_width="match_parent"
  20. android:layout_height="48dip" >
  21. </com.example.toolbar.widget.PagerSlidingTabStrip>
  22. <android.support.v4.view.ViewPager
  23. android:id="@+id/pager"
  24. android:layout_width="match_parent"
  25. android:layout_height="match_parent" >
  26. </android.support.v4.view.ViewPager>
  27. </LinearLayout>
  28. <!-- 侧滑菜单内容 -->
  29. <LinearLayout
  30. android:id="@+id/drawer_view"
  31. android:layout_width="match_parent"
  32. android:layout_height="match_parent"
  33. android:layout_gravity="start"
  34. android:background="@drawable/drawer"
  35. android:orientation="vertical"
  36. android:padding="8dp" >
  37. <TextView
  38. android:layout_width="match_parent"
  39. android:layout_height="match_parent" />
  40. </LinearLayout>
  41. </android.support.v4.widget.DrawerLayout>
  42. </LinearLayout>

Pager的东西可以先忽略,后面会说到。侧滑菜单的内容为简单起见直接先用图片来演示了。可以看到布局的设置大同小异,不同点在代码中:

[java] view plaincopy
  1. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  2. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
  3. mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open,
  4. R.string.drawer_close);
  5. mDrawerToggle.syncState();
  6. mDrawerLayout.setDrawerListener(mDrawerToggle);
[java] view plaincopy
  1. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  2. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
  3. mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open,
  4. R.string.drawer_close);
  5. mDrawerToggle.syncState();
  6. mDrawerLayout.setDrawerListener(mDrawerToggle);

先把图标设置显示出来,然后把ActionBarDrawerToggle作为DrawerLayout的监听器设置进去,还是比较简单的,效果:

要是需要把drawer覆盖toolbar怎么办呢?需要稍微调整一下界面的布局位置就行了,效果就不贴上来了(脑补,或者改下源码的setContentView运行):

[html] view plaincopy
  1. <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:id="@+id/drawer"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:fitsSystemWindows="true" >
  7. <LinearLayout
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:orientation="vertical"
  11. tools:context="com.example.toolbar.MainActivity" >
  12. <include layout="@layout/toolbar" />
  13. <!-- 内容界面 -->
  14. <LinearLayout
  15. android:layout_width="match_parent"
  16. android:layout_height="match_parent"
  17. android:background="@drawable/content"
  18. android:orientation="vertical" >
  19. <com.example.toolbar.widget.PagerSlidingTabStrip
  20. android:id="@+id/tabs"
  21. android:layout_width="match_parent"
  22. android:layout_height="48dip"
  23. android:visibility="invisible" >
  24. </com.example.toolbar.widget.PagerSlidingTabStrip>
  25. <android.support.v4.view.ViewPager
  26. android:id="@+id/pager"
  27. android:layout_width="match_parent"
  28. android:layout_height="match_parent"
  29. android:visibility="invisible" >
  30. </android.support.v4.view.ViewPager>
  31. </LinearLayout>
  32. </LinearLayout>
  33. <!-- 侧滑菜单内容 -->
  34. <LinearLayout
  35. android:id="@+id/drawer_view"
  36. android:layout_width="match_parent"
  37. android:layout_height="match_parent"
  38. android:layout_gravity="start"
  39. android:background="@drawable/drawer"
  40. android:orientation="vertical"
  41. android:clickable="true"
  42. android:padding="8dp" >
  43. <TextView
  44. android:layout_width="match_parent"
  45. android:layout_height="match_parent" />
  46. </LinearLayout>
  47. </android.support.v4.widget.DrawerLayout>
[html] view plaincopy
  1. <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:id="@+id/drawer"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:fitsSystemWindows="true" >
  7. <LinearLayout
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent"
  10. android:orientation="vertical"
  11. tools:context="com.example.toolbar.MainActivity" >
  12. <include layout="@layout/toolbar" />
  13. <!-- 内容界面 -->
  14. <LinearLayout
  15. android:layout_width="match_parent"
  16. android:layout_height="match_parent"
  17. android:background="@drawable/content"
  18. android:orientation="vertical" >
  19. <com.example.toolbar.widget.PagerSlidingTabStrip
  20. android:id="@+id/tabs"
  21. android:layout_width="match_parent"
  22. android:layout_height="48dip"
  23. android:visibility="invisible" >
  24. </com.example.toolbar.widget.PagerSlidingTabStrip>
  25. <android.support.v4.view.ViewPager
  26. android:id="@+id/pager"
  27. android:layout_width="match_parent"
  28. android:layout_height="match_parent"
  29. android:visibility="invisible" >
  30. </android.support.v4.view.ViewPager>
  31. </LinearLayout>
  32. </LinearLayout>
  33. <!-- 侧滑菜单内容 -->
  34. <LinearLayout
  35. android:id="@+id/drawer_view"
  36. android:layout_width="match_parent"
  37. android:layout_height="match_parent"
  38. android:layout_gravity="start"
  39. android:background="@drawable/drawer"
  40. android:orientation="vertical"
  41. android:clickable="true"
  42. android:padding="8dp" >
  43. <TextView
  44. android:layout_width="match_parent"
  45. android:layout_height="match_parent" />
  46. </LinearLayout>
  47. </android.support.v4.widget.DrawerLayout>

做这里时发现拉出菜单后还是可以点击Toggle按钮的,解决方法时把侧滑的布局设置为clickable="true"。关于侧滑菜单需不需要的覆盖Toolbar的问题好像从Google提供的例子来看两者都有。我想既然它做出这个Toggle按钮的动画来的话如果覆盖了不就没有意义了?或者还有其它考虑?暂时我们看着Google Play来就行,新版Play的是没有覆盖上去的。

Palette

说Palette之前先说下前面提到的Pager。ViewPager是什么大家应该都是知道的了,一般ViewPager、xxxTabStrip、Fragment三个好基友是一起出现的。这里的xxxTabStrip是使用Github上的PagerSlidingTabStrip。当我们的Pager切换时伴随着Fragment的变化,而Fragment里的内容一般是不同的,所以每个Fragment里的一般视觉效果也是不同的,所以我们可以用Palette来去提取Fragment中的主色调,那Fragment中的拿什么给Palatte去提取颜色呢,这就需要自己根据自己的情况来决定的。比如我这个demo里,Fragment就一个TextView和给Fragment设了背景,那么我就可以把背景的图片给Palette去提取颜色了。

说了上面一段你也基本知道Palatte是用来干么的了,它就是用来从Bitmap中提取颜色的,然后把颜色设置给title啊content啊等等。

先贴上Pager部分的代码:

[java] view plaincopy
  1. private void initViews() {
  2. mToolbar = (Toolbar) findViewById(R.id.toolbar);
  3. // toolbar.setLogo(R.drawable.ic_launcher);
  4. mToolbar.setTitle("Rocko");// 标题的文字需在setSupportActionBar之前,不然会无效
  5. // toolbar.setSubtitle("副标题");
  6. setSupportActionBar(mToolbar);
  7. /* 这些通过ActionBar来设置也是一样的,注意要在setSupportActionBar(toolbar);之后,不然就报错了 */
  8. // getSupportActionBar().setTitle("标题");
  9. // getSupportActionBar().setSubtitle("副标题");
  10. // getSupportActionBar().setLogo(R.drawable.ic_launcher);
  11. /* 菜单的监听可以在toolbar里设置,也可以像ActionBar那样,通过下面的两个回调方法来处理 */
  12. mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
  13. @Override
  14. public boolean onMenuItemClick(MenuItem item) {
  15. switch (item.getItemId()) {
  16. case R.id.action_settings:
  17. Toast.makeText(MainActivity.this, "action_settings", 0).show();
  18. break;
  19. case R.id.action_share:
  20. Toast.makeText(MainActivity.this, "action_share", 0).show();
  21. break;
  22. default:
  23. break;
  24. }
  25. return true;
  26. }
  27. });
  28. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  29. /* findView */
  30. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
  31. mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open,
  32. R.string.drawer_close);
  33. mDrawerToggle.syncState();
  34. mDrawerLayout.setDrawerListener(mDrawerToggle);
  35. mPagerSlidingTabStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs);
  36. mViewPager = (ViewPager) findViewById(R.id.pager);
  37. mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
  38. mPagerSlidingTabStrip.setViewPager(mViewPager);
  39. mPagerSlidingTabStrip.setOnPageChangeListener(new OnPageChangeListener() {
  40. @Override
  41. public void onPageSelected(int arg0) {
  42. colorChange(arg0);
  43. }
  44. @Override
  45. public void onPageScrolled(int arg0, float arg1, int arg2) {
  46. }
  47. @Override
  48. public void onPageScrollStateChanged(int arg0) {
  49. }
  50. });
  51. initTabsValue();
  52. }
  53. /**
  54. * mPagerSlidingTabStrip默认值配置
  55. *
  56. */
  57. private void initTabsValue() {
  58. // 底部游标颜色
  59. mPagerSlidingTabStrip.setIndicatorColor(Color.BLUE);
  60. // tab的分割线颜色
  61. mPagerSlidingTabStrip.setDividerColor(Color.TRANSPARENT);
  62. // tab背景
  63. mPagerSlidingTabStrip.setBackgroundColor(Color.parseColor("#4876FF"));
  64. // tab底线高度
  65. mPagerSlidingTabStrip.setUnderlineHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  66. 1, getResources().getDisplayMetrics()));
  67. // 游标高度
  68. mPagerSlidingTabStrip.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  69. 5, getResources().getDisplayMetrics()));
  70. // 选中的文字颜色
  71. mPagerSlidingTabStrip.setSelectedTextColor(Color.WHITE);
  72. // 正常文字颜色
  73. mPagerSlidingTabStrip.setTextColor(Color.BLACK);
  74. }
[java] view plaincopy
  1. private void initViews() {
  2. mToolbar = (Toolbar) findViewById(R.id.toolbar);
  3. // toolbar.setLogo(R.drawable.ic_launcher);
  4. mToolbar.setTitle("Rocko");// 标题的文字需在setSupportActionBar之前,不然会无效
  5. // toolbar.setSubtitle("副标题");
  6. setSupportActionBar(mToolbar);
  7. /* 这些通过ActionBar来设置也是一样的,注意要在setSupportActionBar(toolbar);之后,不然就报错了 */
  8. // getSupportActionBar().setTitle("标题");
  9. // getSupportActionBar().setSubtitle("副标题");
  10. // getSupportActionBar().setLogo(R.drawable.ic_launcher);
  11. /* 菜单的监听可以在toolbar里设置,也可以像ActionBar那样,通过下面的两个回调方法来处理 */
  12. mToolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
  13. @Override
  14. public boolean onMenuItemClick(MenuItem item) {
  15. switch (item.getItemId()) {
  16. case R.id.action_settings:
  17. Toast.makeText(MainActivity.this, "action_settings", 0).show();
  18. break;
  19. case R.id.action_share:
  20. Toast.makeText(MainActivity.this, "action_share", 0).show();
  21. break;
  22. default:
  23. break;
  24. }
  25. return true;
  26. }
  27. });
  28. getSupportActionBar().setDisplayHomeAsUpEnabled(true);
  29. /* findView */
  30. mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
  31. mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.drawer_open,
  32. R.string.drawer_close);
  33. mDrawerToggle.syncState();
  34. mDrawerLayout.setDrawerListener(mDrawerToggle);
  35. mPagerSlidingTabStrip = (PagerSlidingTabStrip) findViewById(R.id.tabs);
  36. mViewPager = (ViewPager) findViewById(R.id.pager);
  37. mViewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
  38. mPagerSlidingTabStrip.setViewPager(mViewPager);
  39. mPagerSlidingTabStrip.setOnPageChangeListener(new OnPageChangeListener() {
  40. @Override
  41. public void onPageSelected(int arg0) {
  42. colorChange(arg0);
  43. }
  44. @Override
  45. public void onPageScrolled(int arg0, float arg1, int arg2) {
  46. }
  47. @Override
  48. public void onPageScrollStateChanged(int arg0) {
  49. }
  50. });
  51. initTabsValue();
  52. }
  53. /**
  54. * mPagerSlidingTabStrip默认值配置
  55. *
  56. */
  57. private void initTabsValue() {
  58. // 底部游标颜色
  59. mPagerSlidingTabStrip.setIndicatorColor(Color.BLUE);
  60. // tab的分割线颜色
  61. mPagerSlidingTabStrip.setDividerColor(Color.TRANSPARENT);
  62. // tab背景
  63. mPagerSlidingTabStrip.setBackgroundColor(Color.parseColor("#4876FF"));
  64. // tab底线高度
  65. mPagerSlidingTabStrip.setUnderlineHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  66. 1, getResources().getDisplayMetrics()));
  67. // 游标高度
  68. mPagerSlidingTabStrip.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
  69. 5, getResources().getDisplayMetrics()));
  70. // 选中的文字颜色
  71. mPagerSlidingTabStrip.setSelectedTextColor(Color.WHITE);
  72. // 正常文字颜色
  73. mPagerSlidingTabStrip.setTextColor(Color.BLACK);
  74. }

这些都是一些基本设置,然后Palette在哪里开始工作呢,就是在tab切换时了。在onPagerSelect方法里即上面代码的45行。他是这么干的:

[java] view plaincopy
  1. /**
  2. * 界面颜色的更改
  3. */
  4. @SuppressLint("NewApi")
  5. private void colorChange(int position) {
  6. // 用来提取颜色的Bitmap
  7. Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
  8. SuperAwesomeCardFragment.getBackgroundBitmapPosition(position));
  9. // Palette的部分
  10. Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
  11. /**
  12. * 提取完之后的回调方法
  13. */
  14. @Override
  15. public void onGenerated(Palette palette) {
  16. Palette.Swatch vibrant = palette.getVibrantSwatch();
  17. /* 界面颜色UI统一性处理,看起来更Material一些 */
  18. mPagerSlidingTabStrip.setBackgroundColor(vibrant.getRgb());
  19. mPagerSlidingTabStrip.setTextColor(vibrant.getTitleTextColor());
  20. // 其中状态栏、游标、底部导航栏的颜色需要加深一下,也可以不加,具体情况在代码之后说明
  21. mPagerSlidingTabStrip.setIndicatorColor(colorBurn(vibrant.getRgb()));
  22. mToolbar.setBackgroundColor(vibrant.getRgb());
  23. if (android.os.Build.VERSION.SDK_INT >= 21) {
  24. Window window = getWindow();
  25. // 很明显,这两货是新API才有的。
  26. window.setStatusBarColor(colorBurn(vibrant.getRgb()));
  27. window.setNavigationBarColor(colorBurn(vibrant.getRgb()));
  28. }
  29. }
  30. });
  31. }
  32. /**
  33. * 颜色加深处理
  34. *
  35. * @param RGBValues
  36. *            RGB的值,由alpha(透明度)、red(红)、green(绿)、blue(蓝)构成,
  37. *            Android中我们一般使用它的16进制,
  38. *            例如:"#FFAABBCC",最左边到最右每两个字母就是代表alpha(透明度)、
  39. *            red(红)、green(绿)、blue(蓝)。每种颜色值占一个字节(8位),值域0~255
  40. *            所以下面使用移位的方法可以得到每种颜色的值,然后每种颜色值减小一下,在合成RGB颜色,颜色就会看起来深一些了
  41. * @return
  42. */
  43. private int colorBurn(int RGBValues) {
  44. int alpha = RGBValues >> 24;
  45. int red = RGBValues >> 16 & 0xFF;
  46. int green = RGBValues >> 8 & 0xFF;
  47. int blue = RGBValues & 0xFF;
  48. red = (int) Math.floor(red * (1 - 0.1));
  49. green = (int) Math.floor(green * (1 - 0.1));
  50. blue = (int) Math.floor(blue * (1 - 0.1));
  51. return Color.rgb(red, green, blue);
  52. }
[java] view plaincopy
  1. /**
  2. * 界面颜色的更改
  3. */
  4. @SuppressLint("NewApi")
  5. private void colorChange(int position) {
  6. // 用来提取颜色的Bitmap
  7. Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
  8. SuperAwesomeCardFragment.getBackgroundBitmapPosition(position));
  9. // Palette的部分
  10. Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
  11. /**
  12. * 提取完之后的回调方法
  13. */
  14. @Override
  15. public void onGenerated(Palette palette) {
  16. Palette.Swatch vibrant = palette.getVibrantSwatch();
  17. /* 界面颜色UI统一性处理,看起来更Material一些 */
  18. mPagerSlidingTabStrip.setBackgroundColor(vibrant.getRgb());
  19. mPagerSlidingTabStrip.setTextColor(vibrant.getTitleTextColor());
  20. // 其中状态栏、游标、底部导航栏的颜色需要加深一下,也可以不加,具体情况在代码之后说明
  21. mPagerSlidingTabStrip.setIndicatorColor(colorBurn(vibrant.getRgb()));
  22. mToolbar.setBackgroundColor(vibrant.getRgb());
  23. if (android.os.Build.VERSION.SDK_INT >= 21) {
  24. Window window = getWindow();
  25. // 很明显,这两货是新API才有的。
  26. window.setStatusBarColor(colorBurn(vibrant.getRgb()));
  27. window.setNavigationBarColor(colorBurn(vibrant.getRgb()));
  28. }
  29. }
  30. });
  31. }
  32. /**
  33. * 颜色加深处理
  34. *
  35. * @param RGBValues
  36. *            RGB的值,由alpha(透明度)、red(红)、green(绿)、blue(蓝)构成,
  37. *            Android中我们一般使用它的16进制,
  38. *            例如:"#FFAABBCC",最左边到最右每两个字母就是代表alpha(透明度)、
  39. *            red(红)、green(绿)、blue(蓝)。每种颜色值占一个字节(8位),值域0~255
  40. *            所以下面使用移位的方法可以得到每种颜色的值,然后每种颜色值减小一下,在合成RGB颜色,颜色就会看起来深一些了
  41. * @return
  42. */
  43. private int colorBurn(int RGBValues) {
  44. int alpha = RGBValues >> 24;
  45. int red = RGBValues >> 16 & 0xFF;
  46. int green = RGBValues >> 8 & 0xFF;
  47. int blue = RGBValues & 0xFF;
  48. red = (int) Math.floor(red * (1 - 0.1));
  49. green = (int) Math.floor(green * (1 - 0.1));
  50. blue = (int) Math.floor(blue * (1 - 0.1));
  51. return Color.rgb(red, green, blue);
  52. }

Palette需要你自己写的东西还是比较少的,你只需在它提取完成的回调方法了获取各种提取到的颜色设置给相应的view就行了。图片的颜色比较鲜艳突出,方便直观的了解。提取到的颜色怎么很好的搭配,如果你有UI设计师的话就最好了,像我这种的话看着它顺眼就行。上面的颜色处理:像如果有把Toolbar当成了ActionBar来使用而且有一些明显的ActionBar即视感的ActionButton的话,我觉得状态栏的颜色应该比ToolBar颜色深一点比较好,看起来有一点界限分隔。在Android中RGB颜色Color加深减淡的处理:可以看到我采用的加深颜色的方法就是先得到RGB颜色的red、green、blue的值,然后把每个颜色的值减小,floor函数是向下取整的功能,如果看不懂的可以先看下RGB颜色的构成再看就会很好理解了。设置成一样时的情况更多的是没有ActionButton这些明显的东西或没有三个点的更多ActionButton时,看起来更平面一点,更浑然一体。

说了这么多,Palette呢就是一把利器,方便我们对UI界面色调的处理,所以可以说他是Material Design必不可少的一部分。

END
demo效果:

              

demo源码下载地址:http://download.csdn.net/detail/bbld_/8191251

Android Material Design之Toolbar与Palette相关推荐

  1. Android Material Design之Toolbar与Palette实践

    转载请注明出处:http://blog.csdn.net/bbld_/article/details/41439715 [Rocko's bog] 前言 我们都知道Marterial Design是G ...

  2. Android Material Design简单使用 http://www.cnblogs.com/android-blogs/p/5632103.html

    Android Material Design简单使用 吐槽 作为一个 Android developer,没有什么比拿着 UI 设计的一堆 iOS 风格的设计 来做需求更恶心的了,基本所有空间都要照 ...

  3. Android Material Design 系列之 BottomNavigationView + ViewPager + Fragment + BadgeView 开发详解

    前言 BottomNavigationView 是 Material Design 提供的一个标准底部导航栏的实现,可以轻松的实现导航栏菜单之间的切换与浏览.底部导航使用户更方便的查看和切换最高层级的 ...

  4. 视频教程-Android Material Design 新控件-Android

    Android Material Design 新控件 刘志远,北京邮电大学硕士研究生, 北京育华志远科技有限公司创始人, 育华志远教育品牌负责人,育华志远课程体系打造者. 率领团队为互联网行业培训千 ...

  5. Android Material Design按钮样式

    本文翻译自:Android Material Design Button Styles I'm confused on button styles for material design. 我对材质设 ...

  6. Android Material Design :LinearLayoutCompat添加分割线divider

     Android Material Design :LinearLayoutCompat添加分割线divider Android Material Design 扩展支持包中的LinearLayo ...

  7. Android Material Design TabLayout属性app:tabMode和app: tabGravity

    Android Material Design TabLayout属性app:tabMode和app: tabGravity Android Material Design 中的TabLayout有两 ...

  8. android夜间模式揭露动画,Android Material Design系列之夜间模式

    今天我们讲讲夜间模式的实现,这篇文章的名字应该叫:<Android Material Design系列之夜间模式>.在Android 5.0 之后,实现夜间模式并非很难了,支持的5.0库提 ...

  9. Android Material Design按钮样式设计

    Today we'll dive deep into Android Buttons in Material Design and develop an application that showca ...

最新文章

  1. 英特尔cpu发布时间表_10纳米来了:英特尔十一代酷睿上市,性能提升20%,AI算力乘5倍...
  2. MySQL通过两表避免回表_mysql利用覆盖索引避免回表优化查询
  3. 华为交换机s5700学习笔记
  4. C语言--switch case语句
  5. 大牛唐健,带你领略游戏服务器与后台架构的奥妙
  6. idal 创建springboot 项目_手把手的SpringBoot教程,SpringBoot创建web项目(四)
  7. 如何在mfc主对话框中再显示子对话框_win10扩展显示器设置方法
  8. 七张图了解Kubernetes内部的架构
  9. python 二叉树递归时明明已经得到了结果,但是返回None
  10. HDOJ_1016 素数环
  11. 【转】随机函数 rand() srand() 以及seed的原理
  12. 三菱PLC Q系列大型程序伺服12轴Q01U RS232通讯CCD 应用
  13. arma找不到合适的模型_ARMA模型建模过程中存在的问题分析.htm
  14. 基于Ip的刷投票排名及刷百度推广的自动化实现
  15. Essential Qt 第二十一章 本地目录
  16. 史上最强的烧脑合集!能全都搞懂的只有天才!
  17. OPTA 7模式测试说明
  18. 公司邮箱如何申请?如何申请公司邮箱?公司邮箱号码大全
  19. 字节跳动小程序对接环信IM遇到的问题
  20. Java物流项目第五天 数据聚合服务开发(pd-aggregation)

热门文章

  1. cbow word2vec 损失_word2vec个人总结-理论篇
  2. python aiohttp_aiohttp
  3. java虚拟机调优_Java虚拟机中JVM参数调优及其有用的命令
  4. as3转换为html5,AS3和HTML5 - 使用正则表达式将字符串解析为数组
  5. java2ee和java2se_Java知识:(2)JavaSE和JavaEE
  6. oracle语句取字段前2位,oracle截取某一个字符之前或之后的值;substr();instr()
  7. mysql from unixtime_mysql 错误总结 和FROM_UNIXTIME用法
  8. (2) freemarker入门案例2
  9. UML工具:EA(Enterprise Architect)
  10. Spring Cloud Alibaba 项目工程准备