Dapatkan warna-int dari sumber daya warna

448

Apakah ada cara untuk mendapatkan int warna dari sumber daya warna? Saya mencoba untuk mendapatkan masing-masing komponen merah, biru, dan hijau dari warna yang ditentukan dalam sumber daya (R.color.myColor) sehingga saya dapat mengatur nilai tiga seekbars ke tingkat tertentu.

ataulm
sumber

Jawaban:

928

Kamu bisa menggunakan:

getResources().getColor(R.color.idname);

Lihat di sini tentang cara menentukan warna khusus:

http://sree.cc/google/android/defining-custom-colors-using-xml-in-android

EDIT (1): Karena getColor(int id)sudah usang sekarang, ini harus digunakan:

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

(ditambahkan di perpustakaan dukungan 23)

EDIT (2):

Kode di bawah ini dapat digunakan untuk pre dan post Marshmallow (API 23)

ResourcesCompat.getColor(getResources(), R.color.your_color, null); //without theme

ResourcesCompat.getColor(getResources(), R.color.your_color, your_theme); //with theme
duduk
sumber
7
bagaimana dengan android.R.color.some_color :-(
Blundell
17
@ Blundell uhh, tidak tahu jika Anda membutuhkannya sekarang tetapi ini berfungsi android.R.color.some_colorjuga misalnya: getResources().getColor(android.R.color.holo_blue_bright)(setidaknya, pada API 17)
ataulm
30
getColor () sekarang sudah tidak digunakan lagi, Anda dapat menggunakan: ContextCompat.getColor (konteks, R.color.your_color);
Ricardo
2
Saya menyadari bahwa Anda bukan orang yang melakukan pengeditan, tetapi apa perbedaan antara ContextCompatdan ResourcesCompat? Jika tidak ada perbedaan praktis, itu akan kurang membingungkan jika Anda menghapus salah satu dari mereka dari jawaban Anda.
Suragch
14
Mengapa Google merasa perlu untuk mencela fungsi yang sangat baik untuk pustaka aplikasi yang mengerikan itu. Ini menyebalkan, memiliki keduanya.
Andrew S
116

Berdasarkan Pustaka Dukungan Android yang baru (dan pembaruan ini ), sekarang Anda harus menelepon:

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

Menurut dokumentasi :

public int getColor (int id)

Metode ini sudah tidak digunakan lagi di API level 23 . Gunakan getColor (int, Theme) sebagai gantinya

Ini adalah solusi yang sama untuk getResources().getColorStateList(id):

Anda harus mengubahnya seperti ini:

ContextCompat.getColorStateList(getContext(),id);

EDIT 2019

Mengenai ThemeOverlaypenggunaan konteks tampilan terdekat:

val color = ContextCompat.getColor(
  closestView.context,
  R.color.name.color
)

Jadi dengan cara ini Anda mendapatkan warna yang tepat berdasarkan ThemeOverlay Anda.

Dibutuhkan khusus ketika dalam aktivitas yang sama Anda menggunakan tema yang berbeda, seperti tema gelap / terang. Jika Anda ingin lebih memahami tentang Tema dan Gaya, pembicaraan ini disarankan: Mengembangkan Tema dengan Gaya

Nick Butcher - Droidcon Berlin - Mengembangkan Tema dengan Gaya

Ultimo_m
sumber
10
Bagi mereka yang ingin tahu apa yang harus diisi sebagai tema dalam metode baru, Themedapat dinyatakan sebagai nol, jadi panggil saja getColor(R.color.my_color, null)jika Anda tidak yakin tema apa yang harus dilewati.
w3bshark
hmm ... ini yang dikatakan semua orang tetapi saya tidak bisa membuatnya bekerja. Apakah saya harus menginisialisasi konteks? Saat ini saya mendapatkan "tidak dapat menyelesaikan simbol 'konteks'"
ColdTuna
Untuk memastikan bahwa Anda melakukannya dengan benar, coba panggil di dalam onCreate aktivitas, daripada untuk mendapatkan konteks Anda perlu memanggil getContext () atau hanya "ini"
Ultimo_m
35

Tentukan warna Anda

values ​​/ color.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- color int as #AARRGGBB (alpha, red, green, blue) -->
    <color name="orange">#fff3632b</color>
    ...
    <color name="my_view_color">@color/orange</color>

</resources>

Dapatkan int warna dan atur

int backgroundColor = ContextCompat.getColor(context, R.color.my_view_color);
// Color backgroundColor = ... (Don't do this. The color is just an int.)

myView.setBackgroundColor(backgroundColor);

Lihat juga

Suragch
sumber
1
bisakah Anda hanya menggunakan getResources()dalam Activityatau Fragment?
Zapnologica
2
@Zapnologica, lihat jawaban atas pertanyaan ini untuk pemikiran tentang penggunaan di getResources()luar Aktivitas atau Fragmen.
Suragch
1
@Zapnologica no. getResources()juga tersedia sebagai API publik tentang apa pun yang menerapkan Konteks dan juga pada Tampilan.
ataulm
7

Pendekatan Terbaik

Sebagai jawaban @sat, pendekatan yang baik untuk mendapatkan warna adalah

ResourcesCompat.getColor(getResources(), R.color.your_color, null);

atau gunakan cara di bawah ini ketika Anda tidak memiliki akses ke getResources()metode.

Context context  = getContext(); // like Dialog class
ResourcesCompat.getColor(context.getResources(), R.color.your_color, null);

Apa yang saya lakukan adalah

public void someMethod(){
    ...
    ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);
}

