Чи може в директорії Android, що містить файл, містити підкаталоги?


496

У документації на Android SDK усі приклади, які використовуються з синтаксисом @ dravable / my_image xml, безпосередньо стосуються зображень, які зберігаються в каталозі res / dravable в моєму проекті.

Мені цікаво, чи явно не добре створити підкаталог у межах каталогу, який можна переглядати.

Наприклад, якщо у мене був такий макет каталогу:

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

Чи можу я посилатись на зображення бутерброда з салату з тунця як на @ dravable / бутерброди / tunaOnRye

Або я повинен тримати ієрархію рівною в каталозі, який можна отримати.


16
Зауважте, що великі літери не дозволені в каталозі res.
Тайлер

1
Ви можете зробити це тільки з Gradle: stackoverflow.com/a/19859379
Яір Kukiełka

2
Чи можливо мати каталоги SIBLING для малювання , з функцією Dravable ? Отже, res / tanks / drawble- [hdpi .. тощо] тощо?
Fattie

Відповіді:


545

Ні, механізм ресурсів не підтримує вкладені папки в каталозі, що малюється, тому так - вам потрібно тримати цю ієрархію рівною.

Ви показали макет каталогів, що жодне із зображень не буде доступним.

З моїх власних експериментів видно, що наявність підпапки з будь-якими елементами в ній, всередині res/drawableпапки, спричинить збій компілятора ресурсів - запобігаючи R.javaправильному генеруванню файлу.


135
Що стосується Android 2.2, це не викликає помилки компілятора, але будь-які підкаталоги ігноруються при створенні класу R. Це дійсно гарно і ускладнює управління великими проектами. = /
Нік Рейман

69
Повністю згоден. Їм потрібно придумати краще рішення, що підтримує підпапки. Це не може бути таким важким.
znq

13
Сподіваюсь, це скоро буде вирішено, я отримав понад 100 активів, і навіть тоді я зашифрував деякі з них. Загальна нічна кобила намагається керувати будь-яким незначно складним проектом.
Еміль

14
Це відповідний випуск у трекері проблем Android: code.google.com/p/android/isissue/detail?id=2018
espinchi

44
проклинаю вас андроїд
Уїтніленд

149

Вирішення, яке я використовую (а той, який видається на користь самого Android), полягає в тому, щоб замінити підкреслення на косому напрямку, щоб ваша структура виглядала приблизно так:

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

Підхід вимагає, щоб ви були ретельними у своєму іменуванні і не полегшували складання самих файлів (якщо ви вирішили, що напої та бутерброди справді мають бути всі " food", вам доведеться робити масове перейменування, а не просто переміщення їх до каталогу); але складність вашої логіки програмування не страждає надто погано порівняно з еквівалентом структури папок.

Така ситуація справді гасить. Android - це змішана сумка чудових і жахливих дизайнерських рішень. Ми можемо лише сподіватися, що остання порція з усією поспішністю позбудеться бур’янів :)


31
Лише зауважте, що великі літери заборонені в папці, що малюється. Я отримую помилку: "Неправильне ім'я файлу: повинен містити лише [a-z0-9_.]"
Jason Axelson

5
+1 за "змішану сумку чудових і жахливих дизайнерських рішень"
Brent Faust

1
Навряд чи вирішення: скоріше, «що ти повинен зробити, щоб не зійти з глузду». Смішно обмежуватися одним каталогом.
RichieHH

35

Власне, на Android Studio це можливо. Ви можете мати вкладені ресурси, як показано тут :

введіть тут опис зображення

Існує також плагін для групи ресурсів тут .


Привіт, @android розробник! Я намагався додати це у файл build.gradle: sourceSets {main {res {srcDir 'src / main / res / dravable / ic-toggle'}}}, але у мене є "Uri не зареєстрований" для xmlns : android = " schemas.android.com/apk/res/android . Що може бути?
AlexKost

@AlexKost Я насправді спробував це лише один раз. Я не досвідчений з цим достатньо, щоб допомогти. Вибачте.
андроїд розробник

@RahulMandaliya Хоча це можливо, я пропоную не використовувати його.
андроїд розробник

@androiddeveloper Чому ні?
Джош Хансен

1
@JoshHansen Це безладно.
андроїд розробник

34

Так - це смокче :) Однак ви можете користуватися папкою активів і мати там підкаталоги та завантажувати зображення таким чином.


6
проблема полягає не лише в папці, що малюється, але і в папці макета :( в папці мого макета міститься більше 100 файлів xml, і мені важко відкрити правильний макет xml у цьому.
anticafe

Крім інших заперечень, ресурси можуть бути легко локалізовані, але в AFAIK немає вбудованого механізму для активів l10n.
Fran Marzoa

@anticafe використовуйте "Перейти до ресурсу" у вашому IDE (Eclipse: CTRL + SHIFT + R, IDEA / Android Studio: CTRL + SHIFT + N)
TWiStErRob

23

Використовуйте папку "Активи".

зразок коду:

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

image = BitmapFactory.decodeStream(is);

5
Єдине питання цього методу полягає в тому, що існує багато більше домашніх завдань із використанням растрових зображень. Ресурсна система Android робить набагато кращу роботу з управління пам'яттю. Навіщо ви перебудовувати систему управління пам’яттю, коли Android це вже робить? Якщо у нього більше 100 зображень, це багато завантаження та випуску растрових зображень.
Преподобний Тайлер

18
Це справжня проблема, якщо ви плануєте локалізувати свою програму, також якщо у вас є різні ресурси для різної щільності екрана, тому це не є рішенням, а лише вирішенням дійсного для деяких випадків.
Fran Marzoa

1
Мені потрібно дати коментар @Fran принаймні тисячу нагород :)
HGPB

