รับ color-int จากแหล่งข้อมูลสี


448

มีวิธีรับ color-int จากแหล่งข้อมูลสีหรือไม่? ฉันพยายามรับส่วนประกอบสีแดงสีน้ำเงินและสีเขียวของสีที่กำหนดไว้ในทรัพยากร (R.color.myColor) เพื่อให้ฉันสามารถตั้งค่าของแถบค้นหาสามระดับเป็นระดับที่เฉพาะเจาะจง

คำตอบ:


928

คุณสามารถใช้ได้:

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

ตรวจสอบที่นี่เกี่ยวกับวิธีกำหนดสีที่กำหนดเอง:

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

แก้ไข (1): นับตั้งแต่getColor(int id)มีการเลิกใช้ตอนนี้จะต้องถูกนำมาใช้:

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

(เพิ่มในห้องสมุดสนับสนุน 23)

แก้ไข (2):

โค้ดด้านล่างสามารถใช้ได้ทั้งก่อนและโพสต์ Marshmallow (API 23)

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

ResourcesCompat.getColor(getResources(), R.color.your_color, your_theme); //with theme

7
เกี่ยวกับ android.R.color.some_color :-(
Blundell

17
@ Blundell uhh, dunno หากคุณต้องการตอนนี้ แต่มันก็ใช้งานได้android.R.color.some_colorเช่นกัน: getResources().getColor(android.R.color.holo_blue_bright)(อย่างน้อย, บน API 17)
ataulm

30
getColor () เลิกใช้แล้วในตอนนี้คุณสามารถใช้: ContextCompat.getColor (บริบท, R.color.your_color);
Ricardo

2
ฉันรู้ว่าคุณไม่ใช่คนที่ทำการแก้ไข แต่อะไรคือความแตกต่างระหว่างContextCompatและResourcesCompat? หากไม่มีความแตกต่างในทางปฏิบัติมันจะสับสนน้อยกว่าหากคุณลบหนึ่งในนั้นออกจากคำตอบของคุณ
Suragch

14
เหตุใด Google จึงรู้สึกว่าจำเป็นต้องเลิกใช้งานฟังก์ชั่นที่ดีอย่างสมบูรณ์แบบสำหรับห้องสมุดขนาดกะทัดรัดของแอปที่น่ากลัว มันแย่มีทั้งคู่
Andrew S

116

อ้างอิงไลบรารีสนับสนุน Androidใหม่(และอัปเดตนี้ ) ตอนนี้คุณควรโทร:

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

ตามเอกสาร :

public int getColor (int id)

วิธีการนี้ถูกคัดค้านในAPI ระดับ 23 ใช้ getColor (int, Theme) แทน

มันเป็นทางออกเดียวกันสำหรับgetResources().getColorStateList(id):

คุณต้องเปลี่ยนเป็นดังนี้:

ContextCompat.getColorStateList(getContext(),id);

แก้ไข 2019

เกี่ยวกับการThemeOverlayใช้บริบทของมุมมองที่ใกล้เคียงที่สุด:

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

ด้วยวิธีนี้คุณจะได้สีที่ถูกต้องตาม ThemeOverlay ของคุณ

จำเป็นเป็นพิเศษเมื่ออยู่ในกิจกรรมเดียวกันคุณใช้ชุดรูปแบบที่แตกต่างกันเช่นชุดรูปแบบสีเข้ม / สีอ่อน หากคุณต้องการทำความเข้าใจเพิ่มเติมเกี่ยวกับชุดรูปแบบและลักษณะการพูดคุยนี้ขอแนะนำ: การพัฒนาชุดรูปแบบที่มีสไตล์

Nick Butcher - Droidcon Berlin - การพัฒนาธีมด้วยสไตล์


10
สำหรับผู้ที่สงสัยว่าจะเติมธีมในวิธีการใหม่Themeสามารถส่งเป็นโมฆะได้ดังนั้นให้โทรgetColor(R.color.my_color, null)ถ้าคุณไม่แน่ใจว่าจะส่งธีมอะไรให้เป็นของคุณ
w3bshark

อืม ... นี่คือสิ่งที่ทุกคนพูด แต่ฉันไม่สามารถทำงานได้ ฉันต้องเริ่มต้นบริบทหรือไม่ ขณะนี้ฉันได้รับ "ไม่สามารถแก้ไขสัญลักษณ์ 'บริบท'"
ColdTuna

เพื่อให้แน่ใจว่าคุณทำถูกต้องลองโทรไปที่ onCreate ของกิจกรรมแทนที่จะรับบริบทคุณต้องโทรหา getContext () หรือแค่ "this"
Ultimo_m

35

กำหนดสีของคุณ

ค่า / 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>

รับค่าสีและตั้งค่า

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);

ดูสิ่งนี้ด้วย


1
คุณสามารถใช้เฉพาะgetResources()ในActivityหรือFragment?
Zapnologica

2
@Zapnologica ดูคำตอบสำหรับคำถามนี้สำหรับความคิดเกี่ยวกับการใช้getResources()นอกกิจกรรมหรือส่วน
Suragch

