概念
TransitionDrawable是LayerDrawable的子类,主要用于实现LayerDrawable两层之间的渐变效果,开启第一层到第二层的渐变只需要调用startTransition(int)即可,再调用resetTransition()显示第一层。
官方文档内容
(1)继承结构:
(2)xml属性(item中的属性,下文有例子):
Attribute Name | Description |
---|---|
android:bottom | Bottom coordinate of the layer. |
android:drawable | Drawable used to render the layer. |
android:id | Identifier of the layer. |
android:left | Left coordinate of the layer. |
android:right | Right coordinate of the layer. |
android:top | Top coordinate of the layer. |
(3)方法:
返回类型 | 方法名 | 方法描述 |
---|---|---|
void | draw(Canvas canvas) | Draw in its bounds (set via setBounds) respecting optional effects such as alpha (set via setAlpha) and color filter (set via setColorFilter). |
boolean | isCrossFadeEnabled() | Indicates whether the cross fade is enabled for this transition. |
void | resetTransition() | Show only the first layer. |
void | reverseTransition(int duration) | Reverses the transition, picking up where the transition currently is. |
void | setCrossFadeEnabled(boolean enabled) | Enables or disables the cross fade of the drawables. |
void | startTransition(int durationMillis) | Begin the second layer on top of the first layer. |
使用方式
一 、xml中定义TransitionDrawable的方式
- 定义TransitionDrawable的xml
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/dengpao_off"/>
<item android:drawable="@drawable/dengpao_on"/>
</transition>
- 调用界面的xml布局
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LightTransitionActivity">
<ImageView
android:id="@+id/iv_light"
android:layout_width="80dp"
android:layout_height="80dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:src="@drawable/dengpao"/>
<Switch
android:id="@+id/switchView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginTop="20dp"
android:showText="true"
android:textOff="关"
android:textOn="开"
app:layout_constraintTop_toBottomOf="@+id/iv_light"/>
</androidx.constraintlayout.widget.ConstraintLayout>
- Java代码中调用代码片段
transitionDrawable = (TransitionDrawable) iv_light.getDrawable();
//transitionDrawable.startTransition(1000);
switchView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
transitionDrawable.reverseTransition(1000);
}
});
-
实现效果:
二、Java代码中定义TransitionDrawable的使用方式
界面xml布局如下:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/container"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TransitionActivity">
<ImageView
android:id="@+id/iv_show"
android:layout_width="270dp"
android:layout_height="480dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
背景container,用于展示高斯模糊背景图,ImageView用于展示用于高斯模糊的图片。
Java代码片段如下:
private void handleTransition(int position){
iv_show.setImageResource(mipmaps.get(position));
Bitmap resBlurBmp = BlurBitmapUtil.blurBitmap(this, BitmapFactory.decodeResource(getResources(),mipmaps.get(position)),15f);
// 再将resBlurBmp转为Drawable
Drawable resBlurDrawable = new BitmapDrawable(getResources(),resBlurBmp);
// 获取前一页的Drawable
Drawable preBlurDrawable = preDrawable == null ? resBlurDrawable : preDrawable;
/* 以下为淡入淡出效果 */
Drawable[] drawableArr = {preBlurDrawable, resBlurDrawable};
TransitionDrawable transitionDrawable = new TransitionDrawable(drawableArr);
transitionDrawable.startTransition(500);
container.setBackground(transitionDrawable);
//更新前一次drawable为最新
preDrawable = resBlurDrawable;
}
例子中,我们用一组mipmap图片构成一个列表,当点击图片时切换到下一张,循环切换,背景进行高斯模糊,同时使用TransitionDrawable来实现切换图片背景的平滑过渡。
实现效果:
附上高斯模糊的代码:
public class BlurBitmapUtil {
//图片缩放比例
private static final float BITMAP_SCALE = 0.4f;
/**
* 模糊图片的具体方法
*
* @param context 上下文对象
* @param image 需要模糊的图片
* @return 模糊处理后的图片
*/
public static Bitmap blurBitmap(Context context, Bitmap image, float blurRadius) {
// 计算图片缩小后的长宽
int width = Math.round(image.getWidth() * BITMAP_SCALE);
int height = Math.round(image.getHeight() * BITMAP_SCALE);
// 将缩小后的图片做为预渲染的图片
Bitmap inputBitmap = Bitmap.createScaledBitmap(image, width, height, false);
// 创建一张渲染后的输出图片
Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
// 创建RenderScript内核对象
RenderScript rs = RenderScript.create(context);
// 创建一个模糊效果的RenderScript的工具对象
ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
// 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间
// 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去
Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
// 设置渲染的模糊程度, 25f是最大模糊度
blurScript.setRadius(blurRadius);
// 设置blurScript对象的输入内存
blurScript.setInput(tmpIn);
// 将输出数据保存到输出内存中
blurScript.forEach(tmpOut);
// 将数据填充到Allocation中
tmpOut.copyTo(outputBitmap);
return outputBitmap;
}
}
最后附上一篇简单介绍Drawable及Drawable各个子类的文章:
Drawable图像资源抽象类