22

Я написав плагін eclipse, який дозволяє створити віртуальну папку, розділивши ім'я файлу на дві підкреслення __. Проект знаходиться на ранніх стадіях, але не хвилюйтесь, він не розбить вашу IDE

Більш детальну інформацію можна знайти тут, сміливо роздрібнюйтесь та надсилайте запити на тягнення:

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

введіть тут опис зображення


2
Приємно! Будь-який шанс перенести це також на Android Studio?
БВБ

1
Наразі я навіть не використовую андроїд-студію, тому, мабуть, нам доведеться чекати, коли хтось із досвідчених переправить його.
Кирило Кулаков

9

Мені подобається використовувати простий скрипт, щоб вирівняти організовану структуру каталогів, надану дизайнерами, на те, що можна використовувати для створення файлу R.

Запустити з поточним контуром у Dravable-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 {
    ....
    android.sourceSets {
        main.res.srcDirs = ['src/main/extraresdirnamed_sandwiches', 'src/main/res']
    }
    ....
}

Однак імена не повинні стикатися, це означає, що вам все одно доведеться мати такі імена, як sandwiches_tunaOnRye, але ви зможете мати окремий розділ для всіх своїх сендвічів.

Це дозволяє зберігати свої ресурси в різних структурах (корисно для автоматично створеного контенту, наприклад, панелі активізації)


4

Один із способів частково подолати проблему - використовувати суфікс рівня API. Я використовую res / layout-v1, res / layout-v2 тощо, щоб утримувати кілька підпроектів в одному apk. Цей механізм можна використовувати для всіх типів ресурсів.

Очевидно, що це може бути використано лише у тому випадку, якщо ви орієнтуєтесь на рівні API вище Res / layout-v? ви використовуєте.

Також слідкуйте за помилками в Android 1.5 та 1.6. Дивіться документацію Andoroid про суфікс API рівня .


Кому хто принизив цю відповідь: Чи можете ви пояснити, чому? Цей механізм, хоча і не дуже, добре працює для мене.
OferR

4

З появою бібліотечної системи створення рішення для великої кількості активів може бути бібліотекою.

Це все ще проблематично, оскільки потрібно уникати використання однакових імен у всіх ресурсах, але використання префіксальної схеми для кожної бібліотеки повинно допомогти у цьому.

Це не так просто, як створювати папки, але це допомагає зберігати речі здоровими ...


Так, я думаю, це добре. Якщо я додаю прапори країни до моїх папок Dravable-ldpi тощо, вони будуть завалені. Я думаю, що створення бібліотечного проекту для всіх загальних ресурсів допоможе зменшити безлад у проекті, над яким ви активно працюєте. Здивований, що у вас є лише 1 пропозиція.
Том

3

У цій ситуації є вирішення: ви можете створити resVector(наприклад) папку на тому ж рівні, що і resпапка за замовчуванням . Там ви можете додати будь-які drawable-xxxпапки ресурсів:

resVector
-drawable
-layout
-color

Після цього все, що вам потрібно - це додати

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

у ваш build.gradleфайл (всередині android { }).


На жаль, вони зливаються разом на панелі проектів в Android Studio при використанні точки зору "Android" :(
AjahnCharles

@AjahnCharles - я вважаю за краще взагалі не використовувати цю перспективу (все одно - я завжди працюю в режимі "відволікання без уваги") ... Але ти маєш рацію - "Android" об'єднує все.
Антон Дерев’янко

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 Build досить проста, не потрібні додатки, лише невелике редагування файлів.

https://stackoverflow.com/a/22426467/618419


1

Gradle з Android Studio могли це зробити так ( посилання ).

Це в параграфі "Налаштування структури"

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

1

створити папку в основному. як-от: 'res_notification_btn'

і створити папку дерева. дюйма, як 'Dravable' або '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. Це працює для мене ... подбаєш, щоб пояснити сутічку?
Блейк Міллер


0

активи / Ви можете використовувати його для зберігання необроблених файлів активів. Файли, які ви зберігаєте тут, компілюються у файл .apk як є, а вихідне ім'я файлу зберігається. Ви можете орієнтуватися в цьому каталозі так само, як у типовій файловій системі, використовуючи URI, і читати файли як потік байтів за допомогою AssetManager. Наприклад, це вдале місце для текстур та даних про ігри. http://developer.android.com/tools/projects/index.html


0

Підкаталоги не дозволені, ресурс повинен містити лише [a-z0-9_.].

Ні у вас великих літер, ні нахилів вперед.


-3
  1. Клацніть правою кнопкою миші на Dravable
  2. Виберіть Новий ---> Каталог
  3. Введіть ім'я каталогу. Напр .: logo.png (місце розташування вже буде відображати папку, що витягується, за замовчуванням)
  4. Скопіюйте та вставте зображення безпосередньо в папку, що перетягується. Під час вставки ви можете вибрати mdpi / xhdpi / xxhdpi тощо для кожного із зображень зі списку. Виберіть відповідний варіант та введіть назву зображення. Не забудьте зберегти те саме ім'я, що й ім'я каталогу, тобто logo.png
  5. Зробіть те ж саме для решти зображень. Усі вони будуть розміщені в головній папці logo.png.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.