Android开源:AndroidSkinAnimator - 皮肤切换动画
tjlq4843
8年前
<h2>1. 引子</h2> <p>动画效果是一个非常棒的用户体验,Android 加入Material Design,app赏心悦目了不少,关键还完全没有增加开发者的负担。不需要多写哪怕一行代码,用户体验已经提升了很多。</p> <p>但是在界面中动态删除一个View,或者更新View显示时,界面还是存在抖动的现象,过渡不够平滑。所以是否能有一种方法对开发者透明的高效动画实现呢?几天前看到有个同学实现了 Android-skin-support Android换肤框架,主要原理就是在执行 onCreate 之前通过 setFactory(LayoutInflater inflater, LayoutInflaterFactory factory) 方法替换系统View为自定义的View,从而自如切换View的一些属性。仔细想想,利用这种方式可以实现太多的功能了。</p> <h2>2. 思路</h2> <p>其实我们需要实现的动画主要是View在 Visible,Gone 或者内容更新的时候可以平滑切换:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/28d04ecd4afee05ade6402d216024eef.gif"></p> <p>如图中的第一个TextView在由text1更新到text1_change时,如果有动画是渐隐变化的,无动画时则比较生硬。</p> <p>我们实现Animation everywhere主要就是实现 Visible 、Gone、Update 动画,其它动画不够通用,如果需要可以手动实现。我们采用的方式也是在 setFactory(LayoutInflater inflater, LayoutInflaterFactory factory) 方法中替换系统View,这样可以保证对开发透明,不需要在布局文件中作出改动。</p> <p>自定义View主要是修改View自身的 setVisibility() 和更新内容的一些方法,如TextView 的 setText() 的方法。</p> <h2>3. 存在的问题</h2> <p>替换原生View是一个比较有风险的事情,因此应该提供选项,某些Activity中选择原生View,在有需求的地方再选择Animator View。</p> <p>同时,由于并不是所有时候都需要动画,如首次加载界面的时候,如果每个View都执行一次动画,不仅耗费资源,也很奇怪。因此需要提供开启动画和关闭动画的选项,在需要的时候开启动画。</p> <h2>4. 代码实现</h2> <h3>4.1 功能概要</h3> <ul> <li>自定义View,覆盖原生 setVisibility() 等方法</li> <li>实现多种Animator</li> <li>实现配置View可用动画的架构</li> </ul> <h3>4.2 细节实现</h3> <ul> <li> <p>自定义View</p> <p>覆盖 setVisibility 方法:</p> <pre> <code class="language-java">@Override public void setVisibility(int visibility) { if (AnimatorManager.getConfig().getTextViewVisibleAnimationType() == ViewAnimatorType.None) { super.setVisibility(visibility); } else { this.visibleStatus = visibility; if (visibility == GONE) { ViewAnimatorUtil.executeAnimator(this, AnimatorManager.getConfig().getTextViewVisibleAnimationType(), visibleAction); } else { visibleAction.action(); } } }</code></pre> <p>主要是判断如果不执行动画,那么执行父类方法即可。</p> </li> <li> <p>实现多种Animator</p> </li> </ul> <p>这个主要实现三类动画,出现、消失、更新,可以放置在不同的文件夹中。这里使用了Enum值表示不同的动画,方便配置使用:</p> <pre> <code class="language-java">ROTATE3{ @Override public void apply(View view, Action action) { SkinRotateAnimator3.getInstance().apply(view, action).start(); } },</code></pre> <ul> <li> <p>实现配置View可用动画的架构</p> <p>这个主要通过两个类来实现,一个提供动画操作接口,一个提供动画配置接口:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/7f19416a268145ed069d73d640f2e784.png"></p> </li> </ul> <p style="text-align:center"><img src="https://simg.open-open.com/show/9687a3d9f820734b0cd943b2a994df40.png"></p> <p>动画配置使用build的方式,操作方法:</p> <pre> <code class="language-java">new AnimatorConfig.Builder() .textviewTextAnimationType(ViewAnimatorType.AlphaUpdateAnimator) .textviewVisibleAnimationType(ViewAnimatorType.TranslationAlphaHideAnimator) .imageviewVisibleAnimationType(ViewAnimatorType.TranslationAlphaHideAnimator) .build())</code></pre> <p>以上就是实现animator everywhere 的思路和基本的代码结构</p> <p>以下是已经实现的一些动画:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/9851bf0cc128ad62e7d1f12d341d802c.gif"></p> <p style="text-align:center"><img src="https://simg.open-open.com/show/19cb4cdbf1974d10694c4d75864a32d8.gif"></p> <h3>4.3 框架使用:</h3> <ul> <li> <p>1.继承 SkinCompatActivity , 同时支持了换肤功能</p> </li> <li> <p>2.如果Activity需要支持全局动画,覆盖方法:</p> </li> </ul> <pre> <code class="language-java">@Override protected boolean needAnimator() { return true; }</code></pre> <p>如果不需要,则不用理会</p> <ul> <li>3.在Activity中设置动画配置:</li> </ul> <pre> <code class="language-java">setAnimatorConfig(new AnimatorConfig .Builder() .textviewTextAnimationType(ViewAnimatorType.AlphaUpdateAnimator) .textviewVisibleAnimationType(ViewAnimatorType.TranslationAlphaHideAnimator) .build());</code></pre> <p>在其它地方设置配置:</p> <pre> <code class="language-java">AnimatorManager.setConfig(new AnimatorConfig.Builder() .textviewVisibleAnimationType(ViewAnimatorType.TranslationAlphaHideAnimator) .textviewTextAnimationType(ViewAnimatorType.AlphaUpdateAnimator) .build());</code></pre> <ul> <li>4.在需要的地方打个关闭动画:</li> </ul> <pre> <code class="language-java">AnimatorManager.openAnimator(); AnimatorManager.closeAnimator();</code></pre> <h2>5. 换肤动画</h2> <p>感觉动画写起来还是挺好玩的,于是对换肤过程也写了几个动画:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/ff24b1cd8b28025231466a7d0eaf857e.gif"></p> <p style="text-align:center"><img src="https://simg.open-open.com/show/0ed653c597ddcfa237611492816fb250.gif"></p> <p style="text-align:center"><img src="https://simg.open-open.com/show/0a5e68aaaa4ed7de00f35869c9c89ddd.gif"></p> <p style="text-align:center"><img src="https://simg.open-open.com/show/b146071b656e761403716ce0a967f9e9.gif"></p> <p>其实实现起来都比较简单,主要就是把动画进行分解,通过组合使用平移、旋转、大小变化等基本动画,就可以做出比较好动画。</p> <p> </p> <p> </p> <p>来自:http://www.jianshu.com/p/e96e9775caa3</p> <p> </p>