Android 드로어 블 디렉토리에 하위 디렉토리가 포함될 수 있습니까?


496

Android SDK 설명서에서 @ drawable / my_image xml 구문과 함께 사용 된 모든 예제는 프로젝트의 res / drawable 디렉토리에 저장된 이미지를 직접 처리합니다.

drawable 디렉토리 내에 하위 디렉토리를 만드는 것이 명시 적으로 좋지 않은지 궁금합니다.

예를 들어, 다음 디렉토리 레이아웃이있는 경우 :

res/drawable
-- sandwiches
  -- tunaOnRye.png
  -- hamAndSwiss.png
-- drinks
  -- coldOne.png
  -- hotTea.png

참치 샐러드 샌드위치의 이미지를 @ drawable / sandwiches / tunaOnRye로 참조 할 수 있습니까?

또는 Drawable 디렉토리에 계층 구조를 평평하게 유지해야합니까?


16
res 디렉토리에는 대문자를 사용할 수 없습니다.
Tyler

1
당신은 Gradle을 사용하여이 작업을 수행 할 수 stackoverflow.com/a/19859379
Yair Kukielka

2
그것은이 가능한가요 형제 드로어 블 기능으로, 당김에 디렉토리를? 그래서 res / tanks / drawble- [hdpi .. 등] 등등?
Fattie

답변:


545

아니요, 리소스 메커니즘은 드로어 블 디렉토리의 하위 폴더를 지원하지 않으므로 해당 계층 구조를 평평하게 유지해야합니다.

표시 한 디렉토리 레이아웃으로 인해 사용 가능한 이미지가 없습니다.

내 자신의 실험에서 res/drawable폴더 내에 항목이있는 하위 폴더가 있으면 리소스 컴파일러가 실패하여 R.java파일이 올바르게 생성 되지 않는 것처럼 보입니다 .


135
Android 2.2부터는 컴파일러 오류가 발생하지 않지만 R 클래스 생성시 하위 디렉토리는 무시됩니다. 이것은 정말 짜증나고 더 큰 프로젝트를 관리하기 어렵게 만듭니다. = /
Nik Reiman

69
전적으로 동의합니다. 하위 폴더를 지원하는 더 나은 솔루션이 필요합니다. 그렇게 힘들 수는 없습니다.
znq

13
바라건대이 문제는 곧 해결 될 것입니다. 100 개가 넘는 자산이 있으며 심지어 일부를 코딩했습니다. 약간 복잡한 프로젝트를 관리하려고하는 밤의 악몽.
Emile

14
이것은 Android 문제 추적기의 해당 문제입니다 : code.google.com/p/android/issues/detail?id=2018
espinchi

44
저주 안드로이드
whitneyland

149

내가 사용하는 해결 방법 (Android 자체가 선호하는 것으로 보임)은 기본적으로 슬래시를 밑줄로 대체하여 구조가 다음과 같이 보일 것입니다.

sandwich_tunaOnRye.png
sandwich_hamAndSwiss.png
drink_coldOne.png
drink_hotTea.png

이 방법을 사용하려면 이름을 세 심하게 작성해야하며 파일 자체를 훨씬 쉽게 정리할 수 없습니다 (음료와 샌드위치가 모두 " food" 여야한다고 결정한 경우 단순히 이름을 바꾸지 않고 대량 이름을 변경해야합니다. 디렉토리로 이동); 그러나 프로그래밍 로직의 복잡성은 폴더 구조와 비교할 때 너무 심하게 고통받지 않습니다 .

이 상황은 참으로 짜증납니다. Android는 훌륭하고 끔찍한 디자인 결정이 혼합 된 백입니다. 우리는 후자 부분이 모든 서두름에 매료되기를 바랍니다. :)


31
드로어 블 폴더에는 대문자를 사용할 수 없습니다. 나는 오류 : "잘못된 파일 이름 : 만 있어야합니다 [A-z0-9_.]"
제이슨 Axelson에게

5
"멋지고 끔찍한 디자인 결정의 혼합 가방"+1
브렌트 파우스트

1
해결 방법은 거의 없습니다. "완전히 화를 내지 않기 위해해야 ​​할 일". 하나의 디렉토리로 제한되는 것은 우스운 일입니다.
RichieHH

35

실제로 Android Studio에서는 가능합니다. 와 같이 중첩 된 자원을 가질 수 있습니다 여기에 :

여기에 이미지 설명을 입력하십시오

여기에 리소스를 그룹화하는 플러그인도 있습니다 .


안녕 @android 개발자! 이것을 build.gradle 파일에 추가하려고 시도했습니다. sourceSets {main {res {srcDir 'src / main / res / drawable / ic-toggle'}}}하지만 xmlns에 대해 "Uri is registered"가 있습니다. : android = " schemas.android.com/apk/res/android . 사건은 무엇입니까?
AlexKost

@ AlexKost 나는 실제로 이것을 한 번만 시도했다. 나는 그것을 도울만큼 경험이 없습니다. 죄송합니다.
안드로이드 개발자

@RahulMandaliya 비록 가능하더라도 사용하지 않는 것이 좋습니다.
안드로이드 개발자

