การย้อมสีที่วาดได้สำหรับ api <21


84

เป็นไปได้ไหมที่จะทำการย้อมสีแบบวาดได้สำหรับ api <21

<bitmap
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary" />

ใช้งานได้ดี แต่สำหรับอุปกรณ์ที่มี API21 เท่านั้น วิธีแก้ปัญหาใด ๆ สำหรับอุปกรณ์ API ที่ต่ำกว่าหรือการสนับสนุน AppCompat? ไม่พบอะไร.

คำตอบ:


106

ใช้สิ่งAppCompatImageViewนี้:

<android.support.v7.widget.AppCompatImageView
        android:id="@+id/my_appcompat_imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/my_image"
        android:tint="#636363"
    />

ตรวจสอบให้แน่ใจว่าคุณมีล่าสุดในแอปของคุณappcompat-v7build.gradle

ตัวอย่าง: compile 'com.android.support:appcompat-v7:25.0.0'ในแอปของbuild.gradleคุณ


66
จากAppCompatImageViewdocs: This will automatically be used when you use ImageView in your layouts. You should only need to manually use this class when writing custom views. developer.android.com/reference/android/support/v7/widget/…ดังนั้นการใช้ปกติImageViewในเค้าโครงก็น่าจะใช้ได้ดี
Nimrod Dayan

1
ตามที่ @NimrodDayan ได้กล่าวไว้ข้างต้นนี้ไม่จำเป็น ฉันได้รับรายงานเกี่ยวกับ Android: สีไม่ทำงานบน Samsung A5 และ Moto G อย่างไรก็ตาม (ใช้ appcompat-v7: 23.4.0) ดังนั้นจึงเป็นไปได้ว่า ImageViews จะไม่ถูกแทนที่อย่างถูกต้องในอุปกรณ์บางอย่าง
Stephen Kidson

@StephenKidson ฉันใช้ appcompat เวอร์ชันเดียวกันและพบปัญหาเดียวกันกับอุปกรณ์ยี่ห้อที่ไม่รู้จัก คุณจัดการเพื่อแก้ปัญหานี้หรือไม่? ฉันสงสัยว่ามีรายงานข้อผิดพลาดเกี่ยวกับเรื่องนี้หรือไม่ ...
Nimrod Dayan

4
สิ่งนี้ใช้ไม่ได้กับโปรแกรมจำลอง Android 4.0 ที่ใช้ appcompat-v7: 25.1.0
Peterdk

4
ไม่สามารถใช้ AppCompatImageView ภายในวิดเจ็ต ใช้ setColorFilter บน ImageView
Massimo

46

คุณสามารถทำได้โดยใช้ซอร์สโค้ด DrawableCompatก่อนหน้านี้ย้อมสีก็ไม่ได้รับการสนับสนุนโดย เริ่มจากไลบรารีสนับสนุน 22.1 คุณสามารถทำได้ แต่คุณต้องทำด้วยวิธีนี้:

Drawable normalDrawable = getResources().getDrawable(R.drawable.drawable_to_tint);
Drawable wrapDrawable = DrawableCompat.wrap(normalDrawable);
DrawableCompat.setTint(wrapDrawable, getResources().getColor(R.color.colorPrimaryLight));

18
หากคุณต้องการรองรับการย้อมสีบน <21 APIs คุณอาจต้องการใช้ContextCompat.getColor()แทนgetResources().getColor().
Sevastyan Savanyuk

22

คุณไม่สามารถใช้ ImageView เพื่อแสดง Drawable ของคุณได้หรือ? android:tintทำงานได้ดีในระดับ API ที่เก่ากว่า

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/ic_calendar"
    android:tint="@color/primary"
    />

2
ฉันใช้ ImageView - เพื่อแสดงไอคอนในนั้น ไอคอนเหล่านั้นเป็นส่วนหนึ่งขององค์ประกอบในลิ้นชักการนำทางของฉัน และรายการที่เลือกในลิ้นชักการนำทางมีสีที่แตกต่างกันฉันจึงสร้างแต่ละไอคอนที่ย้อมสีและยังเลือกสำหรับแต่ละไอคอน และฉันกำลังใช้ตัวเลือกนั้นสำหรับไอคอนของฉัน ตัวเลือก:<selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_activated="true" android:drawable="@drawable/ic_home_tinted" /> <item android:drawable="@drawable/ic_home" /> </selector>
MaTT ถึง

@Orochi ดูคำตอบของฉันเพราะมาจากบล็อกของ Google โดยตรง ส่วนใหญ่ใช้งานได้บน Android 5.0+ เป็นหลัก แต่อาจใช้งานได้กับวิดเจ็ตบางอย่างสำหรับอุปกรณ์ที่ใช้ Android 5.0 ก่อน
Jared Burrows

@Orochi คุณจะต้องสร้างมุมมองแบบกำหนดเองเพื่อ "เลียนแบบ" เอฟเฟกต์เดียวกัน
Jared Burrows

1
คุณสามารถใช้มุมมองภาพทำให้ไอคอนเป็นสีขาวที่สุดและทำให้เป็นสีใดก็ได้ที่คุณต้องการด้วย iv.setColorFilter (yourColor, Mode.Multiply); ตรวจสอบว่าคุณนำเข้า android.graphics.PorterDuff.Mode
jb15613

