IT TIP

VectorDrawables srcCompat를 사용하는 Android Selector Drawable

itqueen 2020. 12. 3. 21:32
반응형

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.xmlres/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

참고URL : https://stackoverflow.com/questions/36741036/android-selector-drawable-with-vectordrawables-srccompat

반응형