Android で画像の色を変更するいくつかの方法

1. 画像の色を変更するためのアプリケーションシナリオ

一般に、同じアイコンは、異なるページおよび異なるシナリオでは異なる色で表示されます。あるいは、異なるテーマ、異なる色を使用することもできます。もちろん、UI に色ごとに画像を切り取らせることもできますが、その作業は非常に面倒である一方で、アプリケーションのシナリオは狭く、毎回拡張するのに役立ちません。新しいデザインや新しいテーマがあるたびに、新しいパッケージをリリースする必要があります。最終的にはパッケージサイズも大幅に大きくなるため、同じアイコンの色をコードで動的に変更する必要があります。

この記事では、主にアイコンの色の変更と、画像全体が同じ色の値である場合の画像の変更について説明します。もちろん、アイコン自体の一部の領域が透明な場合は、透明度は継続され、変更されません。したがって、アイコンが完全に不透明な大きな領域を持つ画像である場合、使用後は画像の輪郭を持つ単色のブロックになるため、次の解決策は適用されません。
自分用にシェイプ タイプのドローアブルを描画している場合は、コードを通じてそのカラー値を動的に設定することもできます。
画像が svg の場合、異なる領域 (パスまたはグループ) に異なる色を設定することもできます。これには、svg 画像の xml ファイルについてのある程度の理解が必要です。png タイプのように色の値を直接設定することはできません。

2. アイコンの色を更新する仕組み

2.1 XML を通じてアイコンの色を直接変更する

1 つ目の方法は、src にティントを設定する方法ですが、バージョンの互換性のため、ティントは app タグを使用する必要があることに注意する必要があります。

android:src="@drawable/ic_tag"
app:tint="@color/white"

2 番目の方法は、backgroundTint を背景に設定することです。

android:background="@drawable/ic_tag"
android:backgroundTint="@color/blue"

3 番目の方法では、少なくとも Android バージョン 23 と互換性のあるアプリケーションに対して foreground と foregroundTint を設定できます。

android:foreground="@drawable/ic_tag"
android:src="@drawable/ic_tag"
android:foregroundTint="@color/white"

:

  1. foreground は前景であるため、imageview はその幅と高さを取得して独自の幅と高さに設定することはできません。そのため、foreground を使用する場合は、幅と高さを固定するか、src または background を設定する必要があります。3 番目のオプションは、アイコンの色を変更することはお勧めできません。
  2. ティントを設定するときは、自分のニーズに応じて、対応するティントモードを設定できます。モードごとに、写真の色の変更方法が異なります。アイコンを別の色に変更するだけの場合は、設定せずにデフォルトを使用します。

2.2 ローカル描画形状タイプのドローアブルを動的に設定する

一般に、ローカルに描画された形状は背景に設定されるため、次の設定を行うことができます。

val gd = view.background as? GradientDrawable
gd?.mutate() //重点注意,这里需要调用mutate()
//设置填充颜色,如果是纯色,直接设置color颜色即可,如果是渐变,则需要使用int数组设置到colors
gd?.colors = intArrayOf(bgColor,bgColor) 
//设置边框,第一个参数表示宽度,后面一个表示边框的颜色,有两种取值,直接color或colorStateList
gd?.setStroke(DisplayUtil.dip2px(1f), ColorStateList.valueOf(bgColor)) 

注記:

  1. Android システムのキャッシュにより、リソースのドローアブルが生成された後、リソースを使用するときにオブジェクトが直接呼び出されます。mutate() を設定せずにコード内でリソースの色を動的に調整すると、その後の呼び出しはリソースの色の値はすべて動的に設定される色です。ただし、mutate() を設定すると、この変更はキャッシュされないことになります。同様に、ドローアブルの色を動的に更新する限り、このメソッドの呼び出しを考慮する必要があります。
  2. 塗りつぶしの色の設定では、単色の設定とグラデーションの色の設定に注意する必要があり、対応するパラメータはそれぞれ @ColorInt int color と @ColorInt int[] color です。

2.3 画像の色を動的に設定するコード

最初の方法は、colorfilter を imageview に設定することです。

