VectorDrawables srcCompat를 사용하는 Android Selector Drawable
VectorDrawables와의 새로운 하위 호환성 문제에 직면 해 있습니다. 지원 라이브러리 23.2에는 Android VectorDrawables와의 하위 호환성을위한 새로운 기능이 도입되었습니다.
SelectorDrawable이 할당 된 ImageView가 있습니다. 이 Drawable에는 여러 VectorDrawable이 포함되어 있으므로 호환성을 위해 app : srcCompat를 사용해야한다고 생각했습니다. 그러나 Android 4.1.2가 설치된 Galaxy S2에서는 작동하지 않습니다.
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_gps_fixed_24dp"android:state_activated="true" android:state_selected="true"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="true" android:state_selected="false"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp" android:state_activated="false" android:state_selected="true"></item>
<item android:drawable="@drawable/ic_gps_off_24dp" android:state_activated="false" android:state_selected="false"></item>
<item android:drawable="@drawable/ic_gps_not_fixed_24dp"></item>
</selector>
모든 드로어 블은 벡터 xml 파일입니다.
이 SelectorDrawable을 srcCompat와 함께 사용할 때이 오류가 발생합니다.
Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ Caused by: android.content.res.Resources$NotFoundException: File res/drawable/ic_gps_fixed_24dp.xml from drawable resource ID #0x7f0201c1
at android.content.res.Resources.loadDrawable(Resources.java:1951)
at android.content.res.Resources.getDrawable(Resources.java:672)
at android.graphics.drawable.StateListDrawable.inflate(StateListDrawable.java:173)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:881).xml from drawable resource ID #0x7f0201c1
android : src를 사용하는 것은 더 나쁩니다.
app : srcCompat와 함께 벡터 드로어 블 중 하나를 사용하면 모두 잘 작동합니다. 그래서 나는 그것이 SelectorDrawable과 호환성의 문제라고 생각합니다.
누구든지 동일한 문제가 있었고 해결책을 찾았거나 현재 Android 5 이전의 SelectorDrawables에서 VectorDrawables를 사용할 수 없습니까?
요약 정보 :
- 타겟 API 컴파일 23
- Libraray 23.3.0 지원
- vectorDrawables.useSupportLibrary = true
- Gradle 2.0
이 질문을 한 이후로 몇 가지 사항이 변경되었으므로 직접 답변하겠습니다.
Support Library 23.4.0에서 Ressources의 VectorDrawables에 대한 지원이 다시 활성화되었습니다. Android 지원 라이브러리 23.4.0을 지금 사용할 수 있습니다.
Google I / O 2016 : 지원 라이브러리의 새로운 기능 -Google I / O 2016의이 캐스트에서 이에 대한 자세한 정보를 찾을 수 있습니다.
Android 5.0 (코드 명 Lollipop, API 레벨 21) 미만의 기기에서 VectorDrawables를 사용하려는 모든 활동에이를 추가해야합니다.
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
따라서 이제 DrawableContainers에서 VectorDrawables를 사용할 수 있지만 위의 소스에서 언급 한 것처럼 여전히 몇 가지 문제가 발생할 수 있으므로주의해서 사용하십시오.
지금까지 앱에서이 기능을 다시 활성화하지 않았지만 다음 주요 릴리스에서 많은 아이콘을 VectorDrawables로 변경 한 다음이 주제에 대해 자세히 살펴 보겠습니다.
@Jahnold가 질문에 대한 의견에서 언급했듯이 xml 상태 xml 목록에서 벡터 드로어 블을로드하는 지원은 23.3에서 제거되었습니다.
그러나 도움이 될 수있는 몇 가지 접근 방식을 찾았습니다.
1. 틴트 사용
이 접근 방식은 선택한 상태의 드로어 블이 색상별로 만 다른 경우에 적합합니다.
먼저 틴트와 흰색이있는 벡터 드로어 블을 하나만 만듭니다 fillColor
.
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tintMode="multiply"
android:tint="@color/button_tint">
<path
android:fillColor="#ffffff"
android:pathData="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
<path
android:pathData="M0 0h24v24H0z"/>
</vector>
둘째, 색상 상태 목록 button_tint.xml
을res/color
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#555555" android:state_enabled="false"/>
<item android:color="#6699dd"/>
</selector>
Don't forget add follow lines to build.gradle
or the approach will not work on old Android versions.
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
2. Hardcode creating StateListDrawable
The approach is suitable if you use for the state list vector drawables which difference not only a color but also by a figure so you need create several different xml files. Then you can create StateListDrawable
programmatically as shown in an answer.
After watching What's new in the support library - Google I/O 2016 I noticed one useful method in the AppCompatResources
class. This is AppCompatResources#getColorStateList(Context context, int resId)
. With a help of this method I've implemented selector with vector drawables. Here is my color selector file icon_selector
:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/red_selected" android:state_selected="true"/>
<item android:color="@color/red_pressed" android:state_pressed="true"/>
<item android:color="@color/red"/>
</selector>
And there is java method that returns tinted drawable:
private Drawable getTintedDrawable(@DrawableRes int drawableId) {
Drawable drawable;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
drawable = getResources().getDrawable(drawableId, getTheme());
} else {
drawable = getResources().getDrawable(drawableId);
}
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTintList(drawable.mutate(), AppCompatResources.getColorStateList(this, R.color.selector_nav_bar_item_ico));
return drawable;
}
You can use it like shown below
yourImageView.setImageDrawable(getTintedDrawable(R.drawable.ic_vector_image));
Working fine with below changes.
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
Added in Application class.
app build.gradle inside defaultConfig
vectorDrawables.useSupportLibrary = true
'IT TIP' 카테고리의 다른 글
배열에 다음이 포함 된 경우 각도 표현식 (0) | 2020.12.03 |
---|---|
HttpClient를 사용하여 데이터를 게시하는 방법은 무엇입니까? (0) | 2020.12.03 |
거친 그레이 스케일 알고리즘 사용에 문제가 있습니까? (0) | 2020.12.03 |
사용자 지정 Maven 2 속성에 대한 기본값 설정 (0) | 2020.12.03 |
ArrayList를 새 크기로 축소 (0) | 2020.12.03 |