1
@Zapnologica no getResources()นอกจากนี้ยังมีให้บริการในรูปแบบ API สาธารณะในทุกสิ่งที่ใช้บริบทและใน Views
ataulm

7

วิธีการที่ดีที่สุด

ในฐานะที่เป็น @sat คำตอบวิธีที่ดีสำหรับการรับสีคือ

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

หรือใช้วิธีด้านล่างเมื่อคุณไม่สามารถเข้าถึงgetResources()วิธีการ

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

สิ่งที่ฉันทำคือ

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

มันใช้งานง่ายที่สุดในแอพของคุณ! แม้แต่ในชั้น Util หรือคลาสที่คุณไม่มี Context หรือ getResource ()

ปัญหา (เมื่อคุณไม่มีบริบท)

เมื่อคุณไม่Contextสามารถเข้าถึงได้เช่นเดียวกับวิธีการในUtilชั้นเรียนของคุณ

สมมติวิธีด้านล่างโดยไม่มีบริบท

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

ตอนนี้คุณจะผ่านContextเป็นพารามิเตอร์ในวิธีนี้และใช้getResources().

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

ดังนั้นนี่คือโบนัสที่ไม่ซ้ำกันแก้ปัญหาUtil classโดยที่คุณสามารถเข้าถึงแหล่งข้อมูลได้จากทุกที่เช่น เพิ่มResourcesในApplicationชั้นเรียนของคุณหรือสร้างถ้าไม่มี

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;
    }

}

เพิ่มฟิลด์ชื่อในmanifest.xml <applicationแท็กของคุณ (ถ้ายังไม่ได้เพิ่ม)

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

ตอนนี้คุณก็พร้อมแล้ว ใช้งานResourcesCompat.getColor(App.getRes(), R.color.your_color, null);ได้ทุกที่ในแอป


5

ฉันอัปเดตให้ใช้ContextCompat.getColor(context, R.color.your_color);แต่บางครั้ง (ในอุปกรณ์ / Android บางรุ่นฉันไม่แน่ใจ) ที่ทำให้ NullPointerExcepiton

ดังนั้นเพื่อให้มันใช้งานได้กับอุปกรณ์ / รุ่นทั้งหมดฉันถอยกลับไปตามวิธีเดิมในกรณีของตัวชี้โมฆะ

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));
    }
}

ทำไมไม่ใช้เวอร์ชั่นเก่าในทุกกรณีหรือหากคุณกำลังตรวจสอบเวอร์ชั่นอยู่ให้ใช้ API ใหม่Resources.getColor(int, Theme)ถ้าทำได้ คุณไม่ควรตรวจพบข้อยกเว้นขณะใช้งานจริง
ataulm

แค่ OCD ฉันคิดว่า ContextCompat สำหรับฉันดูเหมือนว่าจะเป็นวิธีการพิสูจน์ในอนาคตของการทำมันและดังนั้นจึงเป็นวิธีที่เหมาะสม ดังนั้นแนวทางของฉันคือทำในสิ่งที่ถูกต้อง และถ้าสิ่งนั้นล้มเหลว (บนอุปกรณ์เก่าหรืออะไรก็ตาม) ให้ทำแบบเดิม เหตุใดฉันจึงไม่ควรตรวจพบข้อยกเว้นขณะใช้งานจริง
ninjachippie

1

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับกรณีการใช้งานอื่นที่อาจช่วยตอบคำถามนี้ในผลการค้นหาฉันต้องการใช้อัลฟากับสีที่กำหนดไว้ในแหล่งข้อมูลของฉัน

ใช้คำตอบที่ถูกต้องของ @ 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)
);

1

พบวิธีที่ใช้งานได้ง่ายขึ้นเช่นกัน:

Color.parseColor(getString(R.color.idname);

น่าสนใจไม่รู้ว่าคุณจะได้สีเป็นสตริงด้วยวิธีนี้ ฉันไม่คิดว่ามันง่ายขึ้น แต่น่าสนใจ😅
ataulm

0

การเข้าถึงสีจากคลาสที่ไม่ใช่กิจกรรมอาจทำได้ยาก enumหนึ่งในทางเลือกที่ผมพบว่าใช้ enumมีความยืดหยุ่นมาก

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;
  }
}


0

หากนาทีปัจจุบันของคุณ ระดับ API คือ 23 คุณสามารถใช้getColor()เหมือนกับที่เราใช้สำหรับgetString():

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

หากคุณต้องการระดับ API ต่ำกว่านี้23ให้ใช้:

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

แต่ทราบว่าจะเลิกในระดับgetResources().getColor() API 23ในกรณีนั้นให้แทนที่ด้วย:

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

ContextCompat : ตัวช่วยสำหรับการเข้าถึงคุณลักษณะในContext

หากคุณต้องการคุณสามารถ จำกัด ด้วยSDK_INTเช่นด้านล่าง:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    textView.setTextColor(getColor(R.color.green));
} else {
    textView.setTextColor(getResources().getColor(R.color.green));
}

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

ในกิจกรรม

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

ในส่วน

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

ตัวอย่างเช่น:

tvsun.settextcolour(ContextCompat.getColor(getActivity(), R.color.your_color))
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.