Android 开发 Tip 17 -- 为什么getBackground().setAlpha(); 会影响别的控件?

本文介绍如何通过调用Drawable的mutate()方法确保Drawable实例的状态独立于资源加载过程中的其他实例。这样可以避免修改一个实例时影响到其他实例的状态。

转载请注明出处:http://blog.csdn.net/crazy1235/article/details/75670018


http://www.jb51.net/article/110035.htm

https://mp.weixin.qq.com/s?__biz=MzA3NTYzODYzMg==&mid=2653578233&idx=1&sn=aea773c1e815fdef910fba28d765940b&chksm=84b3b1feb3c438e8372850a36bdcb87fdfb1ca793793a7c9598bcc792aabbb0f417b7a32c989&mpshare=1&scene=1&srcid=1117pJi4bqTWG94d2q3Dl65f#wechat_redirect

/**
     * Make this drawable mutable. This operation cannot be reversed. A mutable
     * drawable is guaranteed to not share its state with any other drawable.
     * This is especially useful when you need to modify properties of drawables
     * loaded from resources. By default, all drawables instances loaded from
     * the same resource share a common state; if you modify the state of one
     * instance, all the other instances will receive the same modification.
     *
     * Calling this method on a mutable Drawable will have no effect.
     *
     * @return This drawable.
     * @see ConstantState
     * @see #getConstantState()
     */
    public @NonNull Drawable mutate() {
        return this;
    }
为了将背景动画从纯色背景更改为使用自定义的 `@drawable/lamp_shape`,我们需要进行以下修改: ### 修改说明: 1. **不再使用 `setBackgroundColor()`**:因为 `lamp_shape` 是一个 `Drawable`,我们不能直接将其设置为颜色。 2. **使用 `setBackgroundResource()`**:用于加载 `@drawable/lamp_shape`。 3. **使用 `ObjectAnimator` 或 `ValueAnimator` 来操作 Drawable 的 Alpha 值**:因为 `lampView.getBackground()` 是一个 `Drawable`,我们需要操作它的透明度。 --- ### ✅ 修改后的代码如下: ```java package com.example.android; import android.animation.ValueAnimator; import android.graphics.drawable.Drawable; import android.widget.TextView; import androidx.core.content.ContextCompat; public class Lamp { private TextView lampView; private ValueAnimator flashAnimator; private int onResourceId; // 替换为资源ID private int offResourceId = R.drawable.lamp_shape; // 默认关闭状态的Drawable private long interval = 500; // 默认闪烁间隔 public Lamp(TextView lampView, int onResourceId) { this.lampView = lampView; this.onResourceId = onResourceId; initAnimator(); } private void initAnimator() { flashAnimator = ValueAnimator.ofFloat(1f, 0.5f); flashAnimator.setDuration(interval); flashAnimator.setRepeatCount(ValueAnimator.INFINITE); flashAnimator.setRepeatMode(ValueAnimator.REVERSE); flashAnimator.addUpdateListener(animation -> { float alpha = (float) animation.getAnimatedValue(); Drawable background = lampView.getBackground(); if (background != null) { background.setAlpha((int) (255 * alpha)); } lampView.setAlpha(alpha); }); } public void startFlashing() { lampView.setBackgroundResource(onResourceId); // 使用资源ID设置背景 flashAnimator.start(); } public void stopFlashing() { flashAnimator.cancel(); Drawable background = lampView.getBackground(); if (background != null) { background.setAlpha(255); } lampView.setAlpha(1f); lampView.setBackgroundResource(offResourceId); // 恢复默认关闭状态 } } ``` --- ### 🔍 修改点解释: - `onColor` 被替换为 `onResourceId`,我们传入的是 `R.drawable.lamp_shape_on` 这样的资源 ID。 - `setBackgroundResource(int)` 替代了 `setBackgroundColor(int)`,用于设置 drawable- 动画逻辑中保持对 `Drawable.setAlpha()` 的调用不变,因为 drawable 同样支持透明度控制。 - `offColor` 被替换为默认的 drawable 资源 `R.drawable.lamp_shape`。 --- ### ✅ 使用方式: 在你的 `Activity` 或 `Fragment` 中这样使用: ```java Lamp lamp = new Lamp(myTextView, R.drawable.lamp_shape_on); lamp.startFlashing(); // 开始闪烁 lamp.stopFlashing(); // 停止闪烁 ``` --- ### 📌 注意事项: 1. 确保你已经在 `res/drawable` 目录下定义了两个状态的 drawable- `lamp_shape.xml`(关闭状态) - `lamp_shape_on.xml`(开启状态) 2. 如果你的 drawable 是 `StateListDrawable`(即包含不同状态的 XML),你也可以使用 `setImageResource()` + `ImageView` 替代 `TextView`,会更合适。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值