首页 > 代码库 > MaterialDesign设计(下)
MaterialDesign设计(下)
1.转场动画
Android开发过程中提供了一系列的新的过场动画,在旧版本里面,我们切换Activity大多都是使用下面这个api:
overridePendingTransition(enterAnim, exitAnim);
1.新版本的动画提供了类似的功能,动画效果更加柔顺,代码如下:
ActivityOptionsCompat optionsCompat=ActivityOptionsCompat
.makeCustomAnimation(this,R.anim.enter_anim,R.anim.exit_anim);
Intent intent=new Intent(this,SecondActivity.class);
ActivityCompat.startActivity(this,intent,optionsCompat.toBundle());
2.还可以从某个控件开始慢慢放大到完全展示新的界面,代码如下:
ActivityOptionsCompat optionsCompat=ActivityOptionsCompat
.makeScaleUpAnimation(v,v.getWidth()/2,v.getHeight()/2,0,0);
Intent intent=new Intent(this,SecondActivity.class);
ActivityCompat.startActivity(this,intent,optionsCompat.toBundle());
该创建的代码为:
makeScaleUpAnimation (View source, int startX,int startY, int width,int height)
新的activity产生一个缩放的动画,这个动画的起点是,相对于source这个View 的左上角偏移(startX,startY)位置产生一个动画,新的activity的初始宽度和高度是width 和 height,0为新界面的全屏展示。
3.当然我们也可以通过将某个图片放大至全屏,然后打开新的界面:
BitmapDrawable bmp = (BitmapDrawable) ((ImageView) v).getDrawable();
ActivityOptionsCompat optionsCompat=
ActivityOptionsCompat
.makeThumbnailScaleUpAnimation(v,bmp.getBitmap(),0,0);
Intent intent=new Intent(this,SecondActivity.class);
ActivityCompat.startActivity(this,intent,optionsCompat.toBundle());
4.Android5.0后还提供了一个场景转换动画,废话不多说,看效果:
首先要给三个按钮一个设置统一的点击事件,代码如下:
BitmapDrawable bmp = (BitmapDrawable) ((ImageView) v).getDrawable();
ActivityOptionsCompat optionsCompat=
ActivityOptionsCompat
.makeSceneTransitionAnimation(this,v,"img");
Intent intent=new Intent(this,SecondActivity.class);
intent.putExtra("img",bmp.getBitmap());
ActivityCompat.startActivity(this,intent,optionsCompat.toBundle());
这里有必要解释下makeSceneTransitionAnimation方法,该方法的第2个参数指定需要从哪个View开始慢慢放大。第三个参数就是新界面的字符串标识,也就是新的SecondActivity布局中 有这样的标签属性transitionName:
<ImageView
android:id="@+id/iv"
...
android:transitionName="img" />
在新的SecondActivity中,拿到传过来的数据进行显示:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT>=21){
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
}
setContentView(R.layout.activity_second);
Bitmap bmp=(Bitmap) getIntent().getParcelableExtra("img");
ImageView iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bmp);
}
除了可以分享2个界面中的同一元素,还可以分享多个控件元素。该操作基于makeSceneTransitionAnimation的另一个方法:
makeSceneTransitionAnimation(Activity activity,Pair<View, String>... sharedElements)
该效果是这样的:
首先给2个图片控件添加一个点击事件,并调用如下代码:
//第一个参数指定前一个场景的控件 第二个参数指定下一个场景的控件名称
Pair<View, String> a1 = Pair.create(findViewById(R.id.a1), "a1");
Pair<View, String> a4 = Pair.create(findViewById(R.id.a4), "a4");
ActivityOptionsCompat optionsCompat=
ActivityOptionsCompat
.makeSceneTransitionAnimation(this,a1,a4);
Intent intent=new Intent(this,SecondActivity.class);
ActivityCompat.startActivity(this,intent,optionsCompat.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" >
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:transitionName="a4"
android:src="http://www.mamicode.com/@drawable/a4" />
<ImageView
android:layout_width="match_parent"
android:layout_height="300dp"
android:transitionName="a1"
android:src="http://www.mamicode.com/@drawable/a1" />
</LinearLayout>
第2个界面中,为了让界面支持转场动画,代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT>=21){
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
}
setContentView(R.layout.activity_second);
}
2.场景动画
比如上面的动画,如果我们要实现该效果,就需要创建两个平移动画 写起来特别麻烦。不过我们可以使用21版本的场景动画来代替,只需要创建2个不同的场景就可以完成此事。
并且 第一次加载左边图片的时候 需要在容器中指定id.
<RelativeLayout
...
android:id="@+id/root_view" />
假如第一个布局叫activity_one 第二个布局叫activity_two 那么变换场景的代码可以这么写:
if (Build.VERSION.SDK_INT>=21){
mRootView = (ViewGroup) findViewById(R.id.root_view);
Scene scene = Scene
.getSceneForLayout(mRootView, R.layout.activity_two, this);
//ChangeBounds指定了变化过程中的动画
TransitionManager.go(scene,new ChangeBounds());
}
上面的代码靠的是TransitionManager的go方法。而如果你不添加ChangeBounds对象。动画是不会产生的。
Scene的创建也很简单 第一个参数指定需要更改布局的容器,第二个参数指定新的布局文件。
实际上TransitionManager还提供了另一个方法操作动画,下面一个小Demo展示:
其代码如下:
if (Build.VERSION.SDK_INT>=21){
mRootView = (ViewGroup) findViewById(R.id.root_view);
//指定该mRootView父容器下子控件变化的动画
TransitionManager.beginDelayedTransition(mRootView,new Slide(Gravity.TOP));
findViewById(R.id.a5).setVisibility(View.GONE);
}
通过beginDelayedTransition指定我们要监听布局的容器。只要该该容器下的子控件改变了(比如某个控件不见了/某个控件大小变化/位移改变了),就会执行Slide动画。
其可以指定的动画还有很多种 都在android.transition包下:
常见的Transition如下:
1. Slide 划入
2. Explode 爆炸
2. Fade 隐藏
2. changeBounds 位置与大小变化
3.Activity与Transition动画配置
以上就是将Transition与Activity跳转相互嵌套而成的动画,对于第一个界面来说 要实现一个所有子控件向外爆炸(Explode)的退出动画,对于第二个界面需要实现一个向右滑动(Slide)的进场动画。
既然要配置动画,当然可以使用代码来配置,也可以使用xml文件来配置。我们让第一个动画使用代码来配置,第二个动画使用xml来配置。
退出的动画
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT>=21){
//创建一个爆炸动画
Explode explode=new Explode();
explode.setDuration(1500);
//对TRANSITIONS转场动画的支持
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
//设置退出动画的效果
getWindow().setExitTransition(explode);
}
setContentView(R.layout.activity_one);
findViewById(R.id.a4).setOnClickListener(this);
findViewById(R.id.a5).setOnClickListener(this);
}
@Override
public void onClick(View v) {
Intent intent=new Intent(this,SecondActivity.class);
//5.0以后才支持
if (Build.VERSION.SDK_INT>=21){
startActivity(intent,
ActivityOptionsCompat.makeSceneTransitionAnimation(this).toBundle());
}else{
startActivity(intent);
}
}
注意上面的代码需要使用ActivityOptionsCompat.makeSceneTransitionAnimation(this)来实现转场动画,后面的参数可以不传递,因为我们不用分享转场的元素 动画在onCreate()中已经指定了.
进场动画
接下来在新的界面中,使用xml来配置从右向左滑动的进场动画。transition动画的xml配置需要在res 下创建一个transition文件夹。并在内部创建一个文件。该文件我命名为enter_anim.xml:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000" >
<fade android:interpolator="@android:interpolator/accelerate_decelerate"/>
<slide android:slideEdge="right" />
</transitionSet>
transitionSet标签类似补间动画的set标签。内部的标签大概有fade渐变标签,slide滑动标签,changebounds标签,explode标签等。至于其标签的属性很可能工具没提示哈。这里我以slide抛砖引玉。直接找到官网查找Slide,每个类大概都有提示:
其代码引用如下:
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT>=21){
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
Transition transition = TransitionInflater.from(this)
.inflateTransition(R.transition.enter_anim);
getWindow().setEnterTransition(transition);
}
setContentView(R.layout.activity_second);
}
}
4.波纹动画
首先我们可以在布局文件中创建一个播放动画的容器和一个按钮。
接着当点击按钮的时候执行如下代码:
if (Build.VERSION.SDK_INT>=21){
//View view 对哪个控件实现波纹动画
//int centerX, int centerY 启动动画的起始坐标 相对于上面的view
//float startRadius, float endRadius 开始&结束的半径
Animator animator = ViewAnimationUtils
.createCircularReveal(mContainer, 0, 0, 0, 800);
animator.setDuration(1500);
//默认动画如果没设置背景 是看不出效果的
mContainer.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_bright));
animator.start();
}
:) 本文由小码哥教育Android学院提供,谢绝转载
MaterialDesign设计(下)