Android群英传笔记——第十二章:Android5.X 新特性详解,Material Design UI的新体验
!-- 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="内容界面" / /LinearLayoutmToolbar = (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上线前或发版过程中各类隐患。
相关文章
- [Android]中文API(一)android包下的那些类
- [Android] 图像各种处理系列文章合集
- Android SearchView介绍及搜索提示实现
- 【黑马Android】(02)短信发送器/布局演示/android下单位/android下Junit/保存数据/android下权限/xml解析和序列化
- Android学习笔记(35):Android活动条
- 《Android源码设计模式》--状态模式--责任链模式--解释器模式--命令模式--观察者模式--备忘录模式--迭代器模式
- 基础知识奠定发展道路,最新Android学习笔记开源
- Android问题笔记 - 实战解决Studio出现Direct local .aar file dependencies are not supported when building an AAR
- Android定时任务及循环任务基础大集合
- 【Android笔记65】Android小案例之简易版的房贷计算器(附源代码)
- 【Android笔记58】Android中的UI控件之Spinner下拉框的介绍及其使用方式
- 【Android笔记56】Android之内容观察者Content Observer介绍及其使用
- 【Android笔记54】Android中几个常见的系统广播(分钟广播、网络广播、桌面和任务栏广播)
- 【Android笔记35】Android中消息传递机制之Handler和Message的用法
- 【Android笔记32】Android中数据存储技术之SQLite事务操作以及存储大文件
- 【Android笔记25】Android中的动画效果之逐帧动画
- 【Android笔记13】使用Android实现wechat微信的tab页签界面
- 【Android笔记10】Android基本的UI控件(DatePicker、DatePickerDialog、TimePicker、TimePickerDialog)
- 【Android笔记03】Android基本的UI控件(TextView、Button、EditText、ImageView、ProgressBar)
- android 11.0 12.0SystemUI下拉通知栏默认总是展开通知列表的修改
- Android 12.0 通过驱动实现禁用usb鼠标和usb键盘功能
- Android 两道经典算法题(猴子吃桃和兔子算总数)
- Android大图片之缩略图,以及对原图依照指定宽高裁剪成缩略图
- Android培训班(16)
- Android培训班(110)start_kernel函数7
- 如何将Eclipse中的项目迁移到Android Studio 中
- Android面试174道题,帮你牢固基础,一战通关
- Android 系统休眠唤醒 android-suspend
- Android高性能音频之OpenSL ES、AAudio、Oboe介绍(二)