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


91

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과 같은 다른 드로어 블 컨테이너에서 참조되는 경우 벡터 드로어 블로드를 지원합니다. 이 간접적 인 사용 으로 일반적으로 벡터 드로어 블을 지원할 수없는 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


drawableLeft, drawableRight, drawableTop, drawableBottom 체크 아웃으로 VectorDrawable를 사용하는 방법을 보려면 이 답변
베 자드 Bahmanyar

여기에서 내 대답을 확인할 수 있습니까? stackoverflow.com/a/40523623/2557258
Yazon2006

제 경우에는 vactor 드로어 블이 올바른 패키지에 있지 않았습니다 (프로젝트보기 열기) 여기에 원래 답변이 있습니다. stackoverflow.com/a/35836318/2163045
murt

답변:


102

최신 업데이트-2019 년 6 월

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

PNG 생성

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

내 앱에서이 솔루션을 사용하고 있으며 잘 작동합니다. 추가 build.gradle 플래그가 필요하지 않습니다. 해킹이 필요하지 않습니다. 당신이 가면 / 구축 / 생성 / 고해상도 / PNG 파일 / ... 당신은 생성 된 모든 PNG 파일을 볼 수 있습니다.

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

지원 라이브러리

아마도 이것이 당신을 위해 일할 솔루션입니다. 여기에왔다면 Android Studio가 PNG를 자동으로 생성하지 않는다는 의미입니다. 따라서 앱이 충돌합니다.

또는 Android Studio에서 PNG를 전혀 생성하지 않기를 원할 수도 있습니다.

XML 요소의 하위 집합을 지원하는 "자동 PNG 생성"과 달리이 솔루션은 모든 xml 태그를 지원합니다. 따라서 벡터 드로어 블을 완벽하게 지원합니다.

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

android {
  defaultConfig {
    // This flag will also prevents Android Studio from generating PNGs automatically
    vectorDrawables.useSupportLibrary = true
  }
}

dependencies {
  // Use this for Support Library
  implementation 'com.android.support:appcompat-v7:23.2.0' // OR HIGHER

  // Use this for AndroidX
  implementation 'androidx.appcompat:appcompat:1.1.0' // OR HIGHER
}

그런 다음 로드하는 동안 app:srcCompat대신 사용android:srcVectorDrawables . 이것을 잊지 마세요.

들어 TextView당신이 사용하는 경우, androidx지원 라이브러리의 버전을, 당신은 사용할 수 있습니다app:drawableLeftCompat (또는 오른쪽, 위, 아래) 대신app:drawableLeft

의 경우 CheckBox/ RadioButton사용 app:buttonCompat대신android:button .

당신이 사용하지 않는 경우 androidx지원 도서관과의 버전 minSdkVersionIS 17이상 또는 버튼을 사용하여, 당신은을 통해 프로그래밍 방식으로 설정하려고 할 수 있습니다

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

업데이트-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 이미지로 다시 되돌 렸습니다 (다시 활성화하는 옵션을 제공 한 후에도 메모리 문제가 계속 발생하기 때문입니다).

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


1
@Guilherme P에게 감사합니다.하지만 빌드시vectorDrawables.useSupportLibrary = true png 생성을 다시 활성화하기 위해 성능을 제거하지 않은 이유는 무엇입니까?
Behzad Bahmanyar 2011

1
이는 메모리 문제로 인해 최신 버전 v23.3.0에서 비활성화되었습니다. 이렇게하면 런타임에 png를 생성 할 수 없습니다 ... 그래서 logcat 오류에서 알 수없는 태그 벡터 (또는 이와 유사한 것)를 인쇄합니다.
W0rmH0le

4
다음은 선택 안내 plus.google.com/+AndroidDevelopers/posts/B7QhFkWZ6YX 입니다. 불행히도 VectorDrawables는 여전히 Pre-Lollipop 장치에서 작동하지 않습니다. 저는 Support Library 23.4.0에 있으며 defaultConfig {}에서 'generatedDensities = []'및 'vectorDrawables.useSupportLibrary = true'를 모두 호출했습니다.
아담 허 비츠

1
@AdamHurwitz 답변을 업데이트했습니다. 다시 활성화 된 것 같습니다. 그러나 지금은 다르게 활성화해야합니다.
W0rmH0le

1
@juztcode 당신이 맞아요. 'androidx.appcompat : appcompat : 1.1.0'을 사용해야합니다.
W0rmH0le

63

나는 같은 문제가 있었다. 하지만 많은 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"를 사용하십시오.



39

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합니다 ( <bitmap>태그 와 같이 유효하지 않은 경우 IDE에서 경고 ).
  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);
    }

gradle에서 벡터 드로어 블에 대한 지원 라이브러리를 사용해야합니다. vectorDrawables.useSupportLibrary = true
Benny

2
네. 알아. 그러나 벡터 드로어 블이 TexViews의 드로어 블로 작동하도록하려면 래퍼가 필요하므로이 답변은 불완전합니다.
cesards

1
좋은 대답입니다. 사용자 지정 기본 활동에서 확장 된 모든 활동이있는 앱에 특히 좋습니다.
Hong

