Android动画学习(七)之转场动画
Android动画学习(七)之转场动画
概述
Android 中的转场动画用于处理视图怎么进入和退出屏幕。
Android5.0之前的转场动画
概述:
在Android 5.0以前实现转场动画是通过补间动画来实现。通常的Activity跳转是从界面下方进入的,传统的转场动画可设置从左边或右边进入。Activity中调用overridePendingTransition(int enterAnim, int exitAnim)方法,来设置界面切换。enterAnim和exitAnim两个参数对应的是两个View动画。
使用:
从右边进入左边退出:
主转场java代码:
public void oldSpecial(View v) {
startActivity(new Intent(this, SpecialActivity.class));
overridePendingTransition(R.anim.slide_right_in, R.anim.slide_left_out);
}
slide_right_in.xml(enterAnim)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="100%"
android:toXDelta="0%"
android:duration="500" />
</set>
slide_left_out.xml(exitAnim)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%"
android:toXDelta="-40%"
android:duration="500" />
</set>
测试转场Java代码:
public void backToActivity(View view) {
this.finish();
overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);
}
slide_left_in.xml(enterAnim)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="-100%"
android:toXDelta="0%"
android:duration="500" />
</set>
slide_right_out.xml(exitAnim)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0%"
android:toXDelta="100%"
android:duration="500" />
</set>
只要修改上述进入的overridePendingTransition中进入与退出方向,可以实现左边进入左边退出、右边进入右边退出、从左边进入右边退出等效果
测试效果:
Android5.0之后的转场动画
Android 5.0之后,谷歌引入了 Activity Transition 来实现交互更加友好的转场动画效果。传统的转场动画只能作用于整个页面,不能对页面中的单个元素做控制,而5.0新转场动画可以控制页面中的每个元素。
Tansition的类型共有三种:
进入 —— 决定Activity中的所有视图怎么进入屏幕
退出 —— 决定Activity中的所有视图怎么退出屏幕
共享元素 —— 决定两个Activity之间的过渡时怎么共享它们的视图
进入和退出包含如下动画效果:
explode(分解) —— 从屏幕中间进或出
slide(滑动) —— 从屏幕边缘进或出地
fade(淡出) —— 改变屏幕上视图的不透明度实现添加或移除视图的效果
共享元素包含如下动画效果:
changeBounds —— 改变目标视图的布局边界
changeClipBounds —— 裁剪目标视图边界
changeTransform —— 改变目标视图的缩放比例和旋转角度
changeImageTransform —— 改变目标图片的大小和缩放比例
Explode
代码效果:
下一个页面的元素从四面八方进入,最终形成完整的页面。
public void Explode(View v) {//Explode的效果是下一个页面的元素从四面八方进入,最终形成完整的页面
Intent intent = new Intent(this, SpecialTestActivity.class);
intent.putExtra("flag", 0);
/*
在跳转时就要注意一点,intent后面还要再传一个参数bundle,
固定写法ActivityOptions.makeSceneTransitionAnimation(this).toBundle(),
下一个Activity根据这个就能识别出使用5.0新转场动画
*/
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
}
Slide
代码效果:
下一个页面元素从底部依次向上运动,最终形成完整的页面
public void Slide(View v) {//Slide就是下一个页面元素从底部依次向上运动,最终形成完整的页面
Intent intent = new Intent(this, SpecialTestActivity.class);
intent.putExtra("flag", 1);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
}
Fade
代码效果:
下一个页面元素渐变出现,最终形成完整的页面
public void Fade(View v) {//Fade就是下一个页面元素渐变出现,最终形成完整的页面
Intent intent = new Intent(this, SpecialTestActivity.class);
intent.putExtra("flag", 2);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
}
Share
Share是共享元素,是比较最复杂的一种转场方式,在跳转的两个Activity之间,如果有相同的View元素,那么,两个元素就可以设置成共享状态,在跳转时,这个View就会从第一个Activity的显示状态过渡到第二个Activity的显示状态,给用户的感觉仿佛是两个Activity共享一个View。
public void Share(View v) {
// 跳转时,要为每一个共享的view设置对应的transitionName
View fab = findViewById(R.id.fab_button);
View txName = findViewById(R.id.tx_user_name);
Intent intent = new Intent(this, SpecialTestActivity.class);
intent.putExtra("flag", 3);
//创建单个共享元素
// startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this, view, "share").toBundle());
//创建多个共享单元
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(v, "share"),
Pair.create(fab, "fab"),
Pair.create(txName, "user_name"))
.toBundle());
}
可以发现,以上四种转场在切换时几乎一模一样,都是在 startActivity时加入ActivityOptions.makeSceneTransitionAnimation(this).toBundle(),主要的区别在测试的Activity。测试Activity中onCreate下通过
getWindow().setEnterTransition();
getWindow().setExitTransition();
设置视图进入退出方向。不过share与其他集中不同。只需要设置
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
测试的Activity:
public class SpecialTestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int flag = getIntent().getExtras().getInt("flag");
switch (flag) {
case 0:
getWindow().setEnterTransition(new Explode());
getWindow().setExitTransition(new Explode());
break;
case 1:
getWindow().setEnterTransition(new Slide());
getWindow().setExitTransition(new Slide());
break;
case 2:
getWindow().setEnterTransition(new Fade());
getWindow().setExitTransition(new Fade());
break;
case 3:
getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
break;
default:
break;
}
setContentView(R.layout.activity_ca);
}
public void backToActivity(View view) {
this.finish();
overridePendingTransition(R.anim.slide_left_in, R.anim.slide_right_out);
}
Explode的效果:
Slide的效果:
Fade的效果:
Share的效果:
Share的经典应用-新闻列表页跳详情页
在share类中有一个经典应用,就是新闻列表页跳详情页,通常列表页和详情页都会包含相同View元素,使用Share转场给人一种连续过渡效果,非常酷炫。
代码:
/**
* 5.0新的转场动画 Share的典型应用
*@author ZD
*created at 2017/7/14 16:19
*description:
*/
public class ShareListActivity extends AppCompatActivity implements RVAdapter.RVClickListener {
RecyclerView rv;
List<RVBean> beans;
RVAdapter rvAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_share_list);
init();
}
private void init() {
rv = (RecyclerView)findViewById(R.id.rv);
rv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
beans = new ArrayList<>();
beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));
beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));
beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));
beans.add(new RVBean("谈笑冯生", R.drawable.head_image_01, "低调奢华有内涵"));
beans.add(new RVBean("高鹏展翅", R.drawable.head_image_02, "桌游传奇小王子"));
beans.add(new RVBean("珉而好学", R.drawable.head_image_03, "套路王"));
beans.add(new RVBean("汰渍洗衣粉,加亮不加价", R.drawable.head_image_04, "What are you 说啥捏?"));
beans.add(new RVBean("尼古拉斯.赵政", R.drawable.head_image_05, "亚洲舞王不解释"));
rvAdapter = new RVAdapter(this, beans);
rv.setAdapter(rvAdapter);
rvAdapter.setListener(this);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
public void onItemClick(int position) {
RVBean bean = beans.get(position);
Intent intent = new Intent(ShareListActivity.this, ShareListDetailActivity.class);
intent.putExtra("resId", bean.getResId());
intent.putExtra("name", bean.getName());
intent.putExtra("desc", bean.getDesc());
int firstVisiblePosition = ((LinearLayoutManager)rv.getLayoutManager()).findFirstVisibleItemPosition();
View itemView = rv.getChildAt(position - firstVisiblePosition);
View headImage = itemView.findViewById(R.id.head_image);
View name = itemView.findViewById(R.id.name);
View desc = itemView.findViewById(R.id.desc);
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(headImage, "headImage"),
Pair.create(name, "name"),
Pair.create(desc, "desc"))
.toBundle());
}
代码效果:
总结
Activity转场动画非常简单,通过加入代码和动画实现设定界面切换时进入退出的方向。
写博客是为了帮助开发者学习使用技术,同时巩固自己所学技术。如果此篇博客有助于您的学习,那是我的荣幸!如果此篇博客有任何瑕疵,请多多指教!在此感谢您的学习和指教!
下一篇: 方法的定义使用,方法重载及方法的递归调用