Android getResource (). GetDrawable () không dùng API 22


699

Với API Android 22 mới getResources().getDrawable()hiện không được chấp nhận. Bây giờ cách tiếp cận tốt nhất là chỉ sử dụng getDrawable().

Những gì đã thay đổi?


Bạn có thể chỉ định câu hỏi của bạn? Đúng là phương thức getDrawable (int id)của lớp Resourcesbị phản đối. Bây giờ bạn nên sử dụng phương thức getDrawable (int id, Resources.Theme theme)với tham số chủ đề mới.
mã khỉ

1
ContextCompat.getDrawable (bối cảnh, R.color.color_name)
Ashokchakravarthi Nagarajan

Bạn có thể kiểm tra bài viết trên blog của tôi về chủ đề này để được giải thích kỹ hơn về lý do tại sao cả hai Resources#getDrawable(int)Resources#getColor(int)đều không được chấp nhận.
Alex Lockwood

1
Google nên đặt các bản sửa lỗi nhanh cho từng chức năng không dùng nữa. Tôi đã tạo một bài đăng về nó ở đây: code.google.com/p/android/issues/detail?id=219495
nhà phát triển Android

Câu trả lời:


1027

Bạn có một số tùy chọn để xử lý sự phản đối này theo cách đúng (và bằng chứng trong tương lai ), tùy thuộc vào loại bạn có thể rút được:


A) drawable với thuộc tính chủ đề

ContextCompat.getDrawable(getActivity(), R.drawable.name);

Bạn sẽ có được một Drawable theo kiểu như chủ đề Hoạt động của bạn hướng dẫn. Đây có lẽ là những gì bạn cần.


B) drawable không có thuộc tính chủ đề

ResourcesCompat.getDrawable(getResources(), R.drawable.name, null);

Bạn sẽ có được drawable unstyled của bạn theo cách cũ. Hãy lưu ý: ResourcesCompat.getDrawable()không bị phản đối!


EXTRA) có thể vẽ với các thuộc tính chủ đề từ chủ đề khác

ResourcesCompat.getDrawable(getResources(), R.drawable.name, anotherTheme);

Ứng dụng của tôi gặp sự cố khi sử dụng đề xuất B. Nó không giống như cuộc gọi Drawable originalIcon = ResourcesCompat.getDrawable (ctxt.getResource (), iconResId, null);
FractalBob

Tôi khai báo theo cách này: void static void setImageButtonEnabled (Ngữ cảnh ctxt, bật boolean, mục ImageButton, int iconResId) {item.setEnatted (enable); Drawable gốcIcon = ResourcesCompat.getDrawable (ctxt.getResource (), iconResId, null); Biểu tượng có thể vẽ = kích hoạt? gốcIcon: convertDrawableToGrayScale (originalIcon); item.setImageDrawable (biểu tượng); } và gọi nó như thế này: Utility.setImageButtonEnables (getContext (), false, back, R.drawable.arrow_left);
FractalBob

Chính xác hơn, sự cố dường như đang xảy ra vì biểu tượng của tôi là một Vector có thể vẽ được.
FractalBob

1
phiên bản xamarin: ResourcesCompat.GetDrawable (Tài nguyên, Resource.Drawable.name, null);
Brian

Tôi thêm một từ nữa cho bạn , ContextCompat.getColor (bối cảnh, màu sắc) cũng có thể giúp bạn ...
BertKing

746

Chỉnh sửa: xem bài đăng trên blog của tôi về chủ đề này để được giải thích đầy đủ hơn


Bạn nên sử dụng mã sau đây từ thư viện hỗ trợ thay thế:

ContextCompat.getDrawable(context, R.drawable.***)

Sử dụng phương pháp này tương đương với việc gọi:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    return resources.getDrawable(id, context.getTheme());
} else {
    return resources.getDrawable(id);
}

Kể từ API 21, bạn nên sử dụng getDrawable(int, Theme)phương thức thay vì getDrawable(int), vì nó cho phép bạn tìm nạp một đối tượng có thể vẽ được liên kết với ID tài nguyên cụ thể cho mật độ / chủ đề màn hình cụ thể. Gọi getDrawable(int)phương thức không dùng nữa tương đương với gọi getDrawable(int, null).


