วิธีการตั้งค่าโทนสีสำหรับมุมมองภาพโดยทางโปรแกรมใน Android?


396

จำเป็นต้องตั้งค่าโทนสีสำหรับมุมมองภาพ ... ฉันใช้วิธีต่อไปนี้:

imageView.setColorFilter(R.color.blue,android.graphics.PorterDuff.Mode.MULTIPLY);

แต่มันไม่เปลี่ยน ...


15
คุณอาจใช้รหัสทรัพยากรจำนวนเต็มแทนค่าสีจำนวนเต็มลองแปลง R.color.blue เป็น getResources (). getColor (R.color.blue)
milosmns

Drawable drawable = ... ; drawable.setColorFilter (ContextCompat.getColor (บริบท, R.color.white), PorterDuff.Mode.DST); imageView.setImageDrawable (drawable); // สีใดก็ได้ที่สามารถใช้ได้ที่นี่
flame3

คำตอบ:


916

คุณสามารถเปลี่ยนโทนสีได้ง่าย ๆ ในรหัสผ่าน:

imageView.setColorFilter(Color.argb(255, 255, 255, 255)); // White Tint

ถ้าคุณต้องการสีอ่อนแล้ว

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.MULTIPLY);

สำหรับ Vector Drawable

imageView.setColorFilter(ContextCompat.getColor(context, R.color.COLOR_YOUR_COLOR), android.graphics.PorterDuff.Mode.SRC_IN);

อัปเดต :
@ADev มีคำตอบที่ใหม่กว่าในคำตอบของเขาที่นี่แต่โซลูชันของเขาต้องการไลบรารีการสนับสนุนที่ใหม่กว่า - 25.4.0 หรือสูงกว่า



12
ใน xml, android: tint = "@ color / blue"
Luis

1
Android เพิ่มเติม: โทนสีเป็น 21+
androidguy

8
android:tintทำงานบน Android ทุกรุ่น บางทีคุณกำลังพูดถึงdrawableTint?
finstas

11
PorterDuff.Mode.MULTIPLY ไม่ทำงานในสถานการณ์ของฉันฉันใช้ PorterDuff.Mode.SRC_IN และใช้งานได้
Mohamed Nageh

234

คำตอบส่วนใหญ่อ้างถึงการใช้งานsetColorFilterซึ่งไม่ใช่สิ่งที่ถูกถามตั้งแต่แรก

ผู้ใช้ @Tad มีคำตอบในทิศทางที่ถูกต้อง แต่ใช้งานได้กับ API 21+ เท่านั้น

ในการตั้งค่าโทนสีบน Android ทุกรุ่นให้ใช้ImageViewCompat:

ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(yourTint));

โปรดทราบว่าyourTintในกรณีนี้จะต้องเป็น "color int" หากคุณมีทรัพยากรสีเช่นR.color.blueคุณต้องโหลดสี int ก่อน:

ContextCompat.getColor(context, R.color.blue);

6
ควรเป็นคำตอบที่ยอมรับได้ โปรดทราบว่ามันใช้งานได้เฉพาะในImageViewอินสแตนซ์xml ด้วยธีม AppCompat หรือในAppCompatImageViewคลาสย่อย
Louis CAD

1
@ADev ขอขอบคุณทางออกของคุณ แต่คำถามถูกถามในปี 2013 และ ImageViewCompat และ AppCompatImageView รีลีสพร้อมการสนับสนุน v4 lib 25.4.0 ในเดือนมิถุนายน 2017 และ 25.1.0 ธันวาคม 2559 ตามลำดับ :)
Hardik

1
@ADev แน่นอน แต่คุณไม่ได้พูดถึงมันอย่างถูกต้องในคำตอบของคุณว่าโซลูชันของคุณเป็นของใหม่และต้องการไลบรารีการสนับสนุนที่ใหม่กว่า 25.4.0 ขึ้นไปเนื่องจากมีรุ่นที่ต่ำกว่าของการสนับสนุน lib คลาสนี้ไม่พร้อมใช้งาน !! โดยวิธีการที่ผมแก้ไขวันที่คำตอบที่ดี :) ...
Hardik

สิ่งนี้ใช้ไม่ได้กับ API 16
Tayyab Mazhar

49

สิ่งนี้ใช้ได้สำหรับฉัน

mImageView.setColorFilter(ContextCompat.getColor(getContext(), R.color.green_500));

ใช่ทำงานให้ฉันด้วยโดยไม่มีพารามิเตอร์ที่สอง .. มันสามารถไปได้ด้วยmImageView.setColorFilter(getContext().getResources().getColor(R.color.green_500));
Biskrem Muhammad

