失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android群英传笔记——第十二章:Android5.X 新特性详解 Material Design UI的新体验...

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

时间:2021-05-03 19:13:29

相关推荐

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

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

第十一章为什么不写,因为我很早之前就已经写过了,有需要的可以去看

Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能

这一章很多,但是很有趣,也是这书的最后一章知识点了,我现在还在考虑要不要写这个拼图和2048的案例,在此之前,我们先来玩玩Android5.X的新特性吧!

Android 5.X UI设计初步Android 5.X 新增特性分析

一. Android 5.X UI设计初步

Android 5.X开始使用新的设计风格Material Design来统一整个Android系统设计风格,与之前的设计不同,这次的Material Design设计将Android带来一片全新的高度,同时Google在官网推出了新的设计指南,全面的讲解了Material Design的整个实现规范

1.材料的形态模拟

材料的形态模拟是Material Design中最核心也是改变最大的设计,Google通过模拟自然界纸墨的形态变化,光线和阴影,纸和纸之间的空间层次关系,带来一种真实的感觉

2.更加真实的动画

好的动画效果可以非常的有效的指引用户,暗示用户并给用户带来愉悦的使用体验,Android5.X中大量加入了各种新的动画效果,让整个设计风格更加自然,和谐,而各种新的转场动画,能更加有效的指引用户的视觉焦点,不至于因为复杂布局的界面重排而对整体效果产生影响,让使用者达到一个视觉连贯性

3.大色块的使用

Material Design中用了大量高饱和度,适中亮度的大色块来突出界面的主次,并一扫Android4.X系列Holo主题的沉重感,让界面更加富有时尚感和视觉冲击力

此外,还有更多的设计风格,比如悬浮按钮,聚焦大图,无框按钮,波纹效果等新特性,这里就不一一列举了,Google在其Material Design网站上也有

2.Material Design主题

我们先来看看如何使用主题,MD一共有三种默认的主题可以设置

@android:style/Theme.Material (dark version) @android:style/Theme.Material.Light (light version)@android:style/Theme.Material.Light.DarkActionBar

效果如图

同时,Android5.X提出来Color Palette的概念,让开发者可以设定系统区域的颜色,使得整个APP的颜色使得APP的颜色统一

通过如下所示的代码,可以通过自定义style的方式来创建自己的Color palette颜色主题,从而实现颜色的不同风格

<!-- 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>

看效果

3.Palette

在Android的版本发展中,UI越来越成为Google的发展中心,这次的Android5.X创新的使用了Palette来提取颜色,从而让主题能够动态适应当前页面的色调,使得整个app的颜色基本和谐统一

Android内置了几种提取颜色的种类

Vibrant(充满活力的)Vibrant dark(充满活力的黑)Vibrant light(充满活力的白)Muted(柔和的)Muted dark(柔和的黑)Muted light(柔和的白)

使用Palette的API,能够让我们从Bitmap中获取对应的色调,修改当前的主题色调,使用Palette首先需要在Android studio引用相关的依赖

compile 'com.android.support:palette-v7:21.0.+'

可以通过传递一个Bitmap对象给Palette,并调用它的Palette.generate()静态方法或者Palette.generateAsync()方法创建一个Palette,接下来,就可以使用getter方法来检索相应的色调,这些色调就是我们在上面列表所列出的色调

我们这里写一个小例子,演示如何通过加载的图片的柔和色调来改变状态栏和actionbar的色调,代码如下