Ini paling mudah digunakan di mana saja di aplikasi Anda! Bahkan di kelas Util atau kelas mana pun di mana Anda tidak memiliki Konteks atau getResource ()

Masalah (Ketika Anda tidak memiliki Konteks)

Ketika Anda tidak memiliki Contextakses , sukai metode di Utilkelas Anda .

Asumsikan metode di bawah ini tanpa Konteks.

public void someMethod(){
    ...
    // can't use getResource() without Context.
}

Sekarang Anda akan lulus Contextsebagai parameter dalam metode ini dan gunakangetResources().

public void someMethod(Context context){
    ...
    context.getResources...
}

Jadi di sini adalah solusi unik Bonus di mana Anda dapat mengakses sumber daya dari mana saja seperti Util class. Tambahkan Resourceske Applicationkelas Anda atau Buat satu jika tidak ada.

import android.app.Application;
import android.content.res.Resources;

public class App extends Application {
    private static App mInstance;
    private static Resources res;


    @Override
    public void onCreate() {
        super.onCreate();
        mInstance = this;
        res = getResources();
    }

    public static App getInstance() {
        return mInstance;
    }

    public static Resources getResourses() {
        return res;
    }

}

Tambahkan bidang nama ke manifest.xml <applicationtag Anda . (Jika belum ditambahkan)

<application
        android:name=".App"
        ...
        >
        ...
    </application>

Sekarang kamu baik untuk pergi. Gunakan ResourcesCompat.getColor(App.getRes(), R.color.your_color, null);di mana saja di aplikasi.

Khemraj
sumber
5

Saya memperbarui untuk menggunakan ContextCompat.getColor(context, R.color.your_color);tetapi kadang-kadang (Pada beberapa perangkat / versi Android. Saya tidak yakin) yang menyebabkan NullPointerExcepiton.

Jadi untuk membuatnya bekerja pada semua perangkat / versi, saya kembali pada cara lama melakukannya, dalam kasus null pointer.