upvoted และไม่มีพารามิเตอร์ตัวที่สองมันทำงานเหมือนมีเสน่ห์ ขอบคุณ @ toobsco42
Ravi Vaniya

35

@Hardik มันถูกต้อง ข้อผิดพลาดอื่น ๆ ในรหัสของคุณคือเมื่อคุณอ้างอิงสีที่กำหนด XML ของคุณ คุณส่ง ID ไปยังsetColorFilterเมธอดเท่านั้นเมื่อคุณควรใช้ ID เพื่อค้นหาทรัพยากรสีและส่งผ่านทรัพยากรไปยังsetColorFilterเมธอด เขียนรหัสเดิมของคุณใหม่ด้านล่าง

หากบรรทัดนี้อยู่ในกิจกรรมของคุณ:

imageView.setColorFilter(getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

มิฉะนั้นคุณต้องอ้างอิงกิจกรรมหลักของคุณ:

Activity main = ...
imageView.setColorFilter(main.getResources().getColor(R.color.blue), android.graphics.PorterDuff.Mode.MULTIPLY);

โปรดทราบว่านี่เป็นความจริงของทรัพยากรประเภทอื่นเช่นจำนวนเต็ม bools ขนาด ฯลฯ ยกเว้นสตริงซึ่งคุณสามารถใช้getString()ในกิจกรรมของคุณโดยตรงโดยไม่ต้องโทรหาก่อนgetResources()(อย่าถามฉันว่าทำไม) .

มิฉะนั้นรหัสของคุณดูดี (แม้ว่าฉันจะไม่ได้ตรวจสอบsetColorFilterวิธีการมากเกินไป ... )


22

หลังจากที่ฉันลองใช้วิธีการทั้งหมดและพวกเขาไม่ได้ผลสำหรับฉัน

ฉันได้วิธีแก้ปัญหาโดยใช้ PortDuff.MODE อื่น

imgEstadoBillete.setColorFilter(context.getResources().getColor(R.color.green),PorterDuff.Mode.SRC_IN);

14

เริ่มต้นด้วย Lollipop นอกจากนี้ยังมีวิธีโทนสีสำหรับ BitmapDrawables ที่ทำงานกับคลาส Palette ใหม่:

โมฆะสาธารณะ setTintList (โทนสี ColorStateList)

และ

โมฆะสาธารณะ setTintMode (PorterDuff.Mode tintMode)

สำหรับ Android เวอร์ชันเก่าตอนนี้คุณสามารถใช้ไลบรารีDrawableCompat ได้แล้ว


2
จริง ๆ แล้วห้องสมุดสนับสนุนนั้นรองรับ ดูคำตอบของฉัน: stackoverflow.com/a/34479043/878126
นักพัฒนา Android

12

ลองสิ่งนี้ มันควรทำงานกับ Android ทุกรุ่นที่ห้องสมุดสนับสนุนรองรับ:

public static Drawable getTintedDrawableOfColorResId(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorRes int colorResId) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), ContextCompat.getColor(context, colorResId));
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Bitmap inputBitmap, @ColorInt int color) {
    return getTintedDrawable(context, new BitmapDrawable(context.getResources(), inputBitmap), color);
}

public static Drawable getTintedDrawable(@NonNull Context context, @NonNull Drawable inputDrawable, @ColorInt int color) {
    Drawable wrapDrawable = DrawableCompat.wrap(inputDrawable);
    DrawableCompat.setTint(wrapDrawable, color);
    DrawableCompat.setTintMode(wrapDrawable, PorterDuff.Mode.SRC_IN);
    return wrapDrawable;
}

คุณสามารถใช้ข้อใดข้อหนึ่งข้างต้นเพื่อให้มันใช้งานได้

คุณสามารถอ่านข้อมูลเกี่ยวกับคุณสมบัติที่น่าสนใจมากขึ้นของ DrawableCompat บนเอกสารที่นี่


1
ฉันยังต้องทำimageView.getBackground()เพื่อให้ได้มาเพราะimageView.getDrawable()มันกลับมาเป็นโมฆะ
Rock Lee

@RockLee ให้แน่ใจว่าคุณใช้ src ในมุมมองภาพ xml หรือ setImageResource ในรหัส
orelzion

นี่เป็นวิธีที่สมบูรณ์แบบในการตั้งค่าสีอ่อนสำหรับพื้นหลังมุมมองภาพ
398161

12

ฟังก์ชั่นการขยายที่ง่ายขึ้นดีขึ้นด้วยADev

fun ImageView.setTint(@ColorRes colorRes: Int) {
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(ContextCompat.getColor(context, colorRes)))
}

การใช้งาน: -

imageView.setTint(R.color.tintColor)

มีสีที่คล้ายกันสำหรับโทนสีของปุ่ม / TextView หรือไม่?
นักพัฒนา Android