8
Tôi nghĩ rằng OP cũng đề cập đến getDrawable (int id)phương pháp của Contextlớp. Điều này giống như getResources().getDrawable(id, getTheme());và cũng sử dụng API mới.
mã khỉ

9
Theo tài liệu, API tối thiểu cấp 21 là bắt buộc để sử dụng getDrawable(int, Resources.Theme).
Hoàng tử

@Prince Phương thức này đã được thêm vào API 21 nhưng nó không được dùng nữa cho đến API 22. :)
Alex Lockwood

Tài liệu Android cũng khuyên bạn nên sử dụng phương thức Context :: getDrawable (int) nhưng vì nó chỉ được giới thiệu trong API 21 nên dường như ContextCompat là lựa chọn tốt nhất.
goRGon

Câu trả lời này không hoạt động với các tệp .svg, trong các phiên bản cũ hơn API 21. Có một lỗi trong thư viện.
Jorge Rodríguez

141

Thay thế dòng này: getResources().getDrawable(R.drawable.your_drawable)

với ResourcesCompat.getDrawable(getResources(), R.drawable.your_drawable, null)

BIÊN TẬP

ResourcesCompatbây giờ cũng không được chấp nhận Nhưng bạn có thể sử dụng điều này:

ContextCompat.getDrawable(this, R.drawable.your_drawable)(Đây thislà bối cảnh)

để biết thêm chi tiết theo liên kết này: ContextCompat


2
Điều đó cũng được mô tả ngay bây giờ: plus.google.com/+Benjaminweiss/posts/M1dYFaobyBM
Xyaren


2
Nó không nói trong liên kết đó ResourcesCompatbị phản đối. Nó sẽ hoạt động tốt.
Jacob R

phải viết gì trong "your drawable" nếu tôi muốn nhập hình ảnh vào chế độ xem danh sách khi nhấp vào danh sách các mục được lưu trữ trong drawable
0x0001

29

getResources().getDrawable() đã bị phản đối ở cấp độ API 22. Bây giờ chúng ta phải thêm chủ đề:

getDrawable (int id, tài nguyên.Theme theme) (Đã thêm vào API cấp 21)

Đây là một ví dụ:

myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));

Đây là một ví dụ về cách xác nhận cho các phiên bản sau:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage, getApplicationContext().getTheme()));
   } else { 
     myImgView.setImageDrawable(getResources().getDrawable(R.drawable.myimage));
}

Build.VERSION_CODES.LOLLIPOP is API 21Vì vậy, điều này không nên if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1)hay if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP)? Đừng bận tâm. Từ bên dưới "Phương thức đã được thêm vào API 21 nhưng nó không bị phản đối cho đến API 22. :)"
Đánh dấu Cramer

2

Bạn có thể dùng

ContextCompat.getDrawable(getApplicationContext(),R.drawable.example);

đó là công việc cho tôi


Sử dụng bối cảnh ứng dụng để tải các sự cố có thể vẽ vector trên kẹo mút trước. Bất kỳ sửa chữa cho điều này?
muthuraj

1
@muthuraj Tôi không nhớ thử nghiệm mã của mình với trường hợp kẹo mút, nhưng bạn có thể thử getActivity () hoặc getResource () thay vào đó, điều đó có phù hợp với mã của bạn không?
Dasser Basyouni

Tôi đang sử dụng mẫu MVVM và tôi cần tăng các drawable bên trong ViewModels không có ngữ cảnh hoạt động. Nó chỉ có bối cảnh ứng dụng. Đó là vấn đề của tôi.
muthuraj

1

Chỉ là một ví dụ về cách tôi khắc phục sự cố trong một mảng để tải listView, hy vọng nó có ích.

 mItems = new ArrayList<ListViewItem>();
//    Resources resources = getResources();

//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.az_lgo), getString(R.string.st_az), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.ca_lgo), getString(R.string.st_ca), getString(R.string.all_nums)));
//    mItems.add(new ListViewItem(resources.getDrawable(R.drawable.co_lgo), getString(R.string.st_co), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.az_lgo, null), getString(R.string.st_az), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.ca_lgo, null), getString(R.string.st_ca), getString(R.string.all_nums)));
    mItems.add(new ListViewItem(ResourcesCompat.getDrawable(getResources(), R.drawable.co_lgo, null), getString(R.string.st_co), getString(R.string.all_nums)));

