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是什么?它能让你从图像中提取突出的颜色。这个类能提取以下突出的颜色:

  1. Vibrant(充满活力的)

  2. Vibrant dark(充满活力的黑)

  3. Vibrant light(充满活力的亮)

  4. Muted(柔和的)

  5. Muted dark(柔和的黑)

  6. 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 颜色提取器的更多相关文章

  1. Android开发学习之路-Palette颜色提取工具类使用

    视频(要FQ):https://www.youtube.com/watch?v=5u0dtzXL3PQ Palette是一个在support-v7包中的一个颜色提取工具类,用法比较简单,而且是谷歌官方 ...

  2. Android Material Design:NavigationView抽屉导航菜单

    需要添加的包: 测试代码: package com.zzw.navigationview; import android.app.Activity; import android.os.Bundle; ...

  3. Android Material Design 兼容库的使用

    Android Material Design 兼容库的使用 mecury 前言:近来学习了Android Material Design 兼容库,为了把这个弄懂,才有了这篇博客,这里先推荐两篇博客: ...

  4. MaterialEditText——Android Material Design EditText控件

    MaterialEditText是Android Material Design EditText控件.可以定制浮动标签.主要颜色.默认的错误颜色等. 随着 Material Design 的到来, ...

  5. Android Material Design控件学习(三)——使用TextInputLayout实现酷市场登录效果

    前言 前两次,我们学习了 Android Material Design控件学习(一)--TabLayout的用法 Android Material Design控件学习(二)--Navigation ...

  6. Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决

    Android Material Design Ripple Effect在Android5.0(SDK=21)以下Android版本崩溃问题解决 附录1的Android Ripple Effect水 ...

  7. Android Material Design : Ripple Effect水波波纹荡漾的视觉交互设计

     Android Material Design : Ripple Effect水波波纹荡漾的视觉交互设计 Android Ripple Effect波纹荡漾效果,是Android Materia ...

  8. Android Material Design的FloatingActionButton,Snackbar和CoordinatorLayout

    如果是为了兼容低版本的Android系统,则需要引用Android Material Design的扩展支持库,我在之前的一篇文章张,较为详细的说明了如何导入Android Material Desi ...

  9. Android Material Design之Toolbar与Palette

    转:http://blog.csdn.net/jdsjlzx/article/details/41441083 前言 我们都知道Marterial Design是Google推出的全新UI设计规范,如 ...

随机推荐

  1. python-面向对象(一)——开篇基础

    面向对象编程(Object Oriented Programming,OOP,面向对象程序设计) 一.创建类和对象 面向对象编程是一种编程方式,此编程方式的落地需要使用 “类” 和 “对象” 来实现, ...

  2. Yii学习系列:Yii视频讲义——前篇(转)

    1.yii的网址 http://www.yiiframework.com/ yii官方网址 http://www.yiichina.com/ yii中文社区 2.bootstrap的网址 http:/ ...

  3. 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 ...

  4. 安装Office时出现windows installer服务不能更新一个或多个受保护的windows文件错误的解决方法

    今天在Windows XP上安装Microsoft Office 2010时,总是遇到“Windows Installer服务不能更新一个或多个受保护的windows文件,安装失败,正在回滚更改”提示 ...

  5. ==和equals()的用法

    先看一段代码: public class TestEqual{ public static void main(String [ ] args){ //基本类型比较 int a = 100; int ...

  6. 【转载】怎么理解Condition

    注:本文主要介绍了Condition和ReentrantLock工具实现独占锁的部分代码原理,Condition能在线程之间协调通信主要是AbstractQueuedSynchronizer和cond ...

  7. 【python自动化第五篇:python入门进阶】

    今天内容: 模块的定义 导入方法 import的本质 导入优化 模块分类 模块介绍 一.模块定义: 用来在逻辑上组织python代码(变量,函数,逻辑,类):本质就是为了实现一个功能(就是以.py结尾 ...

  8. Yii 通过composer 安装的方法

    Yii2框架可以通过两种方式 安装 : 第一种方法: Yii2有两个模板 一个是基础模板,一个是高级模板,基础可能简单点吧.........,现在直接从   https://github.com/yi ...

  9. 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:// ...

  10. Sae 上传文件到Storage

    首先说一下几个地方: 1.上传使用ss.upload("domin域名","源地址","目标地址,也就是storage的地址");假设要上传 ...