2009-07-03 6 views
411

В документации по SDK для Android все примеры, используемые с синтаксисом @ drawable/my_image xml, напрямую адресуют изображения, которые хранятся в каталоге res/drawable в моем проекте.Может ли выставляемый каталог Android содержать подкаталоги?

Мне интересно, если явным образом не могу создать вспомогательный каталог в выпадающем каталоге.

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

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

Могу ли я сослаться на изображение бутерброд салат из тунца, как @ вытяжке/сэндвичи/tunaOnRye

Или я должен держать иерархия в выпадающем каталоге.

+14

Обратите внимание, что заглавные буквы не разрешены в каталоге res. – Tyler

+1

Вы можете сделать это только с Gradle: http://stackoverflow.com/a/19859379 –

+2

Можно ли иметь ** Sibling ** каталоги вытяжки с растяжимой функциональностью? Итак, res/tanks/drawble- [hdpi .. etc] и так далее? – Fattie

ответ

462

Нет, механизм ресурсов не поддерживает подпапки в выпадающем каталоге, поэтому да - вам нужно сохранить эту иерархию плоской.

Представленный вами макет каталога не приведет к тому, что ни одно из изображений не будет доступно.

Из моих собственных экспериментов кажется, что наличие вложенной папки с любыми элементами в ней в папке res/drawable приведет к сбою компилятора ресурсов - предотвращение корректной генерации файла R.java.

+115

Начиная с Android 2.2, это не вызывает ошибки компилятора, но при создании класса R любые подкаталоги игнорируются. Это действительно засасывает и затрудняет управление крупными проектами. =/ –

+56

Полностью согласен. Им нужно придумать лучшее решение, поддерживающее подпапки. Это не может быть так сложно. – znq

+13

Надеюсь, это скоро будет решено, у меня есть более 100 активов, и даже тогда я закодировал некоторые из них. Всего ночная кобыла пытается управлять любым незначительно сложным проектом. – Emile

30

Да - это сосать :) Однако вы можете использовать папку с ресурсами и иметь подкаталоги там и загружать изображения таким образом.

+5

проблема заключается не только в папке с выделением, но и в папке макета :(В папке моего макета содержится более 100 файлов xml, и мне трудно открыть правильный xml-макет в этом. – anticafe

+0

медленнее, чем использовать механизм ресурсов? я думаю, так ... –

+0

Appart для других возражений, ресурсы могут быть легко локализованы, но AFAIK не существует встроенного механизма для l10n. –

4

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

Очевидно, что это можно использовать, только если вы настроите уровни API выше res/layout-v? ты используешь.

Также обратите внимание на ошибку в Android 1.5 и 1.6. See Andoroid documentation about the API Level suffix.

+0

Кому-то, кто понизил этот ответ: Можете ли вы объяснить, почему? Этот механизм, хотя и не очень хорош, хорошо работает для меня. – OferR

135

Обойти я использую (и один сам Android, кажется, благоволит) является, по существу, заменить подчеркивание для прямых косых черт, так что ваша структура будет выглядеть примерно так:

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

подход требует вы должны быть дотошными в своем наименовании и не намного облегчаете судить о самих файлах (если вы решили, что напитки и бутерброды должны действительно быть «food», вам придется делать массовое переименование, а не просто перемещать их в каталог); но сложность вашей логики программирования не страдает плохо по сравнению с эквивалентом структуры папок.

Эта ситуация действительно отстойная. Android - это смешанная сумка замечательных и страшных дизайнерских решений. Мы можем только надеяться, что последняя часть будет отброшена со всей поспешностью :)

+25

Просто обратите внимание, что заглавные буквы не разрешены в рисоваемом Я получаю сообщение об ошибке: «Недопустимое имя файла: должно содержать только [a-z0-9_.]» –

+6

Давай, человек знает, что «индейка» идет со швейцаром. – theblang

+4

+1 для «смешанной сумки замечательных и страшных дизайнерских решений» –

22

Используйте папку с ресурсами.

Пример код:

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

image = BitmapFactory.decodeStream(is); 
+5

Единственная проблема с этим методом заключается в том, что существует много домашней работы, связанной с использованием растровых изображений. Система ресурсов Android делает намного лучшую работу по управлению памятью. Зачем вам перестраивать систему управления памятью, когда Android уже делает это? Искренне, если у него более 100 изображений, это большая загрузка и выпуск растровых изображений. –