imageview.setColorFilter(Color.parseColor(“#de1212”))

2 番目の方法は、imageTintList を imageview に設定することです。

imageview.imageTintList = ColorStateList.valueOf(colorInt)

xml と同じように、ここでbackgroundTintList = ColorStateList.valueOf(colorInt)を設定することもできます。一部のコントロール アイコンがボタン (CheckBox) の場合は、 textview のドローアブルbuttonTintList = iconsColorStates
を使用できます

textView.compoundDrawables.forEach {
    
    
            it?.mutate()
            it?.setTintList(ColorStateList.valueOf(Color.parseColor("#02724E")).withAlpha(153)) //设置带透明度的颜色
}

注:
ColorStateList については、特定の色だけであれば ColorStateList.valueOf(colorInt) を直接使用できますが、状態ごとに異なる色を設定したい場合は、ColorStateList(int[][] states, @ColorInt int) を使用できます。 [ ]色)を設定します。
例えば:
ColorStateList(arrayOf(intArrayOf(-android.R.attr.state_checked),intArrayOf(android.R.attr.state_checked)), intArrayOf(iconRgb, iconSelectRgb))

拡張してください

ColorStateList はさまざまな状態で色を設定できるので、さまざまな状態で使用されるさまざまなアイコンはありますか? もちろん、次のようなものがあります: StateListDrawable。これは、ColorStateList と同様に使用されます。たとえば、次のようになります。

val stateListDrawable = StateListDrawable()
//按下背景 后一个参数为drawable类型
stateListDrawable.addState(intArrayOf(android.R.attr.state_pressed), pressBackGroundDrawable)
//选中背景
stateListDrawable.addState(intArrayOf(android.R.attr.state_selected), selectBackGroundDrawable)
//默认背景
stateListDrawable.addState(intArrayOf(), gradientDrawable)
view.background = stateListDrawable

もちろん、上記のさまざまな状態で使用されるドローアブルは、上記のメソッドを使用して動的に色を設定することもできます。

2.4 SVG 画像の動的な色の変更

このようなSVG画像があります。XMLは次のとおりです

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="25dp"
    android:height="25dp"
    android:viewportWidth="1024"
    android:viewportHeight="1024">
    <path
        android:name="border"
        android:fillColor="#FFFFFF"
        android:pathData="M512,0c255.41,0 462.45,207.05 462.45,462.45s-207.05,462.45 -462.45,462.45S49.55,717.86 49.55,462.45 256.59,0 512,0zM512,66.06C293.1,66.06 115.61,243.55 115.61,462.45s177.48,396.39 396.39,396.39 396.39,-177.48 396.39,-396.39S730.9,66.06 512,66.06z" />
    <path
        android:name="solid"
        android:fillColor="#22C96A"
        android:pathData="M512,66.06c218.9,0 396.39,177.48 396.39,396.39s-177.48,396.39 -396.39,396.39S115.61,681.36 115.61,462.45 293.1,66.06 512,66.06z" />
    <path
        android:name="center"
        android:fillColor="#FAFFFC"
        android:pathData="M444.12,534.66l237.47,-237.44a48.36,48.36 0,0 1,68.54 0.13c18.96,18.96 18.96,49.71 0.13,68.54l-268.98,268.95c-8.92,8.92 -20.38,13.64 -32.04,14.14a47.57,47.57 0,0 1,-39.21 -13.48l-136.36,-136.36a47.5,47.5 0,0 1,0.1 -67.39,47.86 47.86,0 0,1 67.39,-0.1l102.96,102.99z" />
</vector>

ここに画像の説明を挿入します
パスは 3 つあり、border は一番外側の白いリング、solid は塗りつぶされた緑色の領域、center は中央の白です √
この 3 つのパスのうち、pathData 以外は変更できませんが、その他は開発およびカスタマイズできます。 。

android:name は、現在のパスの名前を設定します。後続のコードでは、この名前でパスが検索され、色が変更されます。android:fillColor は、現在のパスの
塗りつぶしの色です。その後の変更は、コード setFillColor を通じて行われます。 (int Color).
android:strokeColor は現在のパスの境界線の色です。そして、コード setStrokeColor(int Color) を通じてそれを変更します。他にも、
ストロークAlpha、ストローク幅、fillAlpha などの関数があります。それらの関数を知ることができます彼らの名前によると。

コードは色の値を設定します。例:

 VectorChildFinder selectedVector = new VectorChildFinder(context, R.drawable.vector_drawable_ico_selected, imageView);
 VectorDrawableCompat.VFullPath solid = selectedVector.findPathByName("solid");
 solid.setFillColor(iconColor);
 imageView.invalidate(); //重绘imageView

質問する:

SVG 画像に同じ色のパスが多数ある場合、これらのパスに同じ名前を付けることができますか? そうでない場合、findPathByName、setFillColor の繰り返しを避けるにはどうすればよいでしょうか。findPathByNameに加えて、 findGroupByNameメソッドもあります。このグループを通過する方法を見つけることはできますか?

おすすめ

転載: blog.csdn.net/qq_39734865/article/details/132204375