3
ปัญหาเดียวกันที่นี่ น่าเสียดายที่สีที่มีตัวเลือกใช้ไม่ได้กับ api <21
Luccas

17

มีการถามคำถามที่คล้ายกันมาก่อนที่นี่: https://stackoverflow.com/a/26533340/950427

Android Drawable Tinting รองรับใน Android 5.0+ (API 21+) เท่านั้น (มันพูดว่า " At the moment this is limited to coloring the action bar and some widgets.")

ธีม

...

เมื่อคุณตั้งค่าแอ็ตทริบิวต์เหล่านี้ AppCompat จะเผยแพร่ค่าโดยอัตโนมัติไปยังแอ็ตทริบิวต์เฟรมเวิร์กบน API 21+ การทำเช่นนี้จะทำให้แถบสถานะและรายการงานภาพรวม (ล่าสุด) เป็นสีโดยอัตโนมัติ

บนแพลตฟอร์มรุ่นเก่า AppCompat จะเลียนแบบชุดสีหากเป็นไปได้ ในขณะนี้ จำกัด เฉพาะการระบายสีแถบการกระทำและวิดเจ็ตบางส่วน

และ

การย้อมสีวิดเจ็ต

เมื่อทำงานบนอุปกรณ์ที่ใช้ Android 5.0 วิดเจ็ตทั้งหมดจะถูกย้อมสีโดยใช้คุณลักษณะของธีมสีที่เราเพิ่งพูดถึง มีคุณสมบัติหลักสองประการที่อนุญาตให้ใช้กับ Lollipop: การย้อมสีแบบวาดได้และการอ้างอิงแอตทริบิวต์ของธีม (ของรูปแบบ? attr / foo) ในแบบ drawables

AppCompat มีลักษณะการทำงานที่คล้ายกันใน Android เวอร์ชันก่อนหน้าสำหรับส่วนย่อยของวิดเจ็ต UI:

ทุกสิ่งที่มีให้โดยแถบเครื่องมือของ AppCompat (โหมดการทำงาน ฯลฯ ) EditText Spinner CheckBox RadioButton Switch (ใช้ android.support.v7.widget.SwitchCompat ใหม่) CheckedTextView คุณไม่จำเป็นต้องทำอะไรเป็นพิเศษเพื่อให้ทำงานเหล่านี้ได้เพียงใช้การควบคุมเหล่านี้ใน เลย์เอาต์ของคุณตามปกติและ AppCompat จะจัดการส่วนที่เหลือให้ (มีข้อแม้ดูคำถามที่พบบ่อยด้านล่าง)

แหล่งที่มา:

http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html

https://chris.banes.me/2014/10/17/appcompat-v21/


เหตุใดจึงถูกลดลง นี่มาจากเอกสารอย่างเป็นทางการ
Jared Burrows

คำตอบล้าสมัย ImageViewขณะนี้รองรับandroid:tintผ่าน AppCompat แล้วเช่นเดียวกับคำตอบของ @Jonik
Vicky Chijwani

@VickyChijwani ส่งการแก้ไข และคุณหมายถึงไม่ได้AppCompatImageView ImageView
Jared Burrows


6

สำหรับการย้อมสีภาพคุณสามารถimageView.setColorFilter(int color)ใช้ได้ สิ่งนี้ใช้ได้กับ API 8 และใช้สำหรับการย้อมสีภาพสีดำของฉันให้เป็นสีที่ฉันต้องการ สิ่งนี้สามารถแทนที่ได้setImageTintList()แต่เพียงแค่ใช้android:tintก็ควรใช้งานได้เช่นกัน


6

ใช้ NameSpace
xmlns นี้: app = "http://schemas.android.com/apk/res-auto"

และหลังจากที่คุณสามารถแทนที่ android: tint ด้วย app: tint วิธีนี้ช่วยแก้ปัญหาให้ฉันได้


4

ฉันมาสายนิดหน่อย แต่นี่คือวิธีการ

val textInput = EditText(context)

val drawable = ContextCompat.getDrawable(context, R.drawable.your_drawable)
drawable?.let {
    myDrawable -> DrawableCompat.setTint(myDrawable, ContextCompat.getColor(context, R.color.your_color))
    textInput.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, myDrawable, null)
}

1

สิ่งนี้จะทำตามที่คุณต้องการและควรใช้กับไลบรารีการสนับสนุน Android ทุกเวอร์ชัน:

@JvmStatic
fun getTintedDrawable(inputDrawable: Drawable, @ColorInt color: Int): Drawable {
    val wrapDrawable = DrawableCompat.wrap(inputDrawable.mutate())
    DrawableCompat.setTint(wrapDrawable, color)
    DrawableCompat.setTintMode(wrapDrawable, Mode.SRC_IN)
    return wrapDrawable
}

1

ถ้าใครอยากสร้าง drawable ใหม่ (tin1, tint2 .. ) ลองทำดู

<?xml version="1.0" encoding="utf-8"?>
<bitmap
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:src="@drawable/your_image"
  android:tint="@color/tint_color">
   </bitmap>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.