Android çekilebilir dizini alt dizinler içerebilir mi?


496

Android SDK belgelerinde, @ drawable / my_image xml sözdizimi ile kullanılan tüm örnekler, projemdeki res / drawable dizininde depolanan görüntüleri doğrudan ele alır.

Açıkça çekilebilir dizini içinde bir alt dizin oluşturmak için sorun olup olmadığını merak ediyorum.

Örneğin, aşağıdaki dizin düzenine sahip olsaydım:

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

Ton balığı salatası sandviçinin görüntüsüne @ drawable / sandwiches / tunaOnRye olarak başvurabilir miyim

Yoksa hiyerarşiyi çizilebilir dizinde düz tutmak zorunda mıyım?


16
Res dizininde büyük harflere izin verilmediğini lütfen unutmayın.
Tyler

1
Bunu sadece Gradle ile yapabilirsiniz: stackoverflow.com/a/19859379
Yair Kukielka

2
SIBLING dizinlerinin çekilebilir işlevsellik ile çekilebilir olması mümkün müdür? Peki, res / tanklar / çekmeceli- [hdpi .. vs] vb.?
Fattie

Yanıtlar:


545

Hayır, kaynaklar mekanizması çekilebilir dizindeki alt klasörleri desteklemez, bu nedenle evet - bu hiyerarşiyi düz tutmanız gerekir.

Gösterdiğiniz dizin düzeni, resimlerin hiçbirinin kullanılabilir olmamasına neden olmaz.

Kendi deneylerimden, res/drawableklasör içindeki herhangi bir öğeye sahip bir alt klasör bulundurmak, kaynak derleyicisinin başarısız olmasına neden olacak ve R.javadosyanın doğru oluşturulmasını önleyecek gibi görünüyor .


135
Android 2.2'den itibaren bu, derleyici hatasına neden olmaz, ancak R sınıfı oluşturulurken alt dizinler yok sayılır. Bu gerçekten berbat ve daha büyük projeleri yönetmeyi zorlaştırıyor. = /
Nik Reiman

69
Tamamen katılıyorum. Alt klasörleri destekleyen daha iyi bir çözüm bulmaları gerekir. O kadar zor olamaz.
znq

13
Umarım bu yakında çözülecektir, 100'den fazla varlığım var ve o zaman bile bazılarını kodladım. Toplam gece kısrak herhangi bir marjinal karmaşık projeyi yönetmeye çalışıyor.
Emile

14
Bu, Android sorun izleyicisindeki ilgili Sorun: code.google.com/p/android/issues/detail?id=2018
espinchi

44
android lanet
whitneyland

149

Kullandığım geçici çözüm (ve Android'in kendisinin lehine olduğu anlaşılıyor), temelde bir eğik çizgi yerine alt çizgi koymaktır, böylece yapınız şöyle görünecektir:

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

Yaklaşım isimlendirmenizde titiz olmanızı gerektirir ve dosyaları kendileri kontrol etmeyi çok daha kolay hale getirmez (içeceklerin ve sandviçlerin gerçekten " food" olması gerektiğine karar verdiyseniz, sadece toplu olarak yeniden adlandırmak yerine bunları dizine taşımak); ancak programlama mantığınızın karmaşıklığı , klasör yapısı eşdeğerine kıyasla çok kötü bir şekilde etkilenmez .

Bu durum gerçekten berbat. Android harika ve korkunç tasarım kararları karışık bir çanta. Biz sadece ikinci bölümü tüm acele ile ot almak için umut olabilir :)


31
Yalnızca çekilebilir klasörde büyük harflere izin verilmediğini unutmayın. Şu hatayı alıyorum: "Geçersiz dosya adı: yalnızca [a-z0-9_.]
İçermelidir

5
"Harika ve korkunç tasarım kararlarının karışık torbası" için +1
Brent Faust

1
Çok az bir çözüm: daha çok "tamamen delirmemek için ne yapmalısınız". Bir diziyle sınırlı olması gülünç.
RichieHH

35

Aslında, Android Studio'da mümkündür. Burada gösterildiği gibi iç içe kaynaklara sahip olabilirsiniz :

resim açıklamasını buraya girin

Burada kaynakları gruplamak için bir eklenti de var .


