Android Material Design NavigationView 及 Palette 颜色提取器
DrawerLayout + NavigationView
DrawerLayout布局,通常在里面添加两个子控件,程序主界面添加到NavitagionView前面。
<android.support.v4.widget.DrawerLayout 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"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="@layout/app_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
这里有两个重要的属性headerLayout和menu,分别表示header部分布局和menu菜单资源。
程序主界面布局app_main,包含AppBarLayout和content_main,以及一个FloatingActionButton。
<android.support.design.widget.CoordinatorLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
android:src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
上面的主界面布局也以随意切换成其它布局。
注意事项:
1.DrawerLayout指定openDrawer为start,NavigationView指定layout_gravity为start。
2.指定NavigationView的headerLayout属性和menu属性,分别为layout布局文件和menu文件。
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="@dimen/nav_header_height"
android:background="@drawable/side_nav_bar"
android:gravity="bottom"
android:orientation="vertical"
android:theme="@style/ThemeOverlay.AppCompat.Dark">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:src="@android:drawable/sym_def_app_icon" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/nav_header_vertical_spacing"
android:text="Android Studio"
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="android.studio@android.com" />
</LinearLayout>
menu菜单资源
调用 setNavigationItemSelectedListener() 后,在菜单项被选中的时候,你会通过OnNavigationItemSelectedListener 得到回调。在处理回调时,你会知道是哪个菜单项被点击,此时你可以处理选择事件,修改选中状态,加载新的内容,以及通过代码来关闭 drawer,或者其他任何你想执行的操作。
<menu xmlns:android="http://schemas.android.com/apk/res/android">
 <group android:checkableBehavior="single">
<item
android:id="@+id/nav_camera"
android:icon="@drawable/ic_menu_camera"
android:title="Import" />
<item
android:id="@+id/nav_gallery"
android:icon="@drawable/ic_menu_gallery"
android:title="Gallery" />
<item
android:id="@+id/nav_slideshow"
android:icon="@drawable/ic_menu_slideshow"
android:title="Slideshow" />
<item
android:id="@+id/nav_manage"
android:icon="@drawable/ic_menu_manage"
android:title="Tools" />
</group>
<item android:title="Communicate">
<menu>
<item
android:id="@+id/nav_share"
android:icon="@drawable/ic_menu_share"
android:title="Share" />
<item
android:id="@+id/nav_send"
android:icon="@drawable/ic_menu_send"
android:title="Send" />
</menu>
</item>
</menu>
下面是涉及到的styles文件
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>
Activity
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();
        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }
    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        int id = item.getItemId();
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
}
Toolbar设置
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setTitle("Rocko");
// 标题的文字需在setSupportActionBar之前,不然会无效
// toolbar.setSubtitle("副标题");
setSupportActionBar(mToolbar);
/* 这些通过ActionBar来设置也是一样的,注意要在setSupportActionBar(toolbar);之后,不然就报错了 */
// getSupportActionBar().setTitle("标题");
// getSupportActionBar().setSubtitle("副标题");
// getSupportActionBar().setLogo(R.drawable.ic_launcher);
/* 菜单的监听可以在toolbar里设置,也可以像ActionBar那样,通过下面的两个回调方法来处理 */
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", Toast.LENGTH_SHORT).show();
break;
case R.id.action_share:
Toast.makeText(MainActivity.this, "action_share", Toast.LENGTH_SHORT).show();
break;
default:
Log.e("tag", item.toString());
break;
}
return true;
}
});
设置ActionBar及StatusBar背景颜色,在Api21及以上才有。
        if (null != vibrant) {
                /* 界面颜色UI统一性处理,看起来更Material一些 */
            mPagerSlidingTabStrip.setBackgroundColor(vibrant.getRgb());
            mPagerSlidingTabStrip.setTextColor(vibrant.getTitleTextColor());
            // 其中状态栏、游标、底部导航栏的颜色需要加深一下,也可以不加,具体情况在代码之后说明
            mPagerSlidingTabStrip.setIndicatorColor(colorBurn(vibrant.getRgb()));
            mToolbar.setBackgroundColor(vibrant.getRgb());
            if (android.os.Build.VERSION.SDK_INT >= 21) {
                Window window = getWindow();
                // 很明显,这两货是新API才有的。
                window.setStatusBarColor(colorBurn(vibrant.getRgb()));
                window.setNavigationBarColor(colorBurn(vibrant.getRgb()));
            }
        }
