program story

Lollipop 충돌 전 Android 벡터 드로어 블 사용

inputbox 2020. 10. 13. 07:45
반응형

Lollipop 충돌 전 Android 벡터 드로어 블 사용


Lollipop 이전 에 Android에서 벡터 드로어 블을 사용 하고 있으며 다음은 내 라이브러리 및 도구 버전 중 일부입니다.

  • 안드로이드 스튜디오 : 2.0
  • Android Gradle 플러그인 : 2.0.0
  • 빌드 도구 : 23.0.2
  • Android 지원 라이브러리 : 23.3.0

내 앱 수준에이 속성을 추가했습니다. Build.Gradle

android {  
  defaultConfig {  
    vectorDrawables.useSupportLibrary = true  
   }  
}

Android 공식 블로그 ( 여기 링크 )에 명시된대로 LayerDrawable (layer_list)과 같은 추가 드로어 블을 사용하여 외부의 벡터 드로어 블에 드로어 블을 설정 한다는 점도 언급 할 가치가 있습니다.app:srcCompat

<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/search"/>
</level-list>

app : srcCompat 외부에서 직접 참조하는 벡터 드로어 블은 Lollipop 이전에 실패합니다. 그러나 AppCompat는 StateListDrawable, InsetDrawable, LayerDrawable, LevelListDrawable 및 RotateDrawable과 같은 다른 드로어 블 컨테이너에서 참조되는 경우 벡터 드로어 블로드를 지원합니다. indirection 을 사용하면 일반적으로 벡터 드로어 블을 지원할 수없는 TextView의 android : drawableLeft 속성과 같은 경우에 벡터 드로어 블을 사용할 수 있습니다.

언제 사용하고 app:srcCompat내가 사용할 때 모든 것이 잘 작동하지만 :

android:background
android:drawableLeft
android:drawableRight
android:drawableTop
android:drawableBottom

ImageView, ImageButton, TextView또는 EditText롤리팝 이전에, 그것은 expection가 발생합니다 :

Caused by: android.content.res.Resources$NotFoundException: File res/drawable/search_toggle.xml from drawable resource ID #0x7f0200a9

최신 업데이트-2019 년 6 월

지원 라이브러리는 원래 답변 이후 약간 변경되었습니다. 이제 gradle도 빌드시 자동으로 PNG를 생성 할 수 있습니다. 따라서 다음은 요즘 작동해야하는 두 가지 새로운 접근 방식입니다. 여기에서 자세한 정보를 찾을 수 있습니다 .

지원 라이브러리

아마도 이것이 당신을 위해 일할 솔루션입니다. 여기에왔다면 Android Studio가 PNG를 자동으로 생성하지 않는다는 의미입니다. 따라서 앱이 충돌합니다. PNG 생성은 XML 요소의 하위 집합 만 지원합니다. 그러나이 솔루션은 모든 xml 태그를 지원합니다. 따라서 벡터 드로어 블을 완벽하게 지원합니다.

먼저 빌드 gradle을 업데이트하여 지원해야합니다.

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

dependencies {
  compile 'com.android.support:appcompat-v7:23.2.0' // OR HIGHER
}

그런 다음 벡터 드로어 블 app:srcCompat대신 사용하십시오 android:src. 이것을 잊지 마세요.

TextView경우 AndroidX를 사용하는 경우 app:drawableLeftCompat대신 (또는 오른쪽, 위쪽, 아래쪽)을 사용할 수 있습니다.app:drawableLeft

AndroidX를 사용하지 않거나 버튼을 사용하지 않는 경우 다음을 통해 동적으로 설정을 시도 할 수 있습니다.

Drawable icon = AppCompatResources.getDrawable(context, <drawable_id>);
textView.setCompoundDrawablesWithIntrinsicBounds(<leftIcon>,<topIcon>,<rightIcon>,<bottomIcon>);

PNG 생성