@androiddeveloper 왜 안되죠?
Josh Hansen

1
@JoshHansen 지저분합니다.
안드로이드 개발자

34

예-그것은 빨아요 :) 그러나 자산 폴더를 사용하고 하위 디렉토리를 가지고 이미지를로드 할 수 있습니다.


6
문제는 드로어 블 폴더뿐만 아니라 레이아웃 폴더에도 있습니다. (내 레이아웃의 폴더에는 100 개 이상의 xml 파일이 포함되어 있으며, 이것으로 올바른 xml 레이아웃을 여는 것이 어렵습니다.
anticafe

다른 이의 제기의 경우 자원을 쉽게 지역화 할 수 있지만 AFAIK에는 자산에 대한 내장 메커니즘이 없습니다.
Fran Marzoa

@anticafe 사용하여 IDE에서 "리소스로 이동"(이클립스 : CTRL + SHIFT + R, IDEA / 안드로이드 스튜디오 : CTRL + 시프트 + N)
TWiStErRob

23

자산 폴더를 사용하십시오.

샘플 코드 :

InputStream is = null;
try {
    is = this.getResources().getAssets().open("test/sample.png");
} catch (IOException e) {
    ;
}

image = BitmapFactory.decodeStream(is);

5
이 방법의 유일한 문제는 비트 맵 사용과 관련된 많은 숙제가 있다는 것입니다. 안드로이드의 리소스 시스템은 훨씬 더 나은 메모리 관리 작업을 수행합니다. 안드로이드가 이미 메모리 관리 시스템을 재 구축 한 이유는 무엇입니까? 특히 100 개가 넘는 이미지를 보유하고 있다면 비트 맵을로드 및 릴리스하는 작업이 많습니다.
Rev Tyler

18
이것은 실제 문제입니다. 화면 밀도에 따라 다른 리소스를 사용하는 경우에도 응용 프로그램을 지역화 할 계획이므로 솔루션이 아니라 일부 경우에만 유효한 해결 방법이 아닙니다.
Fran Marzoa

1
나는 @Fran의 의견을 적어도 천개의 공짜로 주어야한다 :)
HGPB

22

파일 이름을 두 개의 밑줄로 분리하여 가상 하위 폴더를 만들 수있는 이클립스 플러그인을 작성했습니다 __. 프로젝트는 초기 단계이지만 IDE가 충돌하지 않을 것이라고 걱정하지 마십시오.

자세한 내용은 여기에서 찾을 수 있으며, 포크로 요청하고 풀 요청을 보내십시오.

https://github.com/kirill578/Android-Sorted-Res-Folder

여기에 이미지 설명을 입력하십시오


2
좋은! 이것을 Android Studio로 포팅 할 기회가 있습니까?
BVB

1
나는 현재 안드로이드 스튜디오를 사용하고 있지 않기 때문에 경험이있는 사람들이 기다려야 할 것이라고 생각합니다.
Kirill Kulakov

9

디자이너가 제공하는 체계적인 디렉토리 구조를 R 파일 생성에 사용할 수있는 간단한 스크립트로 사용하고 싶습니다.

drawable-hdpi에서 현재 경로로 실행하십시오.

#! /bin/bash
DIRS=`find * -type d`
for dir in ${DIRS} ; do 
  for file in `ls ${dir}` ; do
    mv ${dir}/${file}  ${dir}_${file};
  done 
  rmdir ${dir};
done

1
폴더 아래에 하위 폴더가 있으면 스크립트가 작동하지 않습니다. $ {dir}에서 모든 '/'를 '_'로 바꿔야한다고 생각합니다.
Seunghoon

9

gradle이있는 android studio에는 여러 소스 디렉터가있어 리소스를 분리 할 수 ​​있습니다. 예를 들면 다음과 같습니다.

android {
    ....
    android.sourceSets {
        main.res.srcDirs = ['src/main/extraresdirnamed_sandwiches', 'src/main/res']
    }
    ....
}

그러나 이름이 충돌해서는 안됩니다. 즉, sandwichs_tunaOnRye와 같은 이름이 필요하지만 모든 샌드위치에 대해 별도의 섹션을 가질 수 있습니다.

이를 통해 리소스를 다른 구조로 저장할 수 있습니다 (actionbargenerator와 같은 자동 생성 컨텐츠에 유용)


4

부분적으로 문제를 해결하는 한 가지 방법은 API 레벨 접미사를 사용하는 것입니다. res / layout-v1, res / layout-v2 등을 사용하여 동일한 apk에서 여러 하위 프로젝트를 보유합니다. 이 메커니즘은 모든 자원 유형에 사용할 수 있습니다.

분명히 res / layout-v 이상의 API 레벨을 타겟팅하는 경우에만 사용할 수 있습니까? 당신은 사용하고 있습니다.

또한 Android 1.5 및 1.6의 버그에주의하십시오. API 레벨 접미사에 대한 Andoroid 문서를 참조하십시오 .


이 답변을 다운 그레이드 한 사람에게 : 이유를 설명 할 수 있습니까? 이 메커니즘은 예쁘지는 않지만 나에게 잘 작동합니다.
OferR

