zl程序教程

您现在的位置是:首页 >  移动开发

当前栏目

Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验

Android笔记UI 详解 特性 Design Material 新体验
2023-09-14 08:59:39 时间
 !-- inherit from the material theme-- 

 style name="AppTheme" parent="android:Theme.Material" 

 !-- Main theme color-- 

 !-- your app branding color for the app bar-- 

 item name="colorPrimary" #BEBEBE /item 

 !-- derker variant for thr status bar and contextual app bars-- 

 item name="colorPrimaryDark" #FF5AEBFF /item 

 !--theme ui controls like checkBoxs and text fields-- 

 item name="colorAccent" #FFFF4130 /item 

 /style 

import android.support.v7.app.AppCompatActivity; import android.support.v7.graphics.Palette; import android.view.Window; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { private ImageView iv_palette; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setPalette(); * Palette获取颜色 private void setPalette() { Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher); //创建Palette对象 Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() { @Override public void onGenerated(Palette palette) { //通过Palette来获取对应的色调 Palette.Swatch vibrant = palette.getDarkVibrantSwatch(); //将颜色设置给相应的组件 getSupportActionBar().setBackgroundDrawable(new ColorDrawable(vibrant.getRgb())); Window window = getWindow(); window.setStatusBarColor(vibrant.getRgb());

Material Design的一个很重要的特点就是拟物扁平化,如果说IOS的扁平化设计太过于超前,让很多人来不及从拟物转变成扁平,那么Material Design则是把IOS往回拉了一点,通过展现生活中的材料效果,恰当的使用阴影和光线,配合完美的动画效果,模拟出一个动感十足又美丽大胆的视觉效果


以往的Android View通常有两个属性——X和Y,而在Android5.X中,Google为其增加了一个新的属性——Z,对应垂直方向上的高度变化,看图,我们更加了解


在Android 5.X中,View的Z值由两部分组成,elevation和translationZ(他们都是Android5.X新引入的属性),elevation是静态的成员,translationZ可以在代码中使用来实现动画效果,他们的关系


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

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

 xmlns:tools="http://schemas.android.com/tools"

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:orientation="vertical" 

 TextView

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_margin="10dp"

 android:background="@mipmap/ic_launcher" / 

 TextView

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_margin="10dp"

 android:background="@mipmap/ic_launcher"

 android:elevation="2dp" / 

 TextView

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_margin="10dp"

 android:background="@mipmap/ic_launcher"

 android:elevation="10dp" / 


Android5.X在对图像的操作有了更多的功能,下面来看看Android5.X的两个对操作图像的新功能——Tinting(着色) 和 Clipping(裁剪)


Tinting的使用非常的简单,只要在XML中配置好tint和tintMode就可以了,对于配置组合效果,只需要大家实际操作一下,就能非常清晰的理解处理效果,在下面的代码中,设置了几种不同的tint和tintMode效果,XML代码如下


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

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

 xmlns:tools="http://schemas.android.com/tools"

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:orientation="vertical" 

 ImageView

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_gravity="center"

 android:elevation="5dp"

 android:src="@mipmap/ic_launcher" / 

 ImageView

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_gravity="center"

 android:elevation="5dp"

 android:src="@mipmap/ic_launcher"

 android:tint="@android:color/holo_blue_bright" / 

 ImageView

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_gravity="center"

 android:elevation="5dp"

 android:src="@mipmap/ic_launcher"

 android:tint="@android:color/holo_blue_bright"

 android:tintMode="add" / 


Tint通过修改图像的Alpha遮罩来修改图像的颜色,从而达到重新着色的目的,这一功能在一些图片处理的APP使用起来还是十分的方便的


Clipping可以让我们改变一个视图的外形,要使用Clipping,首先需要使用ViewOutlineProvider来修改outline作用给视图

下面这个例子,将一个正方形的textview通过Clipping裁剪成一个圆形的正方形和一个圆,XML代码如下


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

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

 xmlns:tools="http://schemas.android.com/tools"

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:gravity="center"

 android:orientation="vertical" 

 TextView

 android:id="@+id/tv_rect"

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_marginTop="20dp"

 android:elevation="1dp"

 android:gravity="center" / 

 TextView

 android:id="@+id/tv_circle"

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:layout_marginTop="20dp"

 android:elevation="1dp"

 android:gravity="center" / 


//修改outline为特定形状 outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 30); //获取Outline ViewOutlineProvider vlp2 = new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { //修改outline为特定形状 outline.setOval(0, 0, view.getWidth(), view.getHeight()); //重新设置形状 v1.setOutlineProvider(vlp1); v2.setOutlineProvider(vlp2); }

在Android5.X中将使用了很久的ListView做了升级,增加了一个使用方便,效率更高的控件——RecyclerView,RecyclerView是support-v7中的一个新的组件,是一个强大的滑动控件,ViewHolder的封装实现,用户只要实现自己的viewholder就可以了,该组件会自动帮你回收服用的每一个item

要使用RecyclerView,首先需要在项目中引用依赖


在布局中使用RecyclerView与使用ListView基本类似,同样需要一个类似List itemd的布局,在Material Design中,通常与CardView配合使用,后面我们再讲CardView的使用

使用RecyclerView的重点和使用和ListView一样,需要使用一个合适的数据适配器来加载数据,RecyclerView中需要重写的很多方法都似曾相识,不过RecyclerView更加先进的是,它已经封装好了ViewHolder,只要实现功能就可以,,先看Adapter


public class RecyclerAdapter extends RecyclerView.Adapter RecyclerAdapter.ViewHolder { private List String mData; public RecyclerAdapter(List String mData) { this.mData = mData; public AdapterView.OnItemClickListener itemClickListener; public void setOnItemClickListener(AdapterView.OnItemClickListener itemClickListener) { this.itemClickListener = itemClickListener; public interface OnItemClickListener { void onItemClic(View view, int position); @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //将布局转化为View并传递给RecyclerView封装好的ViewHolder View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_item, parent, false); return new ViewHolder(v); @Override public void onBindViewHolder(ViewHolder holder, int position) { //建立起ViewHolder中视图和数据的关联 holder.textView.setText(mData.get(position) + position); @Override public int getItemCount() { return mData.size(); public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private TextView textView; public ViewHolder(View itemView) { super(itemView); textView = (TextView) itemView; textView.setOnClickListener(this); //通过接口回调来实现RecyclerView的点击事件 @Override public void onClick(View v) { if (itemClickListener != null) { itemClickListener.onItemClick(null, v, getPosition(), R.id.tv_item);

上面就是一个非常简单却典型的RecyclerView,通过onCreateViewHolder将List item的布局转换成View,并传递给RecyclerView封装好的ViewHolder,就可以将数据和视图关联起来了,但是有一点要注意的是,Android并没有给RecyclerView增进点击事件,所以我们需要自己写接口回调,代码如图


public void setOnItemClickListener(AdapterView.OnItemClickListener itemClickListener) { this.itemClickListener = itemClickListener; public interface OnItemClickListener { void onItemClic(View view, int position); @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { //将布局转化为View并传递给RecyclerView封装好的ViewHolder View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_item, parent, false); return new ViewHolder(v);

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

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

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:background="#bebebe"

 android:textSize="40sp"

 android:layout_margin="3dp"

 android:gravity="center"

 android:id="@+id/tv_item"

 android:orientation="vertical" 

 /TextView 

当然,仅仅是性能也是不够的,让开发者能够更加方便的使用才是非常重要的,Google在RecyclerView中定义了LayoutManager来帮助开发者更加方便的创建不同但的布局,下面的例子就演示如何创建水平和垂直布局,当然,你也可以通过自定义LayoutManager来创建自己的布局,核心代码如下:


 mRcList.setLayoutManager(new LinearLayoutManager(this));

 mRcList.setLayoutManager(new GridLayoutManager(this));

import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.view.View; import android.widget.AdapterView; import android.widget.Spinner; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity { private RecyclerView mRcList; private RecyclerAdapter mAdapter; private RecyclerView.LayoutManager mLayoutManager; private Spinner mSpinner; private List String mData = new ArrayList String @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mRcList = (RecyclerView) findViewById(R.id.mRcList); mLayoutManager = new LinearLayoutManager(this); mRcList.setLayoutManager(mLayoutManager); mRcList.setHasFixedSize(true); //设置显示动画 mRcList.setItemAnimator(new DefaultItemAnimator()); mSpinner = (Spinner) findViewById(R.id.spinner); mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView ? parent, View view, int position, long id) { if(position == 0){ //设置为线性布局 mRcList.setLayoutManager(new LinearLayoutManager(MainActivity.this)); }else if(position == 1){ //设置为表格布局 mRcList.setLayoutManager(new GridLayoutManager(MainActivity.this,3)); }else if(position == 2 ){ @Override public void onNothingSelected(AdapterView ? parent) { //增加测试数据 mData.add("Android Test1"); mData.add("Android Test2"); mData.add("Android Test3"); mAdapter = new RecyclerAdapter(mData); mRcList.setAdapter(mAdapter); mAdapter.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(final AdapterView ? parent, View view, int position, long id) { //设置点击动画 parent.animate().translationZ(15f).setDuration(300).setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); parent.animate().translationZ(1f).setDuration(500).start(); }).start(); public void addRecycler(View view){ int position = mData.size(); if(position 0){ mAdapter.notifyDataSetChanged(); public void delRecycler(View view){ int position = mData.size(); if(position 0){ mData.remove(position-1); mAdapter.notifyDataSetChanged();

CardView曾经开始流行在Google+,后来越来越多的APP也引入了Card这样的布局方式,说到底,CardView也是一个容器布局,只是他提供了一种卡片的形式,Google所幸提供了一个CardView控件,方便大家使用这种布局,开发者可以设置大小和视图高度,圆角的角度等,在此之前,我们要添加依赖


 android.support.v7.widget.CardView xmlns:app="http://schemas.android.com/apk/res-auto"

 android:id="@+id/cardview"

 android:layout_width="match_parent"

 android:layout_height="80dp"

 android:layout_margin="8dp"

 app:cardBackgroundColor="@color/colorAccent"

 app:cardCornerRadius="8dp" 

 TextView

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"

 android:layout_gravity="center"

 android:text="TextView in CardView"

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

 android:textSize="26sp" / 

 /android.support.v7.widget.CardView 


曾经的Android在activity进行跳转的时候,只是很生硬的切换,即使通过 overridePendingTransition( int inId, int outId)这个方法来给Activity增加一些切换动画,效果也只是差强人意,而在Android5.X中,Google对动画效果进行了更深一步的诠释,为Activity的转场效果设计了更加丰富的动画效果

Android5.X提供了三种Transition类型


进入:一个进入的过渡动画决定Activity中的所有视图怎么进入屏幕 退出:一个退出的过渡动画决定Activity中的所有视图怎么退出屏幕 共享元素:一个共享元素过渡动画决定两个Activity之间的过渡,怎么共享他们的视图
slide(滑动)——从屏幕边缘进或出,移动视图 fade(淡出) 一一通过改变屏幕上视图的不透明度达到添加或者移除视图
changeTransfrom——改变目标视图的缩放比例和旋转角度 changeImageTransfrom——改变目标图片的大小和缩放比例

首先来看看普通的三种Activity过渡动画, 要使用这些动画非常简单,例如从ActivityA转到ActivityB,只需要在ActivityA中将基本的startActivity(intent)方法改为如下代码即可


startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle());

getWindow().setEnterTransition(new Explode());

getWindow().setEnterTransition(new Slide());

getWindow().setEnterTransition(new Fade());

要想在程序中使用共享元素的动画效果也很简单,首先需要在他的activity1布局中设置共享元素,增加元素代码


同时在activity2中,也增加一个相应的共享元素属性,如果只要一个共享元素,那么在activity1中可以这样写


startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,view,"share").toBundle());

使用的参数就是前面普通动画的基础上增加了共享的的view和前面取的名字,如果由多个共享元素,那么我们可以通过


startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(view,"share"),Pair.create(fab,"fab")).toBundle());

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

 android:orientation="vertical" 

 Button

 android:layout_width="match_parent"

 android:layout_height="100dp"

 android:onClick="explode"

 android:text="explode" / 

 Button

 android:layout_width="match_parent"

 android:layout_height="100dp"

 android:onClick="slide"

 android:text="slide" / 

 Button

 android:layout_width="match_parent"

 android:layout_height="100dp"

 android:onClick="fade"

 android:text="fade" / 

 Button

 android:layout_width="match_parent"

 android:layout_height="100dp"

 android:onClick="share"

 android:text="share"

 android:transitionName="share" / 

 Button

 android:id="@+id/fab_button"

 android:layout_width="56dp"

 android:layout_height="56dp"

 android:background="@mipmap/ic_launcher"

 android:elevation="5dp"

 android:onClick="explode"

 android:transitionName="fab" / 

 /LinearLayout 

import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Pair; import android.view.View; * BActivity * Created by lgl on 2016/5/1. public class BActivity extends AppCompatActivity { private Intent intent; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_b);
intent.putExtra("flag", 0); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle()); //设置不同的动画效果 public void slide(View view) { intent = new Intent(this, CActivity.class); intent.putExtra("flag", 1); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle()); //设置不同的动画效果 public void fade(View view) { intent = new Intent(this, CActivity.class); intent.putExtra("flag", 2); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle()); //设置不同的动画效果 public void share(View view) { View fab = findViewById(R.id.fab_button); intent = new Intent(this, CActivity.class); intent.putExtra("flag", 3); //创建单个共享元素 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, view, "share").toBundle()); //创建多个共享单元 startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(view, "share"), Pair.create(fab, "fab")).toBundle());
 ?xml version="1.0" encoding="utf-8"? 

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

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:paddingBottom="15dp" 

 View

 android:id="@+id/holder_view"

 android:layout_width="match_parent"

 android:layout_height="300dp"

 android:background="?android:colorPrimary"

 android:transitionName="share" / 

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

 android:id="@+id/fab_button"

 android:layout_width="56dp"

 android:layout_height="56dp"

 android:layout_alignParentEnd="true"

 android:layout_below="@id/holder_view"

 android:layout_marginRight="15dp"

 android:layout_marginTop="-26dp"

 android:background="@mipmap/ic_launcher"

 android:elevation="5dp"

 android:transitionName="fab" / 

 RelativeLayout

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:layout_below="@id/holder_view"

 android:paddingTop="10dp" 

 Button

 android:id="@+id/button1"

 android:layout_width="match_parent"

 android:layout_height="60dp"

 android:layout_alignParentStart="true"

 android:layout_marginTop="10dp" / 

 Button

 android:id="@+id/button"

 android:layout_width="match_parent"

 android:layout_height="60dp"

 android:layout_below="@id/button1"

 android:layout_marginTop="10dp" / 

 /RelativeLayout 

 /RelativeLayout 

import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.transition.Explode; import android.transition.Fade; import android.transition.Slide; import android.view.Window; * CActivity * Created by LGL on 2016/5/2. public class CActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); int flag = getIntent().getExtras().getInt("flag"); switch (flag) { case 0: getWindow().setEnterTransition(new Explode()); break; case 1: getWindow().setEnterTransition(new Slide()); break; case 2: getWindow().setEnterTransition(new Fade()); getWindow().setExitTransition(new Fade()); break; setContentView(R.layout.activity_c);

动画已经成了UI设计中一个非常重要的一个组成部分,在Android5.X的Material Design中,更是使用了大量的动画效果,同时Google官方文档也有详细的说明


在Android5.X中,Material Design大量的使用了Ripple动画,即点就博文效果,可以通过如下代码设置波纹的背景


//波纹无边界 android:background="?android:attr/selectableItemBackgroundBorderless"

波纹有边界是指波纹被限制在控件的边界中,而波纹超出边界,则是不会受到控件的限制,以圆形发散出去,我们做一个演示

XML


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

 android:background="@android:color/holo_blue_light"

 android:gravity="center"

 android:orientation="vertical" 

 Button

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:background="?android:attr/selectableItemBackground"

 android:text="有界波纹"

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


android:layout_height="100dp" android:background="?android:attr/selectableItemBackgroundBorderless" android:text="无界波纹" android:textColor="@android:color/white" / /LinearLayout

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

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

 android:color="@android:color/holo_blue_dark" 

 item 

 shape android:shape="oval" 

 solid android:color="@color/colorPrimary" / 

 /shape 

 /item 

 /ripple 

这个动画效果是在Google I/O 大会上演示了好多次的,具体变现为一个View以圆形的形式展开,揭示出来,通过ViewAnimationUtils.createCircularReveal()来创建动画,代码如下:


public static Animator createCircularReveal(View view, int centerX, int centerY, float startRadius, float endRadius) {

 return new RevealAnimator(view,centerX,centerY,startRadius,endRadius);

 }

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

 android:orientation="vertical"

 android:gravity="center" 

 ImageView

 android:id="@+id/oval"

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:background="@mipmap/ic_launcher" / 

 ImageView

 android:id="@+id/rect"

 android:layout_width="100dp"

 android:layout_height="100dp"

 android:background="@mipmap/ic_launcher" / 

 /LinearLayout 

import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.ViewAnimationUtils; import android.view.animation.AccelerateDecelerateInterpolator; import android.view.animation.AccelerateInterpolator; * Circular Reveal * Created by LGL on 2016/5/2. public class CirActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cir); final View oval = findViewById(R.id.oval); oval.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Animator animator = ViewAnimationUtils.createCircularReveal(oval, oval.getWidth() / 2, oval.getHeight() / 2, oval.getWidth(), 0); animator.setInterpolator(new AccelerateDecelerateInterpolator()); animator.setDuration(2000); animator.start();
final View rect = findViewById(R.id.rect); rect.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Animator animator = ViewAnimationUtils.createCircularReveal(rect, 0, 0, 0, (float) Math.hypot(rect.getWidth(), rect.getHeight())); animator.setInterpolator(new AccelerateInterpolator()); animator.setDuration(2000); animator.start();
StaetListAnimator

StaetListAnimator作为视图改变时的动画效果,通常会使用Seletor来进行设置,但是以前我们设置Seletor的时候,通常是修改他的背景来达到反馈的效果,但是再现在Android5.X中就不需要这样了,可以使用动画来实现,我们用小例子来具体看看怎么实现的吧


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

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

 item android:state_pressed="true" 

 set 

 objectAnimator android:duration="2000" android:property="rotationX" android:valueTo="360" android:valuyeType="floatType" / 

 /set 

 /item 

 item android:state_pressed="false" 

 set 

 objectAnimator android:duration="2000" android:property="rotationX" android:valueTo="0" android:valuyeType="floatType" / 

 /set 

 /item 

 /selector 

Toolbar和actionBar最大的区别就是Toolbar更加的自由,可控,这也是Google在逐渐使用Toolbar来取代actionBar的原因,要使用Toolbar就必须引用依赖


android:layout_height="wrap_content" android:background="@color/colorPrimaryDark"/
 mToolbar = (Toolbar) findViewById(R.id.toolbar);

 mToolbar.setLogo(R.mipmap.ic_launcher);

 mToolbar.setTitle("主标题");

 mToolbar.setSubtitle("副标题");

 setSupportActionBar(mToolbar);

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

 android:orientation="vertical" 

 android.support.v7.widget.Toolbar

 android:id="@+id/toolbar"

 android:layout_width="match_parent"

 android:layout_height="wrap_content"

 android:background="@color/colorPrimaryDark" / 

 android.support.v4.widget.DrawerLayout

 android:id="@+id/drawer"

 android:layout_width="match_parent"

 android:layout_height="match_parent" 

 !--主页内容-- 

 LinearLayout

 android:layout_width="match_parent"

 android:layout_height="match_parent"

 android:background="@android:color/holo_blue_bright"

 android:orientation="vertical" 

 Button

 android:layout_width="100dp"

 android:layout_height="match_parent"

 android:text="内容界面" / 

 /LinearLayout 


 mToolbar = (Toolbar) findViewById(R.id.toolbar);

 mToolbar.setLogo(R.mipmap.ic_launcher);

 mToolbar.setTitle("主标题");

 mToolbar.setSubtitle("副标题");

 setSupportActionBar(mToolbar);

 getSupportActionBar().setDisplayHomeAsUpEnabled(true);

 mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);

 mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout,mToolbar,0,0);

 mDrawerToggle.syncState();

 mDrawerLayout.setDrawerListener(mDrawerToggle);