+16

Реальная проблема заключается в том, что вы планируете локализовать свое приложение, также если у вас разные ресурсы для разных плотностей экрана, поэтому это не решение, а лишь обходное решение, применимое только для некоторых случаев. –

+1

Мне нужно дать комментарий @Fran не менее тысячи upvotes :) – HGPB

9

Я хотел бы использовать простой скрипт для выравнивания организованной структуры каталогов, представленных дизайнерами к чему-то, что может быть использовано для генерации файла 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

Ваш скрипт не будет работать, если есть подпапки под папками. Я думаю, вам нужно заменить все «/» на «_» в $ {dir}. – Seunghoon

2

С появлением библиотечной системы, создание библиотеки за большой набор активов может быть решением.

Это все еще проблематично, так как нужно избегать использования одинаковых имен во всех активах, но с помощью префиксной схемы в библиотеке должно помочь это.

Это не так просто, как возможность создавать папки, но это помогает держать вещи в своем уме ...

+0

Да, я думаю, это хорошо. Если я добавлю флаги страны в мои папки с рисунком-ldpi и т. Д., Тогда они будут загружены. Я думаю, что создание проекта библиотеки для всех общих ресурсов поможет уменьшить беспорядок в проекте, над которым вы активно работаете. Удивленный у вас есть только 1 upvote. – Tom

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

Все это делает автоматизацию обходного пути, предложенного Cheezmeister. Это работает для меня ... позаботиться об объяснении нисходящего потока? –

1

Это не совершенные методы. Вы должны реализовать тот же путь, что и дисплей here.

Вы также можете вызвать изображение в папке с помощью кода вы можете использовать

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

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

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

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

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

enter image description here

+2

Ницца! Есть ли шанс портировать это на Android Studio? – BVB

+0

В настоящее время я даже не использую андроид-студию, поэтому, я думаю, нам придется подождать, пока кто-нибудь испытает ее. –

+0

Для андроид-студии смотрите это http://stackoverflow.com/a/22426467/618419 – Captnwalker1

1

Не мое, но я нашел эту тему, если смотреть на этот вопрос, если вы используете систему Android Studio и Gradle построить свой довольно легко нет плагинов необходимо лишь небольшой файл сборки редактирования

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

0

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

8

В андроидской студии с градием у вас может быть несколько директоров источников, которые позволят вам разделить ресурсы. Например:

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

Однако имена не должны сталкиваться означает, что вы все равно должны иметь имена, такие как sandwiches_tunaOnRye, но вы будете в состоянии иметь отдельный раздел для всех ваших бутербродов.

Это позволяет хранить свои ресурсы в различных структурах (полезно для автоматического контент, такой как actionbargenerator)

1

Gradle с Android Studio может сделать это таким образом (link).

Это в пункте "Настройка структуры"

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

На самом деле, на Android Studio можно. Вы можете иметь вложенные ресурсы, как показано here:

enter image description here

Существует также плагин для группы ресурсов here.

+0

Привет, разработчик @android! Я попытался добавить это в build.gradle файл: sourceSets { основные { Рез { SRCDIR 'SRC/основные/RES/рисуем/IC-тумблеры' }} }, но у меня есть " Uri не зарегистрирован «для xmlns: android =» http://schemas.android.com/apk/res/android. Что может быть? – AlexKost

+0

@AlexKost Я действительно пробовал это только один раз.Я не испытываю этого достаточно, чтобы помочь. Сожалею. –

+0

спасибо человеку, хорошая работа –

0

Подкаталоги запрещены, ресурс должен содержать только [a-z0-9_.].

У вас нет заглавных букв и нет косых черт.

1

создать папку в основном. как:. '' Res_notification_btn

и создать папку дерева в как 'Drawable' или 'макет'

затем в 'build.gradle' добавить

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

Существует обходной путь для этого ситуация: вы можете создать папку resVector (например) на том же уровне, что и папка по умолчанию res. Там вы можете добавить любые drawable-xxx папки ресурсов там:

resVector 
-drawable 
-layout 
-color 

После этого все, что вам нужно, это добавить

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

в файл build.gradle (внутри android { }).

+0

К сожалению, они объединяются в панели проектов в Android Studio при использовании перспективы «Android» :( – AjahnCharles

Смежные вопросы