我使用以下行更改VectorDrawable的颜色:
mydrawable.getBackground().setColorFilter(color, PorterDuff.Mode.SRC_ATOP)
尽管现在已不推荐使用,但效果很好。该文档建议我使用:
mydrawable.getBackground().setColorFilter(new BlendModeColorFilter(color, PorterDuff.Mode.SRC_ATOP))
虽然,BlendModeColorFilter
仅在API29上可用。在检查了不赞成使用的方法的源之后,我意识到它调用了:
new PorterDuffColorFilter()
因此,我继续使用:
mydrawable.getBackground().setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP))
着色工作。这是不推荐使用的方法的正确替代方法,还是我必须在API29上使用BlendModeColorFilter?
谢谢。
shm*_*ova 24
尝试这个:
public class MyDrawableCompat {
public static void setColorFilter(@NonNull Drawable drawable, int color) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
drawable.setColorFilter(new BlendModeColorFilter(color, BlendMode.SRC_ATOP));
} else {
drawable.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
}
}
}
Run Code Online (Sandbox Code Playgroud)
和这个:
MyDrawableCompat.setColorFilter(mydrawable.getBackground(), color);
Run Code Online (Sandbox Code Playgroud)
Coo*_*ind 11
感谢 @shmakova,我为 Kotlin 添加了一个解决方案。
import android.graphics.BlendMode
import android.graphics.BlendModeColorFilter
import android.graphics.PorterDuff
import android.graphics.drawable.Drawable
import android.os.Build
import androidx.annotation.RequiresApi
fun Drawable.setColorFilter(color: Int, mode: Mode = Mode.SRC_ATOP) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
colorFilter = BlendModeColorFilter(color, mode.getBlendMode())
} else {
@Suppress("DEPRECATION")
setColorFilter(color, mode.getPorterDuffMode())
}
}
// This class is needed to call the setColorFilter
// with different BlendMode on older API (before 29).
enum class Mode {
CLEAR,
SRC,
DST,
SRC_OVER,
DST_OVER,
SRC_IN,
DST_IN,
SRC_OUT,
DST_OUT,
SRC_ATOP,
DST_ATOP,
XOR,
DARKEN,
LIGHTEN,
MULTIPLY,
SCREEN,
ADD,
OVERLAY;
@RequiresApi(Build.VERSION_CODES.Q)
fun getBlendMode(): BlendMode =
when (this) {
CLEAR -> BlendMode.CLEAR
SRC -> BlendMode.SRC
DST -> BlendMode.DST
SRC_OVER -> BlendMode.SRC_OVER
DST_OVER -> BlendMode.DST_OVER
SRC_IN -> BlendMode.SRC_IN
DST_IN -> BlendMode.DST_IN
SRC_OUT -> BlendMode.SRC_OUT
DST_OUT -> BlendMode.DST_OUT
SRC_ATOP -> BlendMode.SRC_ATOP
DST_ATOP -> BlendMode.DST_ATOP
XOR -> BlendMode.XOR
DARKEN -> BlendMode.DARKEN
LIGHTEN -> BlendMode.LIGHTEN
MULTIPLY -> BlendMode.MULTIPLY
SCREEN -> BlendMode.SCREEN
ADD -> BlendMode.PLUS
OVERLAY -> BlendMode.OVERLAY
}
fun getPorterDuffMode(): PorterDuff.Mode =
when (this) {
CLEAR -> PorterDuff.Mode.CLEAR
SRC -> PorterDuff.Mode.SRC
DST -> PorterDuff.Mode.DST
SRC_OVER -> PorterDuff.Mode.SRC_OVER
DST_OVER -> PorterDuff.Mode.DST_OVER
SRC_IN -> PorterDuff.Mode.SRC_IN
DST_IN -> PorterDuff.Mode.DST_IN
SRC_OUT -> PorterDuff.Mode.SRC_OUT
DST_OUT -> PorterDuff.Mode.DST_OUT
SRC_ATOP -> PorterDuff.Mode.SRC_ATOP
DST_ATOP -> PorterDuff.Mode.DST_ATOP
XOR -> PorterDuff.Mode.XOR
DARKEN -> PorterDuff.Mode.DARKEN
LIGHTEN -> PorterDuff.Mode.LIGHTEN
MULTIPLY -> PorterDuff.Mode.MULTIPLY
SCREEN -> PorterDuff.Mode.SCREEN
ADD -> PorterDuff.Mode.ADD
OVERLAY -> PorterDuff.Mode.OVERLAY
}
}
Run Code Online (Sandbox Code Playgroud)
像往常一样使用它:
toolbar?.navigationIcon?.setColorFilter(ContextCompat.getColor(this, color)) /* 1 */
progressBar.indeterminateDrawable.setColorFilter(color, Mode.SRC_IN) /* 2 */
Run Code Online (Sandbox Code Playgroud)
我尝试setColorFilter
同时使用BlendMode
和PorterDuff.Mode
参数(如drawable.setColorFilter(color, BlendMode.SRC_ATOP, PorterDuff.Mode.SRC_ATOP)
)进行调用,但这导致了运行时异常:
java.lang.NoClassDefFoundError:解析失败:Landroid/graphics/BlendMode;
因此,我们只能从 SDK 版本 29(它被添加到那里)开始使用BlendMode调用任何方法。我必须setColorFilter
用Mode
参数创建。
小智 9
使用androidx.core:core:1.2.0-beta01
或androidx.core:core-ktx:1.2.0-beta01
。
// Java
implementation 'androidx.core:core:1.2.0-beta01'
// Kotlin
implementation 'androidx.core:core-ktx:1.2.0-beta01'
Run Code Online (Sandbox Code Playgroud)
和这个:
drawable.setColorFilter(BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, BlendModeCompat.SRC_ATOP))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3575 次 |
最近记录: |