Notification作为一个时间触发性的交互提示接口,让我们获得消息的时候,在状态栏,锁屏界面显示相应的消息

Google在Android5.X中,又进一步的改进了通知栏,优化了Notification,在5.X设备上一个标准的通知是这样的,长按是下图


Notification会有一个从白色到灰色的动画切换效果,最终显示发出这个通知的调用者,而在我们的锁屏界面,也可以看到


这个与AlertDialog的使用方法非常的相似,接下来,要点击Notification执行一个intent,由于这个intent的不是立即执行,而是用户触发的,所以用pendingintent来完成这个延时操作,代码如下:


Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com"));

//构造pendingdintent

PendingIntent pendingIntent = PendingIntent.getActivities(this,0,intent,0);

 builder.setSmallIcon(R.mipmap.ic_launcher);

 builder.setContentIntent(pendingIntent);

 builder.setAutoCancel(true);

 builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));

 builder.setContentText("Title");

 builder.setContentText("内容");

 builder.setSubText("text");

 //通过NotificationManager来发出

 NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

 notificationManager.notify(0,builder.build());

折叠式Notification也是一种自定义视图的Notification,常常用于显示文本,他拥有两个视图状态,我们可以用RemoteView来帮助我们创建一个Notification视图,代码如下:


 //通过RemoteViews创建自定义视图

 RemoteViews contentView = new RemoteViews(getPackageName(),R.layout.notification);

 contentView.setTextViewText(R.id.textView,"通知栏");

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

 android:gravity="center_horizontal"

 android:orientation="vertical" 

 TextView

 android:id="@+id/textView"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"

 android:gravity="center"

 android:textColor="#ff43aebe" / 

 ImageView

 android:id="@+id/imageView"

 android:layout_width="wrap_content"

 android:layout_height="wrap_content"

 android:src="@mipmap/ic_launcher" / 

 /LinearLayout 