package com.lgl.materialdesign;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.drawable.ColorDrawable;import android.os.Bundle;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;@Overrideprotected 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() {@Overridepublic void onGenerated(Palette palette) {//通过Palette来获取对应的色调Palette.Swatch vibrant = palette.getDarkVibrantSwatch();//将颜色设置给相应的组件getSupportActionBar().setBackgroundDrawable(new ColorDrawable(vibrant.getRgb()));Window window = getWindow();window.setStatusBarColor(vibrant.getRgb());}});}}

而且,我们可以使用不同的方法获取不同的色调颜色

palette.getVibrantSwatch();palette.getDarkMutedSwatch();palette.getLightMutedSwatch();palette.getMutedSwatch();palette.getDarkVibrantSwatch();palette.getLightVibrantSwatch();

看效果

4.视图与阴影

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

-1.阴影效果

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

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

Z = elevation + translationZ;

通过下面的代码,演示了不同视图高度所显示的效果,xml代码

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/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" /></LinearLayout>

在程序中,我们也可以使用代码改变视图高度

view.setTranslationZ(xxx);

通常也会使用属性动画来为视图高度改变的时候增加动画效果

if(flag){view.animate().translationZ(100);flag = false;}else {view.animate().translationZ(0);flag = true;}

5.Tinting 和 Clipping

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

-1.Tinting(着色)

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

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/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" /><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="multiply" /></LinearLayout>

效果如下

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

-2. Clipping(裁剪)

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

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

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/apk/res/android"xmlns:tools="/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" /></LinearLayout>

逻辑代码很简单

/*** Clipping裁剪*/private void setClipping() {final View v1 = findViewById(R.id.tv_rect);View v2 = findViewById(R.id.tv_circle);//获取OutlineViewOutlineProvider vlp1 = new ViewOutlineProvider() {@Overridepublic void getOutline(View view, Outline outline) {//修改outline为特定形状outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 30);}};//获取OutlineViewOutlineProvider vlp2 = new ViewOutlineProvider() {@Overridepublic void getOutline(View view, Outline outline) {//修改outline为特定形状outline.setOval(0, 0, view.getWidth(), view.getHeight());}};//重新设置形状v1.setOutlineProvider(vlp1);v2.setOutlineProvider(vlp2);}

我们看下效果

6.列表和卡片

-1.RecyclerView

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

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

compile 'com.android.support:recyclerview-v7:21.0.+'

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

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

package com.lgl.materialdesign;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.AdapterView;import android.widget.TextView;import java.util.List;/*** RecyclerView的适配器* Created by LGL on /4/30.*/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);}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {//将布局转化为View并传递给RecyclerView封装好的ViewHolderView v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_item, parent, false);return new ViewHolder(v);}@Overridepublic void onBindViewHolder(ViewHolder holder, int position) {//建立起ViewHolder中视图和数据的关联holder.textView.setText(mData.get(position) + position);}@Overridepublic 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的点击事件@Overridepublic 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 AdapterView.OnItemClickListener itemClickListener;public void setOnItemClickListener(AdapterView.OnItemClickListener itemClickListener) {this.itemClickListener = itemClickListener;}public interface OnItemClickListener {void onItemClic(View view, int position);}@Overridepublic ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {//将布局转化为View并传递给RecyclerView封装好的ViewHolderView v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rc_item, parent, false);return new ViewHolder(v);}

类似ListView的List item视图

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="/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));

完整代码:

package com.lgl.materialdesign;import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.os.Bundle;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>();@Overrideprotected 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() {@Overridepublic 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 ){}}@Overridepublic 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() {@Overridepublic void onItemClick(final AdapterView<?> parent, View view, int position, long id) {//设置点击动画parent.animate().translationZ(15f).setDuration(300).setListener(new AnimatorListenerAdapter() {@Overridepublic 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();}}}

运行结果

-2.CardView

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

compile 'com.android.support:cardview-v7:21.0.0+'

同时要添加命名空间

xmlns:app="/apk/res-auto"

我们举个例子

<android.support.v7.widget.CardView xmlns:app="/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"><TextViewandroid: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>

运行的效果

7.Activity过渡动画

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

Android5.X提供了三种Transition类型

进入:一个进入的过渡动画决定Activity中的所有视图怎么进入屏幕退出:一个退出的过渡动画决定Activity中的所有视图怎么退出屏幕共享元素:一个共享元素过渡动画决定两个Activity之间的过渡,怎么共享他们的视图

其中,进人和退出效果包括

explode(分解)一一从屏幕中间进或出,移动视图slide(滑动)——从屏幕边缘进或出,移动视图fade(淡出) 一一通过改变屏幕上视图的不透明度达到添加或者移除视图

共享元素包括

changeBounds——改变目标视图的布局边界changeCliBounds——裁剪目标视图边界changeTransfrom——改变目标视图的缩放比例和旋转角度changeImageTransfrom——改变目标图片的大小和缩放比例

可以发现,在Android5.X上,动画效果的种类变得更加丰富了

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

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

而在AchvityB中,只需要设置下如下所示代码

getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);

或者在样式文件中设置如下所示代码

<item name="android:windowContentTransitions">true</item>

那么接下来就可以设置进人/退出ActivityB的具体的动画效果了, 代码如下所示

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

而对于共享元素的动画效果.可以借用开发者网上的一张图

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

android:transitionName="XXX"

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

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

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

Pair.create()

来创建多个共享元素

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

下面我们通过一个具体的实例来演示一下过渡动画,我们从BActivity跳转到CActivity

BActivity的XML

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/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>

实现逻辑

package com.lgl.materialdesign;import android.app.ActivityOptions;import android.content.Intent;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.util.Pair;import android.view.View;/*** BActivity* Created by lgl on /5/1.*/public class BActivity extends AppCompatActivity {private Intent intent;@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_b);}//设置不同的动画效果public void explode(View view) {intent = new Intent(this, CActivity.class);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());}}

再看CActivity的XML

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="/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="/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>

实现逻辑就更简单了

package com.lgl.materialdesign;import android.os.Bundle;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 /5/2.*/public class CActivity extends AppCompatActivity {@Overrideprotected 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);}}

我们运行一下就可以看到自己想要的效果了