try {
    textView.setTextColor(ContextCompat.getColor(getActivity(), R.color.text_grey_dark));
}
catch(NullPointerException e) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        textView.setTextColor(getContext().getColor(R.color.text_grey_dark));
    }
    else {
        textView.setTextColor(getResources().getColor(R.color.text_grey_dark));
    }
}
ninjachippie
sumber
mengapa tidak menggunakan versi lama dalam semua kasus, atau jika Anda tetap memeriksa versi itu, gunakan API baru Resources.getColor(int, Theme)jika Anda bisa? Anda seharusnya tidak menangkap pengecualian runtime.
ataulm
Kurasa hanya OCD. ContextCompat, bagi saya tampaknya menjadi cara bukti di masa depan untuk melakukannya, dan karena itu cara yang benar. Jadi pendekatan saya adalah, lakukan dengan cara yang benar. Dan jika itu gagal (pada perangkat lama atau apa pun), lakukan dengan cara lama. Mengapa saya tidak harus menangkap pengecualian saat runtime?
ninjachippie
1

Untuk informasi lebih lanjut tentang penggunaan-kasus lain yang dapat membantu memunculkan pertanyaan ini dalam hasil pencarian, saya ingin menerapkan alpha ke warna yang didefinisikan dalam sumber daya saya.

Menggunakan jawaban yang benar @ sat:

int alpha = ... // 0-255, calculated based on some business logic
int actionBarBackground = getResources().getColor(R.color.actionBarBackground);
int actionBarBackgroundWithAlpha = Color.argb(
        alpha,
        Color.red(actionbarBackground),
        Color.green(actionbarBackground),
        Color.blue(actionbarBackground)
);
ataulm
sumber
1

Menemukan cara yang lebih mudah yang berfungsi juga:

Color.parseColor(getString(R.color.idname);
tokeklume
sumber
Menarik, tidak sadar Anda bisa mendapatkan warna sebagai string dengan cara ini. Saya pikir itu tidak mudah, tetapi ini menarik 😅
ataulm
0

Mengakses warna dari kelas non-aktivitas bisa jadi sulit. Salah satu alternatif yang saya temukan menggunakan enum. enummenawarkan banyak fleksibilitas.

public enum Colors
{
  COLOR0(0x26, 0x32, 0x38),    // R, G, B
  COLOR1(0xD8, 0x1B, 0x60),
  COLOR2(0xFF, 0xFF, 0x72),
  COLOR3(0x64, 0xDD, 0x17);


  private final int R;
  private final int G;
  private final int B;

  Colors(final int R, final int G, final int B)
  {
    this.R = R;
    this.G = G;
    this.B = B;
  }

  public int getColor()
  {
    return (R & 0xff) << 16 | (G & 0xff) << 8 | (B & 0xff);
  }

  public int getR()
  {
    return R;
  }

  public int getG()
  {
    return G;
  }

  public int getB()
  {
    return B;
  }
}
Membingungkan
sumber
0

Metode kerja terbaru:

getColor(R.color.snackBarAction)
zohaib Ansari
sumber
0

Jika min Anda saat ini. Level API 23, Anda cukup menggunakan getColor()seperti yang kami gunakan untuk getString():

//example
textView.setTextColor(getColor(R.color.green));
// if context is not available(ex: not in activity) use with context.getColor()

Jika Anda ingin di bawah level API 23, cukup gunakan ini:

textView.setTextColor(getResources().getColor(R.color.green));

Tetapi perhatikan bahwa getResources().getColor()sudah usang di Level API 23. Jika demikian ganti di atas dengan:

textView.setTextColor(ContextCompat.getColor(this /*context*/, R.color.green)) //Im in an activity, so I can use `this`

ContextCompat : Helper untuk mengakses fitur dalamContext

Jika Anda mau, Anda bisa membatasi dengan SDK_INTseperti di bawah ini:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}
Blasanka
sumber
0
ContextCompat.getColor(context, R.color.your_color);

dalam aktivitas

ContextCompat.getColor(actvityname.this, R.color.your_color);

dalam fragmen

ContextCompat.getColor(getActivity(), R.color.your_color);

sebagai contoh:

tvsun.settextcolour(ContextCompat.getColor(getActivity(), R.color.your_color))
indrajeet jyoti
sumber