import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.widget.RemoteViews; * Notification * Created by LGL on 2016/5/2. public class NotificationActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_notification); Notification.Builder builder = new Notification.Builder(this); Intent intents = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.baidu.com")); //构造pendingdintent PendingIntent pendingIntent = PendingIntent.getActivities(this, 0, new Intent[]{intents}, 0); builder.setSmallIcon(R.mipmap.ic_launcher); builder.setContentIntent(pendingIntent); builder.setAutoCancel(true); builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher)); //通过RemoteViews创建自定义视图 RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification); contentView.setTextViewText(R.id.textView, "通知栏");
RemoteViews expandedView = new RemoteViews(getPackageName(), R.layout.notification_expanded); notification.bigContentView = expandedView;
//通过NotificationManager来发出 NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); notificationManager.notify(0, builder.build());

悬挂式Notification是Android5.X新增加的方式,Google希望通过这个方式来给用户带来更好的体验,这种被称为Headsup的Notification方式,可以在屏幕的上方产生Notification而不打扰用户的操作

在Android Sample中,Google给我们展示了这个项目,代码如下:


Notification.Builder builder = new Notification.Builder(this).setSmallIcon(R.mipmap.ic_launcher).setPriority(Notification.PRIORITY_DEFAULT).setCategory(Notification.CATEGORY_MESSAGE).setContentTitle("Headsup Notification").setContentText("I am Headsup Notification");

 Intent push = new Intent();

 push.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

 push.setClass(this,MainActivity.class);

 PendingIntent pendingIntent = PendingIntent.getActivities(this,0, new Intent[]{push},PendingIntent.FLAG_CANCEL_CURRENT);

 builder.setContentText("Android 5.X Headsup Notification").setFullScreenIntent(pendingIntent,true);

 NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

 nm.notify(0,builder.build());


VISIBILITY_PUBLIC - 表明在任何情况下都会显示 VISIBILITY_SECRET - 表明在pin,password等安全锁和没有锁屏的情况下显示

群英传到这里,也就没有知识点可以将了,最后十三章,是两个小项目,本来不准备讲的,不过看到这个拼图还是可以讲一讲的,就准备写了,2048我很早之前就写过,这里就不重复了


阿里云EMAS-专家测试服务iOS和Android上百种机型性能、兼容及UI等测试 阿里云EMAS测试专家有着集团内部多个日活过亿规模APP经验,提供EMAS专家测试,客户只需提交测试需求,从用例设计、脚本录制、海量机型测试、整理测试结果、48小时输出专家测试报告均由阿里云EMAS测试专家一站式服务完成。覆盖功能测试、深度兼容测试、性能测试、UI适配测试以及隐私合规检测等,帮助用户以更低成本获得高质量的全面测试能力,可用于APP正式发版前验收,规避手机APP上线前或发版过程中各类隐患。