本文章向大家介绍如何在Android中将工具栏顶出场转换为动画,主要包括如何在Android中将工具栏顶出场转换为动画的使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。
实现原理
在A页面,把需要顶出的区域截取出来
val contentView = (context as Activity).window.decorView.findViewById<View>(android.R.id.content) ?: return null var captureImage: Bitmap? = null contentView.isDrawingCacheEnabled = true captureImageFromView(contentView) contentView.destroyDrawingCache()
在B页面,把A页面截取的图片用ImageView展示在顶部,并做上移动画。同时,取消按钮做出现的动画。
ImageView的上移动画非常简单:通过不断改变topMarigin来实现上移效果
val captureImageUpAnimator = ValueAnimator.ofFloat(0f, 1f).apply { addUpdateListener { val newTopMargin = captureImageStartLocationY * (animatedValue as Float) (captureView.layoutParams as LinearLayout.LayoutParams)?.apply { topMargin = -(newTopMargin.toInt()) } } } val captureImageDownAnimator = ValueAnimator.ofFloat(1f, 0f).apply { addUpdateListener { val newTopMargin = captureImageStartLocationY * (animatedValue as Float) (captureView.layoutParams as LinearLayout.LayoutParams)?.apply { topMargin = -(newTopMargin.toInt()) } } }
取消按钮的出现动画,则是通过取消按钮左侧的框不断变小来实现的。
val rightBtnShowAnimator = ValueAnimator.ofFloat(0f, 1f).apply { addUpdateListener { val animateWidth = (it.animatedValue as Float) * RIGHT_BTN_WIDTH flexingView.layoutParams = LinearLayout.LayoutParams(containerWidth - animateWidth.toInt(), UIUtil.dp2px(30f)) } }
下图大概描述了整个动画时如何实现的:
动画实现需要注意的点
页面A保存的截图如何传到B页面?
1、截图应该放到内存还是本地?
这个截图应该放在内存中,如果截图保存到本地。那么 I/O 占用的时间肯定会导致动画实现效果不好。
2、对于截取的图片需要压缩
对于不同分辨率的手机,截取出的图片的大小是不一样的。图片太大放在内存中是不合适的,因此在截取图片后对图片的大小做了压缩。
private fun captureFromView(view: View): Bitmap? { return translateToRgb555(view.drawingCache) } //为了压缩大小,同时保证图片宽高不变,直接将图片转成 RGB_565。 private fun translateToRgb555(srcBitmap: Bitmap): Bitmap? { try { /*传入bitmap参数,返回bitmap。*/ val dataByte = ByteArrayOutputStream() srcBitmap.compress(Bitmap.CompressFormat.JPEG, 100, dataByte) val opts = BitmapFactory.Options() opts.inPreferredConfig = Bitmap.Config.RGB_565 return BitmapFactory.decodeByteArray(dataByte.toByteArray(), 0, dataByte.size(), opts) } catch (e: Exception) { e.printStackTrace() } catch (e: OutOfMemoryError) { e.printStackTrace() } return null }
经过上面的处理,大部分手机截图大小在0.2MB左右
3、B界面如何获取截取的图片?
放在intent中传给B
这样是有问题的,虽然android官方说intent中可以传递小于1MB的图片,但是国内各anroid厂商对framework做了不同的定制,有可能你的图片0.3MB就会出现崩溃,即TransactionTooLargeException
放在Fresco的缓存中?
尝试将图片放入Fresco缓存中,不过Fresco提供的接口十分不友好,(大概就不是给框架外使用的:
CloseableReference<V> cache(K key, CloseableReference<V> value);
放在全局静态变量中
不过需要注意的是在页面finish时,将这个变量置null,以免占用内存
覆盖系统原生转场动画
如果对于默认转场动画不做处理的话,效果就不是我们想要的,因此要取消默认的转场动画
需要把B页面的Theme的动画相关属性置null就可以了
<style name="NullAnimation" parent="@android:style/Animation.Activity"> <item name="android:activityOpenEnterAnimation">@null</item> <item name="android:activityOpenExitAnimation">@null</item> <item name="android:activityCloseEnterAnimation">@null</item> <item name="android:activityCloseExitAnimation">@null</item> </style>
不过这样后,在一些手机,比如华为,还是会有默认的转场动画,为了保险起见,在startActivity是最好这样
context.overridePendingTransition(0, 0)
页面闪烁的问题
在覆盖了系统原生动画后,大部分手机效果都还是ok的,不过在一些手机上会出现闪屏的问题,比如华为 Mate10。在网上参考一些大家的解决方法:
<item name="android:windowIsTranslucent">true</item>
即设置B页面的背景为透明的。
不过问题到这里还没有结束
windowIsTranslucent引发的崩溃问题
在设置windowIsTranslucent属性后,在Mate10进行测试,发现页面启动就崩溃:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.linkedin.android.XXXX.XXXX/com.linkedin.android.XXXX.XXXX.activity.LoginActivity}:
java.lang.IllegalStateException: Only fullscreen activities can request orientation
怎么解决呢?
前有山后有虎,脑壳子疼,最后决定取消B页面的锁屏属性,并且页面旋转时页面不做变化。
<activity android:name=".activity.BActivity" android:exported="false" android:configChanges="orientation|keyboardHidden|screenSize" android:theme="@style/AnimationTheme">
到此这篇关于如何在Android中将工具栏顶出场转换为动画的文章就介绍到这了,更多相关的内容请搜索亿速云以前的文章或继续浏览下面的相关文章希望大家以后多多支持亿速云!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。