Night模块(一)

来源:互联网 发布:截图下载软件 编辑:程序博客网 时间:2024/06/06 20:02
Night模块(一)


Night模块是前期的试手项目,虽然比较简单,不过因为本blog的目的就是记录所有自己的工作点滴,
因此这个也不漏掉.
NightMode其中一个组件就是提供一个夜间日间模式切换的动画,
产品和设计给的设计稿就是一个太阳/月亮按照某种可计算的轨迹升起/落下,并且伴随着整个APP界面的渐变亮/暗.


<1>此UI组件NightToggleAnimatioView直接extends了FrameLayout, 并且拥有独立的layout文件,layout最外的包裹类
就是NightToggleAnimatioView,如何显示这个NightToggleAnimatioView,有两种方案:
(1)直接将此View覆盖在MainView上面<都处于一个FrameLayout>,平时是INVISIBLE,在需要的时候变为VISIBLE.
(2)在MainLayout文件中不添加此View,然后每次使用时,动态的inflate对应的layout文件,然后将其add到MainView所处的
FrameLayout中,在不需要的时候在remove.
方案1的优点是性能好,不必用的时候才生成View,但是增加了MainLayout的setContentView时间,增加了启动时间和占用内存.
方案2正好相反,虽然中间也想过将View用ViewStub包裹来两者部分兼顾,但是后来感觉这个功能对性能其实不敏感,
切换夜间模式通常不会是一个频繁的行为.所以最终使用了方案2.


<2>自定义View取得内部View的索引的时机就是onFinishInflate.


<3>需要一个backGroundView来显示背景,这是为了截取MainView的截图作为模拟还在MainView的效果<将View直接设为透明不行,因为MainView在
NightMode切换的时候的颜色变化不可能达到整个MainView渐变的效果,并且慢慢变暗的效果不等于MainView夜间模式效果>.
还要在backGroundView上覆盖一个View来实现慢慢变暗/明的效果,渐变是通过逐渐调整alpha来实现的,并且处于兼容性,使用了
nineOldAndroid的ObjectAnimator来实现.


<4>太阳/月亮使用两个ImageView, 位移的效果变换是通过调整TranslationX/Y实现<不需要重新layout,只需要redraw>,


<5>View截图得到BitmapDrawable很简单,create一张和View等宽高的Bitmap<一般用RGB_565>,然后创建一个以此Bitmap为底的
canvas,直接View.draw(canvas),最后利用此Bitmap构造一个BitmapDrawable即可,注意create过程中可能会有OutOfMemoryError,
这种情况就返回null了<但是不至于让程序crash,就是不好看罢了>


<6>渐变效果依旧还是ValueAnimator的AnimatorUpdateListener来实现,

<7>该组件对外的唯一开发接口是Toggle,输入 一个boolean表明暗/明,以及一个runnable作为动画完了以后的在MainHandler回调<项目中很喜欢用这种
runnable封装的简化回调法,方便handler的使用,也不用EventBus或者Listener>.

<8>sun和moon两个ImageView在FrameLayout中的layout_gravity都是center, 即默认在TranslationX/Y不调整的时候
都在屏幕的中心,也是最终升起到的位置,以后所有的TranslationX/Y调整都是以此为基准值的,顺便再说一下TranslationX/Y>0,
View向右/下移动。

<9>动画的设计本身完全就是设计驱动的,设计和产品是大爷,是导演,开发的任务就是利用各种的Animator相关tool来实现,
比如要实现几个动画连续/一起播放,可以使用AnimatorSet的playSequentially/playTogether<还需要start,没有真正开始>,
空等待就利用setStartDelay实现,就那么几样.

<10>sun/moon的TranslationX/Y调整基于二阶贝塞儿函数<现在已然忘了>,虽然为ValueAnimnator指定了ofFloat,但是实际的
updateListener中并没有使用这个值<getAnimatedValue()>,而是使用了以1为最大值的动画完成比率<getAnimatedFractio()
elapsed/interpolated fraction>,因为贝塞儿曲线方程的参数就是t[0,1],为了便于重复利用AnimatorUpdateListener的处理逻辑,

implements的类里面可以指定要被操作的View,以及起点X/Y,终点X/Y等信息,这样sun和moon就可以直接用同一个即可.


0 0