八.Material Design动画效果

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

1.Ripple效果

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

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

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

XML

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/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" /><Button android:layout_width="100dp"android:layout_height="100dp"android:background="?android:attr/selectableItemBackgroundBorderless"android:text="无界波纹"android:textColor="@android:color/white" /></LinearLayout>

运行的效果

同样的,我们可以写一个xml文件来实现Ripple效果

<?xml version="1.0" encoding="utf-8"?><ripple xmlns:android="/apk/res/android"android:color="@android:color/holo_blue_dark"><item><shape android:shape="oval"><solid android:color="@color/colorPrimary" /></shape></item></ripple>

使用方法直接设置背景就可以了,运行效果

2.Circular Reveal

这个动画效果是在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);}

RevealAnimator的使用特别简单,主要就是几个关键的坐标点

centerX 动画开始的中心点XcenterY 动画开始的中心点YstartRadius 动画开始半径endRadius 动画结束半径

我们还是通过一个实例去演示一下

XML

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/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>

逻辑代码

package com.lgl.materialdesign;import android.animation.Animator;import android.os.Bundle;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 /5/2.*/public class CirActivity extends AppCompatActivity {@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic 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();}});}}

这样我们就可以去实现了

3. View state changes Animation

在Android5.X中,系统提供了视图与状态改变来设置一个视图状态的切换

StaetListAnimator

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

在XML中定义一个StaetListAnimator

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="/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>

然后直接在布局中设置即可

<Button android:layout_width="200dp"android:layout_height="200dp"android:background="@drawable/animatorstate" />

animated-selector

animated-selector同样是一个改变动画效果的动画,

这个效果不讲,没素材

九.Toolbar

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

compile 'com.android.support:appcompat-v7:23.3.0'

同样的,我们要设置主题

Theme.AppCompat.Light.NoActionBar

然后在XML中

<android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"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);

而menu都是一样的,就不写了,这样一个title就写出来了

![这里写图片描述](https://img-/0502113126051)

我们再来具体实现以下,我们加入一个侧滑的效果,XML代码

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/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"><Buttonandroid:layout_width="100dp"android:layout_height="match_parent"android:text="内容界面" /></LinearLayout><!--侧滑菜单内容,必须制定水平重力--><LinearLayout android:id="@+id/drawer_view"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="start"android:orientation="vertical"><Buttonandroid:layout_width="100dp"android:layout_height="match_parent"android:text="菜单界面" /></LinearLayout></android.support.v4.widget.DrawerLayout></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);

运行的效果

![这里写图片描述](https://img-/0502114128620)

十.Notification

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

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

![这里写图片描述](https://img-/0502115934511)

长按会显示消息的来源

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

![这里写图片描述](https://img-/050214877)

我们分四重境界来讲解在Android5.X下使用Notification

1.基本的Notification

通过Notification.Builder创建一个Notification的builder,代码如下

Notification.Builder builder = new Notification.Builder(this);

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

Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(""));//构造pendingdintentPendingIntent pendingIntent = PendingIntent.getActivities(this,0,intent,0);

这样点击PendingIntent 之后就会触发时间了,我们也可以给他增加属性

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());

这样我们很轻松的就创建了一个通知栏

![这里写图片描述](https://img-/0502121915412)

2.折叠式Notification

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

//通过RemoteViews创建自定义视图RemoteViews contentView = new RemoteViews(getPackageName(),R.layout.notification);contentView.setTextViewText(R.id.textView,"通知栏");

其中notification的布局是这样的

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="/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>

通过如下代码,可以讲一个视图指定为Notification正常状态下的视图

notification.contentView = contentView;

另一个展开的代码

notification.bigContentView = expandedView;

奉献完整代码

package com.lgl.materialdesign;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Intent;import android.graphics.BitmapFactory;import .Uri;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.widget.RemoteViews;/*** Notification* Created by LGL on /5/2.*/public class NotificationActivity extends AppCompatActivity {@Overrideprotected 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(""));//构造pendingdintentPendingIntent 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, "通知栏");Notification notification = builder.build();//指定视图notification.contentView = contentView;RemoteViews expandedView = new RemoteViews(getPackageName(), R.layout.notification_expanded);notification.bigContentView = expandedView;//通过NotificationManager来发出NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);notificationManager.notify(0, builder.build());}}

3.悬挂式Notification

悬挂式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());

效果

![这里写图片描述](https://img-/0502131330033)

4.显示等级的Notification

最后一重境界也就是新加入的一种模式,显示登记,具体分三级

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

这一章自我感觉没啥写的,就一页,跳过吧,很少的知识点

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

笔记下载地址:/s/1c0U7k2W 密码:9v0g

Demo下载:/detail/qq_26787115/9509289

如果觉得《Android群英传笔记——第十二章:Android5.X 新特性详解 Material Design UI的新体验...》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。