colorBurn
    private int colorBurn(int RGBValues) {
        int alpha = RGBValues >> 24;
        int red = RGBValues >> 16 & 0xFF;
        int green = RGBValues >> 8 & 0xFF;
        int blue = RGBValues & 0xFF;
        red = (int) Math.floor(red * (1 - 0.1));
        green = (int) Math.floor(green * (1 - 0.1));
        blue = (int) Math.floor(blue * (1 - 0.1));
        return Color.rgb(red, green, blue);
    }
Palette
根据图片来决定标题的颜色和标题栏的背景色,这样视觉上更具有冲击力和新鲜感,而不像统一色调那样呆板。
Palette是什么?它能让你从图像中提取突出的颜色。这个类能提取以下突出的颜色:
Vibrant(充满活力的)
Vibrant dark(充满活力的黑)
Vibrant light(充满活力的亮)
Muted(柔和的)
Muted dark(柔和的黑)
Muted lighr(柔和的亮)
如何使用?
要提取这些颜色,在你加载图片的后台线程中传递一个位图对象给Palette.generate()静态方法。如果不使用线程,则调用Palette.generateAsync()方法并且提供一个监听器去替代。
你可以在Palette类中使用getter方法来从检索突出的颜色,比如Palette.getVibrantColor。
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
      xx.setBackgroundColor(palette.getVibrantColor(mContext
             .getResources().getColor(R.color.black_translucent_60)));
  }
});
2.
Palette.from(bitmap).generate(new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
      xx.setBackgroundColor(palette.getVibrantColor(mContext
             .getResources().getColor(R.color.black_translucent_60)));
  }
});
Palette.generateAsync(bitmap,new Palette.PaletteAsyncListener() {
   @Override
   public void onGenerated(Palette palette) {
        Palette.Swatch vibrant =palette.getVibrantSwatch();
         if (swatch != null) {
             // If we have a vibrant color
             // update the title TextView
             titleView.setBackgroundColor(vibrant.getRgb());
             titleView.setTextColor(vibrant.getTitleTextColor());
         }
   }
});
上面的代码展示了如何从一张图片中提取颜色将textView的背景色设置成图片的主色调,然后再使用getTitleTextColor()来设置一个匹配的文字颜色。
比如如果你的TextView 有个背景图片,要想让字体颜色能够和背景图片匹配,则使用getBodyTextColor()比较合适,getTitleTextColor()其实应该和getBodyTextColor()差不多。
size的问题
你还可以使用如下方法一次性获得所有的swatch:
List<Palette.Swatch> swatches = palette.getSwatches();
在上面的代码中,你可能注意到了可以设置palette的size。size越大,花费的时间越长,而越小,可以选择的色彩也越小。最佳的选择是根据image的用途:
- 头像之类的,size最好在24-32之间;
 - 风景大图之类的 size差不多在8-16;
 - 默认是16.
 
有四种创建Palette实例的方法:
// Synchronous methods.
// --------------------------------
// These should be used when you have access to the underlying image loading thread.
// Picasso allows this through a Transformation. For other libraries, YMMV.
// Uses the default palette size (16).
Palette p = Palette.generate(bitmap);
// Allows you to specify the maximum palette size, in this case 24.
Palette p = Palette.generate(bitmap, 24);
// Asynchronous methods
// --------------------------------
// This is the quick and easy integration path. Internally uses an AsyncTask so
// this may not be optimal (since you're dipping in and out of threads)
// Uses the default palette size (16).
Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
// Here's your generated palette
}
});
// Allows you to specify the maximum palette size, in this case 24.
Palette.generateAsync(bitmap, 24, new Palette.PaletteAsyncListener() {
@Override
public void onGenerated(Palette palette) {
// Here's your generated palette
}
});
创建完一个实例之后,我们还需要得到一种采集的样本(swatch),有6中样本(swatch):
Vibrant. Palette.getVibrantSwatch()
Vibrant dark. Palette.getDarkVibrantSwatch()
Vibrant light. Palette.getLightVibrantSwatch()
Muted. Palette.getMutedSwatch()
Muted dark. Palette.getDarkMutedSwatch()
Muted light. Palette.getLightMutedSwatch()
具体选择哪一种取决于你自己,大多数情况下我们都使用Vibrant and Dark Vibrant。
使用样本(swatch)
swatch有以下方法:
getPopulation(): the amount of pixels which this swatch represents.
getRgb(): the RGB value of this color.
getHsl(): the HSL value of this color.
getBodyTextColor(): the RGB value of a text color which can be displayed on top of this color.
getTitleTextColor(): the RGB value of a text color which can be displayed on top of this color.
Android Material Design NavigationView 及 Palette 颜色提取器的更多相关文章
- Android开发学习之路-Palette颜色提取工具类使用
		
