目录
Observer处理完onComplete后会还能onNext吗?
Activity,Dialog,Toast的Window创建过程
差值器和估值器
差值器
一般指时间差值器TimeInterpolator,是设置 属性值 从初始值过渡到结束值 的变化规律,比如匀速,加速,减速等等。可以通过xml属性和java代码设置。系统默认的差值器是AccelerateDecelerateInterpolator,即先加速后减速。
//匀速插值器设置
android:interpolator="@android:anim/linear_interpolator"
或
alphaAnimation.setInterpolator(new LinearInterpolator());
属性动画中,差值器的含义就是要设置时间和属性的变化关系,也就是根据动画的进度(0%-100%)通过逻辑计算 计算出当前属性值改变的百分比。比如匀速关系就是动画进度和属性值改变的进度保持一致,50%时间进度就完成了属性值50%的变化。
自定义匀速差值器
public class MyLinearInterpolator implements TimeInterpolator {
@Override
public float getInterpolation(float input) {
return input;
}
估值器
又叫类型估值算法TypeEvaluator,用来设置 属性值 从初始值过渡到结束值 的变化具体数值,刚才介绍的差值器是指变化规律,而这个估值器是决定具体的变化数值,是用来协助差值器完成动画设置。比如属性动画设置:
ObjectAnimator anim = ObjectAnimator.ofObject(view, "scale", new IntEvaluator(),1,10);
//系统估值器类型
IntEvaluator:针对整型属性
FloatEvaluator:针对浮点型属性
ArgbEvaluator:针对Color属性
可以看看IntEvaluator源码,其实就是根据三个参数—估值小数(fraction),开始值(startValue)和 结束值(endValue)然后计算具体属性变化的值:
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
所以要实现一个完整的属性动画,需要估值器和差值器进行协同工作:
- 首先由TimeInterpolator(差值器)根据时间流逝的百分比计算出当前属性值改变的百分比,并且 差值器 将这个百分比返回,这个时候 差值器 的工作就完成了。
- 比如 差值器 返回的值是0.5,很显然我们要的不是0.5,而是当前属性的值,即当前属性变成了什么值,这就需要 估值器根据当前属性改变的百分比来计算改变后的属性值,根据这个属性值,我们就可以设置当前属性的值了。
使用动画的注意事项
- OOM问题:这个问题主要出现在帧动画中,当图片数量较多且图片较大时就极易出现OOM,这个在实际开发中要尤其注意,尽量避免使用帧动画
- 内存泄露:在属性动画中有一类无限循环的动画,这类动画需要在Activity退出时及时停止,否则将导致Activity无法释放从而造成内存泄露,通过验证后发现View动画并不存在此问题
- 兼容性问题:动画在3.0以下的系统有兼容性问题,在某些特殊场景可能无法正常工作,因此要做好适配工作
- View动画的问题:View动画是对View的影像做动画,并不是真正改变View的状态,因此有时候会出现动画完成后View无法隐藏的现象,即setVisibility(View.GOEN)失效了,这个时候只要调用view.clearAnimation()清除View动画即可解决问题
- 不要使用px:在进行动画的过程中,要尽量使用dp,使用px会导致在不用的设备上有不用的效果
- 动画元素的交互:从3.0开始,将view移动(平移)后,属性动画的单击事件触发位置为移动后的位置,但是View动画仍然在原位置。在Android3.0以前的系统中,不管是View动画还是属性动画,新位置都无法触发单击事件同时,老位置仍然能触发单击事件(因为属性动画在Android3.0以前是没有的,是通过兼容包实现的,底层也是调用View动画)
- 硬件加速:使用动画的过程中,建议开启硬件加速,这样会提高动画的流畅性
RxJava的订阅关系
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
emitter.onNext(1);
emitter.onComplete();
}
}).subscribe(new Observer<Integer>() {
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
Toast.makeText(activity, "Error!", Toast.LENGTH_SHORT).show();
}
});
代码中主要有三个角色:
-
被订阅者Observable,是整个事件的来源,可以发射数据给订阅者。
-
订阅者Observer,通过subscribe方法和被订阅者产生关系,也就是开始订阅,同时可以接受被订阅者发送的消息。
-
发射器Subscriber/Emitter,在Rxjava2之后,发射器改为了Emitter,他的作用主要是用来发射一系列事件的,比如next事件,complete事件等等。
有了这三个角色,一个完整的订阅关系也就生成了。
Observer处理完onComplete后会还能onNext吗?
要弄清楚这个问题,得去看看onComplete,onNext方法到底做了什么。
@Override
public void onComplete() {
if (!isDisposed()) {
try {
observer.onComplete();
} finally {
dispose();
}
}
}
@Overrid

本文详细探讨了Android开发中的关键概念,包括差值器和估值器在动画中的作用,使用动画的注意事项,如内存管理和兼容性问题。此外,还深入讲解了Drawable、Canvas、Bitmap的关系,Window的内部机制,以及Activity、Dialog和Toast的Window创建过程。对于开发者来说,理解这些概念对于提升Android应用的性能和用户体验至关重要。
最低0.47元/天 解锁文章
223

被折叠的 条评论
为什么被折叠?