14

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

vectorDrawables.useSupportLibrary = true

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

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

1
이것은 나를 위해 일했습니다. 감사. 난 그냥 제거 그vectorDrawables.useSupportLibrary = true
안드로이드 평균 이하

나는 이것이 적절한 방법이 아니라고 생각합니다. 어느 쪽이든 귀하의 답변에 찬성했습니다. !!
Harish Reddy

감사합니다. t 내 앱에서 작동합니다. 모든 벡터 드로어 블은 제거 된 경우에도 계속 작동합니다. 앱에서 com.android.support:appcompat-v7:28.0.0
Hong

10

사전 롤리팝의 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 메서드를 사용하고 있다고 생각합니다.


선택기에서 벡터 이미지를 설정하는 방법은 무엇입니까?
Tushar Gogna

gradle 기본값 및 AppCompatDelegate.setCompatVectorFromResourcesEnabled (true) 에서 vectorDrawables.useSupportLibrary = true 를 설정 한 후 ); in activity on create Textview에서 android : drawableleft 와의 충돌을 방지하려면 드로 블을 textview에 프로그래밍 방식으로 왼쪽으로 설정합니다. textview.setCompoundDrawablesWithIntrinsicBounds (R.drawable.movie, 0, 0, 0);
Afjalur Rahman Rana

7

많은 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


1
TextInputEditText에서 작동하는 고유 한 솔루션이었습니다.
heronsanches

1
Awsome, 이것은 내 문제가 해결되었습니다. 이것은 받아 들여지는 대답이어야합니다.
DJtiwari

6

가장 쉬운 방법 사용 :

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

그리고 ... app:**Compat호환성을 위해 사용하십시오 . build.gradle(모듈) 에 대한 지원도 추가하십시오.

android {
   defaultConfig {
       vectorDrawables.useSupportLibrary = true
   }
}

응용 프로그램 : drawableEndCompat 및 응용 프로그램 : drawableRightCompat 거의 같은 일 자사의 영어 경우
호삼 하산

5

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

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


흥미롭게도 저는 gradle 3.3.0을 사용하고 있으며이 솔루션이 작동합니다. 그러나 Android Studio는 여전히 set vectorDrawables.useSupportLibrary = true를 사용하도록 설정합니다.
masterwok jul.

2

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

2

아래 코드를 사용한 후.

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"
       />

감사 !!! 배경 속성의 경우 벡터 드로어 블을 직접 사용하지 않고 사이에 선택기를 추가하면 롤리팝 이전 API에서 작동했습니다 (19).
Ankur

제 경우에는 여전히 API (16)에서 작동하지 않습니다. 포장도 마찬가지입니다selector
mochadwi

1

3 가지 시도

vectorDrawables.useSupportLibrary = true

애플리케이션 클래스에서 setCompatVectorFromResourcesEnabled 설정

static {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}

그리고 사용 app:srcCompat

하지만 그 후에도 실패했습니다

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

그런 다음 SVG에 Gradient 태그가 있음을 알아 냈습니다. API <= 23 이하의 경우 그라데이션 태그를 개별 경로로 변환하고 동일한 SVG API> = 24를 사용하면 효과가 있습니다.

이 답변에서 도움을 얻었습니다 https://stackoverflow.com/a/47783962/2171513


왜 아무도 이것을 찬성하지 않았는지 모르겠지만 이것이 실제로 내 문제의 해결책이 될 수 있습니다. 감사합니다
DevMike01

0

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

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

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

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


0

나는 이것을 몇 시간 동안 고심하고 있었다.

나는이 대답이 내게 말한 모든 것을 시도했지만 내 앱이 멈추지 않았습니다. 이 줄을 삭제했습니다. app:srcCompat="@drawable/keyboard"내 앱이 중단되었습니다. 그런 다음 동일한 것을 다시 추가했을 때 다시 충돌하기 시작했습니다. 그래서 저는 그 파일을 열기로 결정했고 첫 번째 줄에서

"드로어 블 '키보드'는 기본 드로어 블 폴더에 선언이 없습니다. 이로 인해 충돌이 발생할 수 있습니다.

파일을 마우스 오른쪽 버튼으로 클릭하고 "Show in explorer"를 클릭했는데 드로어 블 폴더가 아니라 드로어 블 -v24 디렉토리에있었습니다. 그래서 나는 그것을 복사하여 드로어 블 디렉토리에 붙여넣고 마침내 충돌을 제거했습니다.


-2

Guilherme P의 제안은 저에게 효과가 없었습니다. 나는 계속해서 app : srcCompat, 즉 drawableLeft, drawableRight 등을 수행해야하는 곳에 png를 사용하기로 결정했습니다. 이것은 매우 쉬운 변경이었고 잠재적 인 메모리 문제가 없습니다 AppCompatDelegate.setCompatVectorFromResourcesEnabled ( 진실); 소개합니다.


-3

Benny의 대답에 대한 대안 은 Activity수퍼 클래스 를 만드는 것입니다 .

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

  //...
}

이제 확장 VectorDrawableActivity대신 AppCompatActivity.


@cesards 왜 안돼?
Code-Apprentice
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.