视频(要FQ):https://www.youtube.com/watch?v=5u0dtzXL3PQ Palette是一个在support-v7包中的一个颜色提取工具类,用法比较简单,而且是谷歌官方 ...
 - Android Material Design:NavigationView抽屉导航菜单
		
需要添加的包: 测试代码: package com.zzw.navigationview; import android.app.Activity; import android.os.Bundle; ...
 - Android Material Design 兼容库的使用
		
Android Material Design 兼容库的使用 mecury 前言:近来学习了Android Material Design 兼容库,为了把这个弄懂,才有了这篇博客,这里先推荐两篇博客: ...
 - MaterialEditText——Android Material Design EditText控件
		
MaterialEditText是Android Material Design EditText控件.可以定制浮动标签.主要颜色.默认的错误颜色等. 随着 Material Design 的到来, ...
 - Android Material Design控件学习(三)——使用TextInputLayout实现酷市场登录效果
		
前言 前两次,我们学习了 Android Material Design控件学习(一)--TabLayout的用法 Android Material Design控件学习(二)--Navigation ...
 - Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决
		
Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决 附录1的Android Ripple Effect水 ...
 - Android Material Design : Ripple Effect水波波纹荡漾的视觉交互设计
		
 Android Material Design : Ripple Effect水波波纹荡漾的视觉交互设计 Android Ripple Effect波纹荡漾效果,是Android Materia ...
 - Android Material Design的FloatingActionButton,Snackbar和CoordinatorLayout
		
如果是为了兼容低版本的Android系统,则需要引用Android Material Design的扩展支持库,我在之前的一篇文章张,较为详细的说明了如何导入Android Material Desi ...
 - Android Material Design之Toolbar与Palette
		
转:http://blog.csdn.net/jdsjlzx/article/details/41441083 前言 我们都知道Marterial Design是Google推出的全新UI设计规范,如 ...
 
随机推荐
- python-面向对象(一)——开篇基础
			
面向对象编程(Object Oriented Programming,OOP,面向对象程序设计) 一.创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现, ...
 - Yii学习系列:Yii视频讲义——前篇(转)
			
1.yii的网址 http://www.yiiframework.com/ yii官方网址 http://www.yiichina.com/ yii中文社区 2.bootstrap的网址 http:/ ...
 - MongoDB:The Definitive Guide CHAPTER 2 Getting Started
			
MongoDB is very powerful, but it is still easy to get started with. In this chapter we’ll introduce ...
 - 安装Office时出现windows installer服务不能更新一个或多个受保护的windows文件错误的解决方法
			
今天在Windows XP上安装Microsoft Office 2010时,总是遇到“Windows Installer服务不能更新一个或多个受保护的windows文件,安装失败,正在回滚更改”提示 ...
 - ==和equals()的用法
			
先看一段代码: public class TestEqual{ public static void main(String [ ] args){ //基本类型比较 int a = 100; int ...
 - 【转载】怎么理解Condition
			
注:本文主要介绍了Condition和ReentrantLock工具实现独占锁的部分代码原理,Condition能在线程之间协调通信主要是AbstractQueuedSynchronizer和cond ...
 - 【python自动化第五篇:python入门进阶】
			
今天内容: 模块的定义 导入方法 import的本质 导入优化 模块分类 模块介绍 一.模块定义: 用来在逻辑上组织python代码(变量,函数,逻辑,类):本质就是为了实现一个功能(就是以.py结尾 ...
 - Yii 通过composer 安装的方法
			
Yii2框架可以通过两种方式 安装 : 第一种方法: Yii2有两个模板 一个是基础模板,一个是高级模板,基础可能简单点吧.........,现在直接从 https://github.com/yi ...
 - BA Practice Lead Handbook 1 - Why Is Business Analysis Taking The World By Storm?
			
The articles in this series are focused on individual Business Analysts and their managers. https:// ...
 - Sae 上传文件到Storage
			
首先说一下几个地方: 1.上传使用ss.upload("domin域名","源地址","目标地址,也就是storage的地址");假设要上传 ...