Merhaba, @android geliştiricisi! Bunu build.gradle dosyasına eklemeye çalıştım: sourceSets {main {res {srcDir 'src / main / res / drawable / ic-toggle'}}}, ancak xmlns için "Uri kayıtlı değil" var : android = " schemas.android.com/apk/res/android . Durum ne olabilir?
AlexKost

@AlexKost Bunu sadece bir kez denedim. Yardım edecek kadar tecrübeli değilim. Afedersiniz.
android geliştirici

@RahulMandaliya Mümkün olsa da, kullanmamanızı öneririm.
android geliştirici

@androiddeveloper Neden olmasın?
Josh Hansen

1
@JoshHansen Dağınık.
android geliştirici

34

Evet - emiyor :) Ancak varlıklar klasörünü kullanabilir ve orada alt dizinlere sahip olabilir ve görüntüleri bu şekilde yükleyebilirsiniz.


6
sorun sadece çekilebilir klasör için değil, aynı zamanda düzen klasörü için :( Düzenimin klasörü 100'den fazla xml dosyası içeriyor ve buradaki doğru xml düzenini açmak benim için zor.
anticafe

Diğer itirazlar için, kaynaklar kolayca yerelleştirilebilir, ancak AFAIK varlıklar için l10n yerleşik bir mekanizma yoktur.
Fran Marzoa

@anticafe IDE'nizde "Kaynağa git" seçeneğini kullanın (Eclipse: CTRL + ÜST KARAKTER + R, IDEA / Android Studio: CTRL + ÜST KRKT + N)
TWiStErRob 19:14

23

Varlıklar klasörünü kullan.

basit kod:

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

image = BitmapFactory.decodeStream(is);

5
Bu yöntemle ilgili tek sorun, bitmap'lerin kullanımı ile ilgili çok daha fazla ödev olmasıdır. Android'in kaynak sistemi, bellek yönetiminden çok daha iyi bir iş çıkarıyor. Android zaten yaptığında neden bir bellek yönetim sistemini yeniden inşa edesiniz? Özellikle 100'den fazla resim varsa, bu çok fazla bitmap yükleme ve bırakma.
Rev Tyler

18
Bu, gerçek bir sorun, farklı ekran yoğunlukları için farklı kaynaklarınız varsa, uygulamanızı yerelleştirmeyi planlamanızdır, bu nedenle bir çözüm değildir, sadece bazı durumlar için geçerli bir çözümdür.
Fran Marzoa

1
@Fran adlı kullanıcının yorumunu en az bin kadar oy vermeliyim :)
HGPB

22

Dosya adını iki alt çizgiyle ayırarak sanal alt klasör oluşturmaya izin veren bir tutulma eklentisi yazdım __. Proje erken aşamalarda, ama endişelenmeyin IDE'nizi çökertmeyecek

daha fazla detay burada bulunabilir, çatal çekinmeyin ve çekme istekleri göndermek:

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

resim açıklamasını buraya girin


2
Güzel! Bunu Android Studio'ya da taşıma şansınız var mı?
BVB

1
Şu anda android stüdyo bile kullanmıyorum, bu yüzden sanırım, onu taşımak için deneyimli bazı beklemek zorundayız.
Kirill Kulakov

9

Bir R dosyası oluşturmak için kullanılabilecek bir şey için tasarımcılar tarafından sağlanan organize dizin yapısını düzleştirmek için basit bir komut dosyası kullanmayı seviyorum.

Geçerli yolla drawable-hdpi'de çalıştır:

#! /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
Klasörlerin altında alt klasörler varsa komut dosyanız çalışmaz. $ {Dir} içindeki tüm '/' yerine '_' koymanız gerektiğini düşünüyorum.
Seunghoon

9

Kepçe ile android stüdyoda, kaynakları ayırmanıza izin verecek çoklu kaynak yöneticileri olabilir. Örneğin:

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

Ancak isimlerin çarpışmaması gerekir, bu da sandwiches_tunaOnRye gibi isimlere sahip olmanız gerektiği anlamına gelir, ancak tüm sandviçleriniz için ayrı bir bölümünüz olabilir.

Bu, kaynaklarınızı farklı yapılarda depolamanızı sağlar (actionbargenerator gibi otomatik olarak oluşturulan içerik için yararlıdır)


4

Sorunu kısmen çözmenin bir yolu, API Düzeyi sonekini kullanmaktır. Aynı apk içinde birden fazla alt projeyi tutmak için res / layout-v1, res / layout-v2 vb. Bu mekanizma tüm kaynak türleri için kullanılabilir.