Gradle은 빌드시 자동으로 PNG 이미지를 생성 할 수 있습니다. 그러나이 접근 방식에서는 모든 xml 요소가 지원되는 것은 아닙니다 . 이 솔루션은 코드 나 build.gradle에서 아무것도 변경할 필요가 없기 때문에 편리합니다. Android 플러그인 1.5.0 이상Android Studio 2.2 이상을 사용하고 있는지 확인하세요 .

내 앱에서이 솔루션을 사용하고 있으며 잘 작동합니다. 추가 build.gradle 플래그가 필요하지 않습니다. 해킹이 필요하지 않습니다. `/ build / generated / res / pngs / ... "로 이동하면 생성 된 모든 PNG를 볼 수 있습니다.

따라서 모든 xml 요소가 지원되지 않기 때문에 간단한 아이콘이있는 경우이 솔루션이 적합 할 수 있습니다. Android Studio와 Android Gradle 플러그인을 업데이트하기 만하면됩니다.


업데이트-2016 년 7 월

그들은 Android 지원 라이브러리 23.4.0 에서 VectorDrawable을 다시 활성화했습니다.

AppCompat 사용자의 경우 AppCompatDelegate.setCompatVectorFromResourcesEnabled (true)를 통해 리소스 (23.2에서 발견 된 동작)에서 벡터 드로어 블 지원을 다시 활성화 하는 옵트 인 API를 추가했습니다. 그래도 메모리 사용량에 문제가 발생할 수 있으며 구성 인스턴스를 업데이트하는 데 문제가 있으므로 기본적으로 비활성화되어 있습니다.

어쩌면 , build.gradle설정이 폐지되어 당신은 적절한 활동 (시험에 그러나 필요)에서 활성화해야합니다.

이제 활성화하려면 다음을 수행해야합니다.

public class MainActivity extends AppCompatActivity {
    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }

    ...
}

원래 답변-2016 년 4 월

최신 라이브러리 버전 23.3.0에서 Support Vector가 비활성화 되었기 때문에 이런 일이 발생한 것 같습니다.

POST 에 따르면 :

AppCompat 사용자의 경우 버전 23.2.0 / 23.2.1 (ISSUE 205236) 의 구현에서 발견 된 문제로 인해 Lollipop 이전 기기의 리소스에서 벡터 드로어 블을 사용할 수있는 기능을 제거하기로 결정했습니다 . app : srcCompat 및 setImageResource () 사용은 계속 작동합니다.

문제 205236 을 방문 하면 향후 활성화 될 것으로 보이지만 메모리 문제는 곧 해결되지 않을 것입니다.

다음 릴리스에서는 제거 된 VectorDrawable 지원을 다시 활성화 할 수있는 옵트 인 API를 추가했습니다. 이전과 동일한주의 사항이 있습니다 (메모리 사용량 및 구성 업데이트 문제).

비슷한 문제가있었습니다. 그래서 제 경우에는 벡터 드로어 블을 사용하는 모든 아이콘을 리소스에서 PNG 이미지로 다시 되돌 렸습니다 (다시 활성화하는 옵션을 제공 한 후에도 메모리 문제가 계속 발생하기 때문입니다).

이것이 최선의 선택인지 확실하지 않지만 내 생각에 모든 충돌을 해결합니다.


나는 같은 문제가 있었다. 하지만 많은 R & D를하면서 답을 얻었습니다.

Imageview 및 ImageButton 사용 app:srcCompat="@drawable/...."및 Button, Textview와 같은 다른보기의 "drawableLeft/right..."경우 XML에서 사용하는 대신 드로어 블을 다음과 같이 프로그래밍 방식으로 지정합니다.

button.setCompoundDrawablesWithIntrinsicBounds(AppCompatResources.getDrawable(mContext,R.drawable.ic_share_brown_18dp), null, null, null);

그리고 드로어 블을 얻으려면 "AppCompatResources"를 사용하십시오.


다른 아주 좋은 답변 에 대해 자세히 설명하기 위해 여기에 도움이 될 수 있는 다이어그램 이 있습니다. 지원 라이브러리가 23.4.0에서 25.1.0 이상인 경우 유효합니다.

VectorDrawable cheatsheet


Guillherme P 의 답변 은 매우 훌륭합니다. 약간의 개선을 위해 모든 활동에 해당 라인을 추가 할 필요가 없습니다. Application 클래스에 한 번 추가하면 작동합니다.

public class App extends Application {

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

기억하세요 : 그래도 gradle에서 지원 라이브러리 사용을 활성화해야합니다.

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

또한 Google이 VectorDrawables 용 드로어 블 컨테이너에 대한 지원을 다시 추가했을 때 v23.4 이상의 지원 라이브러리 버전을 사용하고 있는지 확인하십시오 ( 릴리스 노트 ).

최신 정보

그리고 코드 변경 :

  1. 속성 app:srcCompat을 허용하는 모든 위치 로 업데이트해야 android:src합니다 (IDE가 <bitmap>태그 와 같이 유효하지 않은 경우 경고합니다 ).
  2. 를 들어 drawableLeft, drawableStart, drawableRight, drawableEnd에 사용되는 속성 TextView과 유사한 전망, 당신은 지금 프로그램을 설정해야합니다. 설정 예 drawableStart:

    Drawable drawable = AppCompatResources.getDrawable(
            getContext(),
            R.drawable.your_vector_drawable);
    
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
        textView.setCompoundDrawablesRelativeWithIntrinsicBounds(drawable, null, null, null);
    }
    

나는 같은 문제가 있었다. 그리고 제거하여 수정

vectorDrawables.useSupportLibrary = true

내 대상 버전은 25이고 지원 라이브러리는

 compile 'com.android.support:appcompat-v7:25.3.1'

사전 롤리팝의 VectorDrawables는 사용하지 않아도 잘 작동합니다.

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

ImageViews 내에서 VectorDrawables를 사용하려는 경우 속성을 사용할 수 있으며 srcCompat작동하지만 Buttons 또는 TextViews 내에서는 작동 하지 않으므로 Drawable을 InsetDrawable 또는 LayerDrawable로 래핑해야합니다. 내가 발견 한 또 다른 트릭이 있습니다. 데이터 바인딩을 사용하는 경우 다음과 같이 할 수 있습니다.

android:drawableLeft="@{@drawable/vector_ic_access_time_24px}"
android:drawableStart="@{@drawable/vector_ic_access_time_24px}"

그것은 마술처럼 작동 할 것입니다. 뒤에서 무슨 일이 일어나고 있는지 조사하지 않았지만 TextView가 AppCompatResources 또는 이와 유사한 getDrawable 메서드를 사용하고 있다고 생각합니다.


많은 R & D가 마침내 사전 롤리팝 장치의 충돌에 대한이 솔루션을 얻었습니다.

Imageview 용

  • 사용하는 응용 프로그램 : srcCompat 대신 안드로이드의 : SRC

TextView / EditText의 경우

  • drawableleft , drawableright ....를 제거하고 드로어 블 자바 코드에서 설정합니다.

txtview.setCompoundDrawablesWithIntrinsicBounds (AppCompatResources.getDrawable (EventDetailSinglePage.this, R.drawable.ic_done_black_24_n), null, null, null);

Build.gradle의 경우

vectorDrawables.useSupportLibrary = true


Android gradle 3.0 이상으로 업그레이드하는 사람은을 사용 AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)하거나 설정할 필요가 없습니다 vectorDrawables.useSupportLibrary = true(추가하면 문제가 발생 함) app:srcCompat.

이 문제를 해결하는 데 이틀이 걸리고 Google 문서에서 관련 문서를 찾지 못했습니다.


나는 Pre-lollipop 장치에서 VectorDrawables를 사용하고 있으며 이것이 내가하는 방법입니다 :-

1 단계 : 이를 앱 수준 gradle에 넣습니다.

android {
  defaultConfig {
    vectorDrawables.useSupportLibrary = true
  }
}

2 단계:

이것을 Application 클래스에 넣고 매니페스트 파일에 Application 클래스를 등록하는 것을 잊지 마십시오.

public class App extends Application {
    static {
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
    }
}

3 단계 :

다음을 사용하여 VectorDrawables 가져 오기,

imageView.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.my_vector_drawable));

벡터 드로어 블을 상태 목록에 겹치면 문제가 해결됩니다.

예를 들어 뒤로 화살표 벡터 이미지가 있습니다.

ic_back_arrow.xml

예, 레이어 목록 xml (ic_back_arrow_vector_vector.xml)과 겹쳐 야합니다.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_back_arrow"/>
</layer-list>

논리 때문에 :

vectorDrawables.useSupportLibrary = true

AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);

일부 중국 장치 및 구형 삼성 장치에서는 도움이되지 않습니다. 겹치지 않으면 실패합니다.


가장 쉬운 방법 사용 :

  app:drawableRightCompat ="@drawable/ic_mobilelogin"
  app:drawableEndCompat="@drawable/ic_mobilelogin"
app:srcCompat="@drawable/ic_mobile"

그리고 ... app : ** Compat for compatability를 사용하세요.

또한 buil.gradle (Module)에 대한 지원 추가

android {
 defaultConfig {
vectorDrawables.useSupportLibrary = true
               }
        }

아래 코드를 사용한 후.

android {
  defaultConfig {
  vectorDrawables.useSupportLibrary = true  
                }
        }




public class App extends Application {
static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}}

여전히, 아래 속성에 대한 벡터 이미지 문제가 있습니다.

DrawableEnd, DrawableStart, DrawableTop, DrawableBottom, 배경

이 경우, 벡터 이미지를 직접 참조하는 대신 중간 드로어 블 파일로 선택기 태그를 사용하십시오.

예:

ic_warranty_icon.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="17dp"
android:height="24dp"
android:autoMirrored="true"
android:viewportWidth="17"
android:viewportHeight="24">

<path
    android:fillColor="#fff"
    android:pathData="M10.927,15.589l-1.549,0.355a7.47,7.47 0,0 1,-0.878 0.056c-4.136,0 -7.5,-3.364 -7.5,-7.5s3.364,-7.5 7.5,-7.5 7.5,3.364 7.5,7.5c0,3.286 -2.126,6.078 -5.073,7.089zM8.5,2a6.508,6.508 0,0 0,-6.5 6.5c0,3.583 2.917,6.5 6.5,6.5s6.5,-2.917 6.5,-6.5 -2.917,-6.5 -6.5,-6.5z" />

safe_ic_warranty_icon.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/ic_warranty_icon"  />
</selector>

귀하의 TextView / 레이아웃.

<TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:drawableStart="@drawable/ic_warranty_icon"
       />


<LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/ic_warranty_icon"
       />

3 가지 시도

vectorDrawables.useSupportLibrary = true

Setting setCompatVectorFromResourcesEnabled in Application class

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

And use app:srcCompat

But even after that it was failing with

Resources$NotFoundException: File res/drawable/$my_icon__0.xml from color state list resource ID #0x7f080008

then we figured out that our SVG had a Gradient tag. Converting the gradient tag to individual paths for below API <= 23 and using the same SVG API >= 24 worked.

Got help from this answer https://stackoverflow.com/a/47783962/2171513


Guilherme P's suggestion was not working for me. I went ahead and made the decision to use png's where I need to do things outside of app:srcCompat i.e. drawableLeft, drawableRight, etc. This was a pretty easy change to make, and doesn't have the potential memory issues AppCompatDelegate.setCompatVectorFromResourcesEnabled(true); introduces.


An alternative to Benny's answer is to create an Activity superclass:

public abstract class VectorDrawableActivity extends AppCompatActivity {
  static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
  }

  //...
}

Now extend VectorDrawableActivity instead of AppCompatActivity.

참고URL : https://stackoverflow.com/questions/36867298/using-android-vector-drawables-on-pre-lollipop-crash

반응형