คุณหมายถึง color text text หรือ tint สำหรับ textview drawable?
Manohar Reddy

ฉันหมายถึง "text tint" สีของข้อความ แต่ฉันคิดว่ามันค่อนข้างเป็นปัญหาเนื่องจากข้อความมีสีสำหรับแต่ละรัฐ ... จากนั้นอีกครั้งทำไมมันถึงได้ผลเมื่อฉันตั้งค่าสีที่ถูกเน้น ... แปลก ... ปุ่มเฉพาะ (หรือ TextView) โดยทางโปรแกรมหรือไม่
นักพัฒนา android

11

หากสีของคุณมีความโปร่งใสฐานสิบหกให้ใช้รหัสด้านล่าง

ImageViewCompat.setImageTintMode(imageView, PorterDuff.Mode.SRC_ATOP);
ImageViewCompat.setImageTintList(imageView, ColorStateList.valueOf(Color.parseColor("#80000000")));

เพื่อล้างสี

ImageViewCompat.setImageTintList(imageView, null);

ประเภทของ "img"
Beyaz

1
@Beyaz imgเป็นประเภท ImageView
สาย


9

ในฐานะที่เป็นคำตอบแรกไม่ได้สำหรับฉัน:

//get ImageView
ImageView myImageView = (ImageView) findViewById(R.id.iv);

//colorid is the id of a color defined in values/colors.xml
myImageView.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(), R.color.colorid)));

ดูเหมือนว่าจะใช้งานได้เฉพาะใน API 21+ เท่านั้น แต่สำหรับฉันที่ไม่ใช่ปัญหา คุณสามารถใช้ ImageViewCompat เพื่อแก้ไขปัญหานั้นได้

ฉันหวังว่าฉันช่วยทุกคนออก :-)


7

เริ่มต้นใน Lollipop มีวิธีการที่เรียกImageView#setImageTintList()ว่าคุณสามารถใช้ ... ประโยชน์ที่จะได้รับColorStateListเมื่อเทียบกับสีเดียวจึงทำให้ภาพของรัฐทราบสี

บนอุปกรณ์ pre-Lollipop คุณสามารถรับพฤติกรรมเดียวกันได้โดยการแต้มสี drawable แล้วตั้งเป็นImageViewภาพของ drawable:

ColorStateList csl = AppCompatResources.getColorStateList(context, R.color.my_clr_selector);
Drawable drawable = DrawableCompat.wrap(imageView.getDrawable());
DrawableCompat.setTintList(drawable, csl);
imageView.setImageDrawable(drawable);

6
Random random=new Random;
ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
ColorFilter cf = new PorterDuffColorFilter(Color.rgb(random.nextInt(255), random.nextInt(255), random.nextInt(255)),Mode.OVERLAY);

imageView.setImageResource(R.drawable.ic_bg_box);
imageView.setColorFilter(cf);

6

สำหรับตั้งค่าโทนสีสำหรับมุมมองภาพโดยทางโปรแกรมใน Android

ฉันมีสองวิธีสำหรับ Android:

1)

imgView.setColorFilter(context.getResources().getColor(R.color.blue));

2)

 DrawableCompat.setTint(imgView.getDrawable(),
                     ContextCompat.getColor(context, R.color.blue));

ฉันหวังว่าฉันช่วยทุกคนออก :-)


4

การเพิ่มคำตอบของADev (ซึ่งในความคิดของฉันถูกต้องที่สุด) เนื่องจากการยอมรับอย่างกว้างขวางของ Kotlin และฟังก์ชันการขยายที่เป็นประโยชน์:

fun ImageView.setTint(context: Context, @ColorRes colorId: Int) {
    val color = ContextCompat.getColor(context, colorId)
    val colorStateList = ColorStateList.valueOf(color)
    ImageViewCompat.setImageTintList(this, colorStateList)
}

ฉันคิดว่านี่เป็นฟังก์ชั่นที่น่าจะมีประโยชน์สำหรับโครงการ Android ใด ๆ !


4

ฉันพบว่าเราสามารถใช้ color selector สำหรับ tint attr:

mImageView.setEnabled(true);

activity_main.xml:

<ImageView
    android:id="@+id/image_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_arrowup"
    android:tint="@color/section_arrowup_color" />

section_arrowup_color.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@android:color/white" android:state_enabled="true"/>
    <item android:color="@android:color/black" android:state_enabled="false"/>
    <item android:color="@android:color/white"/>
</selector>

สวัสดีมันไม่ทำงานกับเวกเตอร์ที่วาดได้ .. การแก้ไขใด ๆ เหมือนกันหรือไม่
Manukumar