Açıkçası, bu yalnızca API düzeylerini res / layout-v? kullanıyorsun.

Ayrıca, Android 1.5 ve 1.6'daki hatalara dikkat edin. API Düzeyi soneki hakkında Andoroid belgelerine bakın .


Bu cevabı kim düşürdüyse: Nedenini açıklayabilir misiniz? Bu mekanizma, hoş olmasa da, benim için iyi çalışıyor.
OferR

4

Kütüphane sisteminin ortaya çıkmasıyla, büyük varlık kümeleri başına kütüphane oluşturmak bir çözüm olabilir.

Tüm varlıklarda aynı adları kullanmaktan kaçınmak gerektiğinden yine de sorunludur, ancak kütüphane başına önek şeması kullanmak bu konuda yardımcı olacaktır.

Klasörler oluşturmak kadar basit değil, ama işleri aklı başında tutmaya yardımcı oluyor ...


Evet, bence bu iyi. Çekilebilir-ldpi vb. Klasörlerime ülke bayrakları eklersem o zaman onlar batacak. Tüm genel kaynaklar için bir kütüphane projesi oluşturmanın aktif olarak üzerinde çalıştığınız projedeki karmaşayı azaltmaya yardımcı olacağını düşünüyorum. Sadece 1 oyunuz var.
Tom

3

Bu durum için bir geçici çözüm vardır: resVectorvarsayılan resklasörle aynı düzeyde (örneğin) bir klasör oluşturabilirsiniz . Buraya herhangi bir drawable-xxxkaynak klasörü ekleyebilirsiniz :

resVector
-drawable
-layout
-color

Bundan sonra tek ihtiyacınız olan

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

içine build.gradle(içine android { }).


Ne yazık ki "Android" perspektifini kullanırken Android Studio'daki proje panelinde bir araya
geliyorlar

@AjahnCharles - Bu perspektifi hiç kullanmamayı tercih ederim (her neyse - her zaman 'dikkat dağıtıcı modda' çalışıyorum) ... Ama haklısın - "Android" her şeyi birleştiriyor.
Anton Derevyanko

1

Bu mükemmel yöntemler değil. Burada gösterilenle aynı şekilde uygulamanız gerekir .

Kullanabileceğiniz kod ile klasör altındaki görüntüyü de arayabilirsiniz

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

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


1

Android Studio ile Gradle bu şekilde yapabilir ( bağlantı ).

"Yapıyı Yapılandırma" paragrafındadır

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

1

ana klasör oluştur. beğen: 'res_notification_btn'

ve 'drawable' veya 'layout' gibi.

sonra 'build.gradle' içine bunu ekleyin

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?("/")
}

Tüm bunlar Cheezmeister tarafından önerilen geçici çözümü otomatikleştirmektir. Benim için çalışıyor ... downvote'u açıklamak ister misin?
Blake Miller


0

varlıklar / Ham varlık dosyalarını saklamak için kullanabilirsiniz. Buraya kaydettiğiniz dosyalar olduğu gibi bir .apk dosyasında derlenir ve özgün dosya adı korunur. Bu dizinde URI'leri kullanarak tipik bir dosya sistemiyle aynı şekilde gezinebilir ve AssetManager'ı kullanarak dosyaları bayt akışı olarak okuyabilirsiniz. Örneğin, burası dokular ve oyun verileri için iyi bir yerdir. http://developer.android.com/tools/projects/index.html


0

Alt dizinlere izin verilmez, kaynak yalnızca [a-z0-9_.] İçermelidir.

Hayır, büyük harfleriniz var ve eğik çizgi yok.


-3
  1. Çekilebilir'e sağ tıklayın
  2. Yeni ---> Dizin'i seçin
  3. Dizin adını girin. Örn: logo.png (konum varsayılan olarak zaten çekilebilir klasörü gösterecektir)
  4. Görüntüleri kopyalayıp doğrudan çekilebilir klasöre yapıştırın. Yapıştırırken listeden her görüntü için mdpi / xhdpi / xxhdpi vb. Seçeneklerinden birini seçebilirsiniz. Uygun seçeneği belirleyin ve görüntünün adını girin. Dizin adıyla aynı adı tuttuğunuzdan emin olun, yani logo.png
  5. Kalan görüntüler için de aynısını yapın. Hepsi logo.png ana klasörünün altına yerleştirilecektir.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.