1

Thử cái này:

public static List<ProductActivity> getCatalog(Resources res){
    if(catalog == null) {
        catalog.add(new Product("Dead or Alive", res
                .getDrawable(R.drawable.product_salmon),
                "Dead or Alive by Tom Clancy with Grant Blackwood", 29.99));
        catalog.add(new Product("Switch", res
                .getDrawable(R.drawable.switchbook),
                "Switch by Chip Heath and Dan Heath", 24.99));
        catalog.add(new Product("Watchmen", res
                .getDrawable(R.drawable.watchmen),
                "Watchmen by Alan Moore and Dave Gibbons", 14.99));
    }
}

Mặc dù mã này có thể trả lời câu hỏi, cung cấp ngữ cảnh bổ sung về lý do và / hoặc cách mã này trả lời câu hỏi cải thiện giá trị lâu dài của nó.
Vịt Donald

1

Nếu bạn đang nhắm mục tiêu SDK> 21 (kẹo mút hoặc 5.0), hãy sử dụng

context.getDrawable(R.drawable.your_drawable_name)

Xem tài liệu


1

getDrawable (int drawable) không được dùng ở cấp API 22. Để tham khảo xem liên kết này .

Bây giờ để giải quyết vấn đề này, chúng ta phải vượt qua một trình xây dựng mới cùng với id như: -

getDrawable(int id, Resources.Theme theme)

Đối với giải pháp Làm như thế này: -

Trong Java: -

ContextCompat.getDrawable(getActivity(), R.drawable.name);   

hoặc là

 imgProfile.setImageDrawable(getResources().getDrawable(R.drawable.img_prof, getApplicationContext().getTheme()));

Trong Kotlin: -

rel_week.background=ContextCompat.getDrawable(this.requireContext(), R.color.colorWhite)

hoặc là

 rel_day.background=resources.getDrawable(R.drawable.ic_home, context?.theme)

Hy vọng điều này sẽ giúp bạn. Cảm ơn.


Điều đáng nói, getDrawable (DrawableRes int id, Theme theme) có thể đưa ra một ngoại lệ nếu tài nguyên không được tìm thấy trong khi, getDrawable (Ngữ cảnh ngữ cảnh, int id) là nullable, vì vậy nó có phải được trả về với Drawable không? trong Kotlin.
Pitos

0

en api cấp 14

marker.setIcon(ResourcesCompat.getDrawable(getResources(), R.drawable.miubicacion, null));

Bạn nên cung cấp thêm một chút bối cảnh xung quanh câu trả lời của bạn.
Nicolas Grenié

0

Bây giờ bạn cần thực hiện như thế này

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { //>= API 21
        //
    } else {
        //
    }

Theo sau một dòng mã là đủ, mọi thứ sẽ được ContextCompat.getDrawable chăm sóc

ContextCompat.getDrawable(this, R.drawable.your_drawable_file)

0

Đối với một số người vẫn giải quyết được vấn đề này ngay cả sau khi áp dụng đề xuất của chủ đề này (tôi đã từng là một người như vậy), hãy thêm dòng này vào lớp Ứng dụng của bạn, phương thức onCreate ()

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)

Như được đề xuất ở đâyở đây đôi khi điều này là bắt buộc để truy cập vectơ từ các tài nguyên, đặc biệt là khi bạn đang xử lý các mục menu, v.v.


0

Trong Kotlin, bạn có thể sử dụng tiện ích mở rộng

fun Context.getMyDrawable(id : Int) : Drawable?{

    return  ContextCompat.getDrawable(this, id)
}

sau đó sử dụng như

context.getMyDrawable(R.drawable.my_icon)

-2

Build.VERSION_CODES.LOLLIPOP nên được thay đổi thành BuildVersionCodes.Leets tức là:

if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop) {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder, Context.Theme);
} else {
    this.Control.Background = this.Resources.GetDrawable(Resource.Drawable.AddBorder);
}

Không phải là BuildVersionCodesmột lớp học cụ thể cho Xamarin?
Ted Hopp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.