4

라이브러리 시스템의 출현으로 대규모 자산 세트마다 라이브러리를 작성하는 것이 해결책이 될 수 있습니다.

모든 자산 내에서 동일한 이름을 사용하지 않아야하지만 라이브러리 당 접두사 체계를 사용하면 도움이되므로 여전히 문제가됩니다.

폴더를 만드는 것만 큼 간단하지는 않지만 일을 제자리에 유지하는 데 도움이됩니다 ...


예, 이것이 좋다고 생각합니다. drawable-ldpi 등의 폴더에 국가 플래그를 추가하면 늪이됩니다. 모든 일반 리소스에 대한 라이브러리 프로젝트를 만들면 현재 작업중 인 프로젝트의 혼란을 줄일 수 있다고 생각합니다. 업 보트가 1 개 뿐인 것에 놀랐습니다.
Tom

3

이 상황에 대한 해결 방법이 있습니다. resVector예를 들어 기본 res폴더 와 같은 수준에서 폴더를 만들 수 있습니다 . 거기에 모든 drawable-xxx리소스 폴더를 추가 할 수 있습니다 .

resVector
-drawable
-layout
-color

그 후에 필요한 것은 추가하는 것입니다

sourceSets {
        main.res.srcDirs += 'src/main/resVector'
    }

당신에 build.gradle파일 (내부 android { }).


안타깝게도 "Android"퍼스펙티브를 사용할 때 Android Studio의 프로젝트 패널에 병합됩니다. (
AjahnCharles

@AjahnCharles-나는이 관점을 전혀 사용하지 않는 것을 선호한다. (어쨌든-나는 항상 '산만 무료 모드'에서 일하고있다.) 그러나 당신은 옳다- "Android"는 모든 것을 병합한다.
Anton Derevyanko

1

이것은 완벽한 방법이 아닙니다. 여기 에 표시된 것과 동일한 방식으로 구현해야합니다 .

사용할 수있는 코드를 통해 폴더 아래의 이미지를 호출 할 수도 있습니다.

Resources res = getResources();
Drawable shape = res. getDrawable(R.drawable.gradient_box);

TextView tv = (TextView)findViewByID(R.id.textview);
tv.setBackground(shape);


1

Android Studio를 사용하는 Gradle은 이런 식으로 할 수 있습니다 ( link ).

"구조 구성"단락에 있습니다.

sourceSets {
 main {
    java {
        srcDir 'src/java'
    }
    resources {
        srcDir 'src/resources'
    }
 }
}

1

메인에 폴더를 만듭니다. 'res_notification_btn'

'drawable'또는 'layout'과 같은 트리 폴더를 만듭니다.

그런 다음 'build.gradle'에서 이것을 추가하십시오

sourceSets
            {
                main
                {
                    res
                    {
                        srcDirs = ['src/main/res_notification_btn', 'src/main/res']
                      or
                        srcDir 'src/main/res_notification_btn'
                    }
                }
            }

0
#!/usr/bin/env ruby

# current dir should be drawable-hdpi/ etc

# nuke all symlinks
Dir.foreach('.') {|f|
    File.delete(f) if File.symlink?(f)
}

# symlink all resources renaming with underscores
Dir.glob("**/*.png") {|f|
    system "ln -s #{f} #{f.gsub('/', '_')}" if f.include?("/")
}

이 모든 것은 Cheezmeister가 제안한 해결 방법을 자동화하는 것입니다. downvote를 설명하는 데 관심이 있습니까?
Blake Miller


0

자산 /이를 사용하여 원시 자산 파일을 저장할 수 있습니다. 여기에 저장 한 파일은 그대로 .apk 파일로 컴파일되며 원래 파일 이름이 유지됩니다. URI를 사용하여 일반 파일 시스템과 동일한 방식으로이 디렉토리를 탐색하고 AssetManager를 사용하여 파일을 바이트 스트림으로 읽을 수 있습니다. 예를 들어, 이것은 텍스처와 게임 데이터를위한 좋은 위치입니다. http://developer.android.com/tools/projects/index.html


0

하위 디렉터리는 허용되지 않으며 리소스에는 [a-z0-9_.] 만 포함해야합니다.

대문자가없고 슬래시가 없습니다.


-3
  1. Drawable을 마우스 오른쪽 버튼으로 클릭하십시오.
  2. New ---> Directory를 선택하십시오.
  3. 디렉토리 이름을 입력하십시오. 예 : logo.png (기본적으로 위치는 기본적으로 드로어 블 폴더를 표시합니다)
  4. 이미지를 복사하여 드로어 블 폴더에 직접 붙여 넣습니다. 붙여 넣는 동안 목록의 각 이미지에 대해 mdpi / xhdpi / xxhdpi 등을 선택할 수 있습니다. 적절한 옵션을 선택하고 이미지 이름을 입력하십시오. 디렉토리 이름과 같은 이름을 유지하십시오 (예 : logo.png).
  5. 나머지 이미지에 대해서도 동일하게 수행하십시오. 모든 파일은 logo.png 메인 폴더에 위치합니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.