@Manukumar ใช้app:srcCompatแทนandroid:srcและเพิ่มvectorDrawables.useSupportLibrary = trueเข้าไปในdefaultConfigส่วนของไฟล์ build.gradle ของคุณ ผ่านการทดสอบแล้วว่าทำงานได้ดีกับตัวจำลอง Kitkat
นักพัฒนา android

3

อย่าใช้PoterDuff.Modeใช้setColorFilter()มันใช้ได้กับทุกคน

ImageView imageView = (ImageView) listItem.findViewById(R.id.imageView);
imageView.setColorFilter(getContext().getResources().getColor(R.color.msg_read));

2

ตามที่ @milosmns กล่าวว่าคุณควรใช้ imageView.setColorFilter(getResouces().getColor(R.color.blue),android.graphics.PorterDuff.Mode.MULTIPLY);

API นี้ต้องการค่าสีแทนรหัสทรัพยากรสีนั่นคือสาเหตุที่ทำให้คำสั่งของคุณใช้งานไม่ได้


2

ฉันไปงานปาร์ตี้สาย แต่ฉันไม่เห็นคำสันโดษข้างต้น เราสามารถตั้งค่าสีอ่อนsetImageResource()ๆ ได้เช่นกัน (minSdkVersion ของฉันคือ 24)

ดังนั้นก่อนอื่นคุณต้องสร้างตัวเลือกและบันทึกลงใน/drawableโฟลเดอร์ทรัพย์สิน (ฉันเรียกมันว่าic_color_white_green_search.xml)

<!-- Focused and not pressed -->
<item android:state_focused="true"
      android:state_pressed="false">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Focused and pressed -->
<item android:state_focused="true"
      android:state_pressed="true">

    <bitmap android:src="@drawable/ic_search"
            android:tint="@color/branding_green"/>
</item>

<!-- Default -->
<item android:drawable="@drawable/ic_search"/>

จากนั้นตั้งเป็นรหัสดังนี้:

val icon = itemView.findViewById(R.id.icon) as ImageButton
icon.setImageResource(R.drawable.ic_color_white_green_search)

2

ในกรณีที่คุณต้องการตั้งค่าตัวเลือกเป็นโทนสีของคุณ:

ImageViewCompat.setImageTintList(iv, getResources().getColorStateList(R.color.app_icon_click_color));

0

วิธีแก้ปัญหา Kotlin โดยใช้ฟังก์ชันส่วนขยายเพื่อตั้งค่าและยกเลิกการตั้งค่าการย้อมสี:

fun ImageView.setTint(@ColorInt color: Int?) {
    if (color == null) {
        ImageViewCompat.setImageTintList(this, null)
        return
    }
    ImageViewCompat.setImageTintMode(this, PorterDuff.Mode.SRC_ATOP)
    ImageViewCompat.setImageTintList(this, ColorStateList.valueOf(color))
}

-4

ไม่ใช่คำตอบที่แน่นอน แต่เป็นทางเลือกที่ง่ายกว่า:

  • วางมุมมองอื่นที่ด้านบนของภาพ
  • เปลี่ยนค่าอัลฟาของมุมมองตามที่คุณต้องการ (โดยทางโปรแกรม) เพื่อให้ได้เอฟเฟกต์ที่ต้องการ

นี่คือตัวอย่างสำหรับ:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:contentDescription="@string/my_description"
        android:scaleType="fitXY"
        android:src="@drawable/my_awesome_image"/>

    <View
        android:layout_width="match_parent"
        android:layout_height="@dimen/height120"
        android:alpha="0.5"
        android:background="@color/my_blue_color"/>
</FrameLayout>

นี่เป็นสีอ่อน ๆ ! ไม่ใช่อัลฟาสำหรับความโปร่งใส
เดวิด

แต่ท้ายที่สุดก็กลายเป็นสีอ่อน คุณควรลองด้วยตัวเอง นี่เป็นเพียงวิธีหนึ่งในการดูสิ่งต่าง ๆ
Shubham Chaudhary

@ShubhamChaudhary ฉันรู้ว่ามันมาช้า แต่ถ้าเป็นภาพpngล่ะ ถ้าเช่นนั้นพื้นหลังจะไม่เปลี่ยนแปลงใช่ไหม นอกจากนี้อัลฟ่าและสีอ่อนแตกต่างกันมาก สีอ่อนเหมือนการเปลี่ยนสีถ้าฉันไม่ผิด ไม่มีเจตนากระทำความผิด แค่พยายามช่วย :)
KISHORE_ZE

จุดที่ถูกต้อง คำตอบนี้ช่วยในกรณีของฉัน หวังว่าพอดีกับรองเท้าของคนอื่นด้วย
Shubham Chaudhary
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.