讲讲ViewGroup的setPersistentDrawingCache方法
系列文章目录
讲讲ViewGroup的setPersistentDrawingCache方法
文章目录
- 系列文章目录
- 前言
- 一、看看Demo中给出的注释
- 二、Android官方文档给出的介绍
- 三、丢一个案例源码(此案例为官方Demo源码,根据个人修改了点效果)
- 1.3d动画类
- 2.Activity类
- 3.布局文件
- 4.Listview的载入动画
- 5.效果图
这是一篇采坑文章,灵感来源于博主某篇文章中与大佬的聊天
前言
记得在三年前,还在上一个学校,学生时代的时候,接过一个外包的Android单,里面有个需求是在一个Activity中根据用户的点击反复的执行两个动画以达到比较好的交互效果。当时在网上没有找到类似的效果,最后还是在Android官方Demo里找到的。
而本人对其案例中setPersistentDrawingCache方法的理解一直是在对其进行优化。
mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);
并且在后续的自己开发APP中,甚至是拿了软著权准备上架的那几款APP相同情景下一直使用此方法。今天和大佬在另一篇文章中聊到性能消耗,于是测试了下setPersistentDrawingCache加与不加的性能消耗,结果发现貌似不加效果还好一点。
一、看看Demo中给出的注释
// Since we are caching large views, we want to keep their cache
//由于我们缓存的是大视图,我们希望保留它们的缓存
开始想着是动画的强度不够,加大了动画的强度,结果不加setPersistentDrawingCache还是好一点,于是去Android官方文档查看了下,才明白。
二、Android官方文档给出的介绍
此方法在APl级别28中已弃用,随着APl 11中硬件加速渲染的引入,视图绘图缓存在很大程度上已经过时了。在使用硬件加速时,中间缓存层基本上是不必要的,并且由于创建和更新该层的成本,很容易导致性能的净损失。在极少数情况下,缓存层是有用的,比如alpha动画。View.setLaverTvpe (int。android.araphics.Paint)通过硬件渲染处理这个问题。对于视图层次结构或单个视图的一小部分的软件渲染快照,建议从位图或图片创建一个Canvas,并在视图上调用View. draw(android.graphics.Canvas)。然而,这些软件渲染的用法是不鼓励的,并且与硬件渲染特性(如Config)存在兼容性问题。硬件位图,实时阴影,轮廓剪辑。对于Ul反馈报告或单元测试的屏幕截图,建议使用PixelCopy APl。
三、丢一个案例源码(此案例为官方Demo源码,根据个人修改了点效果)
代码比较简单就不解释了
1.3d动画类
public class Rotate3dAnimation extends Animation {private final float mFromDegrees;private final float mToDegrees;private final float mCenterX;private final float mCenterY;private final float mDepthZ;private final boolean mReverse;private Camera mCamera;public Rotate3dAnimation(float fromDegrees, float toDegrees,float centerX, float centerY, float depthZ, boolean reverse) {mFromDegrees = fromDegrees;mToDegrees = toDegrees;mCenterX = centerX;mCenterY = centerY;mDepthZ = depthZ;mReverse = reverse;}@Overridepublic void initialize(int width, int height, int parentWidth, int parentHeight) {super.initialize(width, height, parentWidth, parentHeight);mCamera = new Camera();}@Overrideprotected void applyTransformation(float interpolatedTime, Transformation t) {final float fromDegrees = mFromDegrees;float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime);final float centerX = mCenterX;final float centerY = mCenterY;final Camera camera = mCamera;final Matrix matrix = t.getMatrix();camera.save();if (mReverse) {camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);} else {camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));}camera.rotateY(degrees);camera.getMatrix(matrix);camera.restore();matrix.preTranslate(-centerX, -centerY);matrix.postTranslate(centerX, centerY);}
}
2.Activity类
public class Transition3d extends Activity implementsAdapterView.OnItemClickListener, View.OnClickListener {private ListView mPhotosList;private ViewGroup mContainer;private ImageView mImageView;//item-nameprivate static final String[] PHOTOS_NAMES = new String[] {"百度关键词","微信公众号","微信小程序","个人网站","掘金","同id:计蒙不吃鱼"};//item-imgprivate static final int[] PHOTOS_RESOURCES = new int[] {R.drawable.aaaa,R.drawable.aaaa1,R.drawable.aaaa1,R.drawable.aaaa,R.drawable.aaaa,R.drawable.aaaa};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.animations_main_screen);mPhotosList = (ListView) findViewById(android.R.id.list);mImageView = (ImageView) findViewById(R.id.picture);mContainer = (ViewGroup) findViewById(R.id.container);// 准备列表视图final ArrayAdapter<String> adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1, PHOTOS_NAMES);mPhotosList.setAdapter(adapter);mPhotosList.setOnItemClickListener(this);// 准备图片mImageView.setClickable(true);mImageView.setFocusable(true);mImageView.setOnClickListener(this);//由于我们缓存的是大视图,我们希望在每个动画之间保持它们的缓存mContainer.setPersistentDrawingCache(ViewGroup.PERSISTENT_ANIMATION_CACHE);}/*** 在容器视图上设置一个新的3D旋转。** @param position 单击该项以显示图片,或单击-1以显示列表* @param start 旋转必须开始的起始角度* @param end •旋转的结束角度*/private void applyRotation(int position, float start, float end) {//找到容器的中心final float centerX = mContainer.getWidth() / 2.0f;final float centerY = mContainer.getHeight() / 2.0f;//使用提供的参数创建一个新的3D旋转// 动画监听器用于触发网络动画final Rotate3dAnimation rotation =new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);rotation.setDuration(500);rotation.setFillAfter(true);rotation.setInterpolator(new AccelerateInterpolator());rotation.setAnimationListener(new DisplayNextView(position));mContainer.startAnimation(rotation);}public void onItemClick(AdapterView<?> parent, View v, int position, long id) {//预加载图像然后开始动画mImageView.setImageResource(PHOTOS_RESOURCES[position]);applyRotation(position, 0, 90);}public void onClick(View v) {applyRotation(-1, 180, 90);}/**这class收听动画前半部分的结尾部分。•当容器旋转90度,因此不可见时,它会发布一个新的动作,有效地交换视图。*/private final class DisplayNextView implements Animation.AnimationListener {private final int mPosition;private DisplayNextView(int position) {mPosition = position;}public void onAnimationStart(Animation animation) {}public void onAnimationEnd(Animation animation) {mContainer.post(new SwapViews(mPosition));}public void onAnimationRepeat(Animation animation) {}}/**这个类负责交换视图并启动第二个视图动画的一半。*/private final class SwapViews implements Runnable {private final int mPosition;public SwapViews(int position) {mPosition = position;}public void run() {final float centerX = mContainer.getWidth() / 2.0f;final float centerY = mContainer.getHeight() / 2.0f;Rotate3dAnimation rotation;if (mPosition > -1) {mPhotosList.setVisibility(View.GONE);mImageView.setVisibility(View.VISIBLE);mImageView.requestFocus();rotation = new Rotate3dAnimation(90, 180, centerX, centerY, 310.0f, false);} else {mImageView.setVisibility(View.GONE);mPhotosList.setVisibility(View.VISIBLE);mPhotosList.requestFocus();rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f, false);}rotation.setDuration(500);rotation.setFillAfter(true);rotation.setInterpolator(new DecelerateInterpolator());mContainer.startAnimation(rotation);}}}
3.布局文件
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/container"android:layout_width="match_parent"android:layout_height="match_parent"><ListViewandroid:id="@android:id/list"android:persistentDrawingCache="animation|scrolling"android:layout_width="match_parent"android:layout_height="match_parent"android:layoutAnimation="@anim/layout_bottom_to_top_slide" /><ImageViewandroid:id="@+id/picture"android:scaleType="fitCenter"android:layout_width="match_parent"android:layout_height="match_parent"android:visibility="gone" />FrameLayout>
4.Listview的载入动画
- layout_bottom_to_top_slide.xml
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"android:delay="30%"android:animationOrder="reverse"android:animation="@anim/slide_right" />
- slide_right.xml
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"><translate android:fromXDelta="-100%p" android:toXDelta="0"android:duration="@android:integer/config_shortAnimTime" />
set>
5.效果图

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
