Android 转场动画+Adapter启动Activity
2017-02-23 22:26
525 查看
Android 转场动画+Adapter启动Activity
最近有个需求就是在RecyclerView中点击一个item然后跳出新的Activity,由于最近对于Material Design的翻译,所以也想做一个转场动画更为流畅的跳转。本文在环境 Android 5.0 及以上。本文参考:
http://blog.csdn.net/wl9739/article/details/52833668
实现转场动画
在res/ 目录下创建 transition 文件夹,在该文件夹下定义界面转场动画和共享元素的动画。在 res/value/style 文件中为每个Activity指定转场动画的style, 并在 AndroidManifest.xml 文件中为每个 Activity 设置对应的 android:theme。
在 Activity 调用 startActivity() 切换动画前,使用 ActivityOptionsCompat 来创建转场动画时的共享对象。
定义转场动画
在 res/ 目录下创建了 transition 资源文件夹后,就可以在该文件夹下对每一种动画进行定义。Android 5.0(API 级别 21)支持这些进入与退出转换:
explode(分解): 从场景中心移入或移出视图
slide(滑动): 从场景边缘移入或移出视图
fade(淡入淡出): 通过调整透明度在场景中增添或移除视图
每一种动画效果,都有额外的属性。比如 slide,可以使用
android:slideEdge="top"设置滑动的方向;fade 可以使用
android:fadingMode="fade_in"设置具体是淡入还是淡出。
一般来说,一个过渡动画可以写成下面的形式:
<explode xmlns:android="http://schemas.android.com/apk/res/android"> <targets> <target android:excludeId="@android:id/statusBarBackground"/> <target android:excludeId="@android:id/navigationBarBackground"/> </targets> </explode>
<targets/>标签里面定义需要转场(或者不需要转场)的目标id,这个id可以是系统自带的,也可以是我们自己视图中的view的id,每一个id需要单独在
<target />标签中定义, android:targetId 表示目标ID需要进行过渡转换的view,而 android:excludeId 表示我们不需要该ID的view进行过渡转场。上面的那段代码的意思就是,除了状态栏和导航栏以外的所有的view,都执行 explode 动画。
而我们想要在同一个过渡状态中实现两种或多种动画效果怎么办?也简单,将根标签替换为
<transitionSet/>,然后定义每一种动画效果 。在根标签中可以使用
android:transitionOrdering注明几种动画的演示顺序,
sequential表示顺序执行,而
together表示同时执行。当然只有一个动画也可以使用该标签,这样以后要再加入动画,也很好修改,默认是同时执行所有动画。
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> <fade> <targets> <target android:targetId="@id/article_date" /> <target android:targetId="@id/article_author" /> <target android:targetId="@id/article_title" /> <target android:targetId="@id/article_author_img" /> <target android:targetId="@id/article_spec" /> </targets> </fade> <slide android:slideEdge="bottom"> <targets> <target android:targetId="@id/article_content" /> </targets> </slide> </transitionSet>
为每个 Activity 定义转场样式
这里的每一种动画,指的是在进行界面跳转过渡时,两个界面的状态。比如对于 Activity A 和 Activity B 这两个界面,可能的状态如下:界面A 跳转至 界面B:这时界面A是 exit(退出) 过渡状态,而对应的界面B是 enter(进入) 过渡状态。
界面B 返回到 界面A:这时界面A是 reenter(重新进入) 过渡状态,而对应的界面B则是 return(返回) 过渡状态。
一般来说,所有的 Activity 过渡动画都可以定义成如下的形式:
<style name="BaseAppTheme" parent="android:Theme.Material"> <!-- 开启过渡效果 --> <item name="android:windowContentTransitions">true</item> <!-- 指定界面进入/退出动画效果 --> <item name="android:windowEnterTransition">@transition/explode</item> <item name="android:windowExitTransition">@transition/explode</item> <!-- 指定共享元素进入/退出的动画效果 --> <item name="android:windowSharedElementEnterTransition"> @transition/change_image_transform</item> <item name="android:windowSharedElementExitTransition"> @transition/change_image_transform</item> </style>
上面的代码你会发现还有共享元素的动画效果,本文并没有涉及到共享元素的动画,读者可以自行查阅相关文章。
当然,你不必写全所有的属性,比如我在我的项目中定义的就是
<style name="AppTheme.Main" parent="IndexActivityTheme"> <item name="android:windowExitTransition">@transition/public_exit</item> </style>
定义了style,不要忘记要在 AndroidManifest.xml 文件中给相应的Activity 设置对应的 android:theme
<activity android:name=".Index" android:theme="@style/AppTheme.Main"> </activity>
调用 ActivityOptionsCompat
转场动画是在两个界面的跳转返回时发b03b
生的,所以,当使用intent跳转界面时,需要调用
ActivityOptionsCompat来指定动画的运行。
一般来说,调用
ActivityOptionsCompat的模板代码如下:
// 创建一个包含过渡动画信息的 ActivityOptions 对象 ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, view, getString(R.string.image_transition_name)); // 使用 Intent 跳转界面,并传递共享对象信息 Intent intent = new Intent(this, DetailActivity.class); startActivity(intent, optionsCompat.toBundle());
有时候我们需要让多个元素产生动画效果,可以使用Pair来实现:
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2"));
这里要注意的一点是,这里的view1,view2都必须是View类型的,所以你要使用例如TextView类型的view 的话,要强制转型为View,而”agreedName”就是在xml中
android:transitionName="agreedName"定义的共享元素的名称。
一切本来都是这么顺利,但是问题出现了
Adapter启动Activity
RecyclerView中的点击事件,大家都应该熟悉了,我想实现的就是点击后跳转到新的Activity中,我的做法是在Adapter的onBindViewHolder中给view增加点击的监听事件。但是问题来了,在
makeSceneTransitionAnimation和 Intent的构造函数中都是需要 Activity 参数的,而在Adapter中如何才能获取到这一参数呢?这是一个问题。
我的解决方法是在Adapter中增加一个 Context 变量,并在onCreateViewHolder方法中给变量赋值,这样我们就能获取到上下文了。
private Context mContext; @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (mContext == null) { mContext = parent.getContext(); } ... }
这样的话,通过上下文我们就能获得Activity变量了,我们只要对Context变量进行强制类型转换成我们需要的那一个Activity类型即可,比如我的RecyclerView在Index这一个Activity中,我们来增加过场动画。
holder.mCardView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { new Handler().postDelayed(new Runnable() { @Override public void run() { ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation((Index) mContext, Pair.create((View) holder.articleImage, "image_transition")); Intent intent = new Intent(mContext, ArticleIndex.class); intent.putExtra("article", article); mContext.startActivity(intent, options.toBundle()); } }, 200); } });
在Intent的构造函数中,我们也可以直接将Context传入,会自动帮我们转化成Activity类型,这样的话,就大功告成了!
相关文章推荐
- Android动画 之 在Activity启动时运行
- Android中帧动画在Activity启动时自动运行的几种方式 .
- android窗体动画:activity启动从底部向上滑动出现,关闭的时候从顶部向下滑动消失,并解决activity跳转的时候出现短暂的黑屏
- 解决Activity启动黑屏及设置android:windowIsTranslucent不兼容activity切换动画问题
- Android中帧动画在Activity启动时自动运行的几种方式
- Android Activity和Fragment的转场动画
- 解决Activity启动黑屏和设置android:windowIsTranslucent不兼容activity切换动画的问题
- 解决Activity启动黑屏及设置android:windowIsTranslucent不兼容activity切换动画问题
- android窗体动画:activity启动从底部向上滑动出现,关闭的时候从顶部向下滑动消失的动画实现
- Android中帧动画在Activity启动时自动运行的几种方式
- 解决Activity启动黑屏及设置android:windowIsTranslucent不兼容activity切换动画问题
- Android中帧动画在Activity启动时自动运行的几种方式
- [转]Android Activity和Fragment的转场动画
- Android中帧动画在Activity启动时自动运行的几种方式
- Android 编程下帧动画在 Activity 启动时自动运行的几种方式
- Android Activity和Fragment的转场动画
- android窗体动画:activity启动从底部向上滑动出现,关闭的时候从顶部向下滑动消失,并解决activity跳转的时候出现短暂的黑屏
- Android Activity 启动/退出 动画效果
- Activity启动从底部向上滑动出现,关闭的时候从顶部向下滑动消失的动画实现---Android提高篇
- 解决Activity启动黑屏及设置android:windowIsTranslucent不兼容activity切换动画问题