Intereting Posts
Android – Как отслеживать приложение. Возобновляет только при выходе и возвращении в приложение? Можно ли получить доступ только для чтения к базе данных sqlite в apk? Как включить изображение в интерфейс Android? Сохранение наложения изображений с захваченным снимок камеры ActiveAndroid Отношение «многие ко многим» Ограничить длину текста EditText в Android Почему я не могу исключить исключение при использовании тернарного оператора Android Toast начался с сервиса только один раз Android EditText Multiline с SoftInputMode adjustPan Android SDK эквивалентен для просмотраWillAppear (iOS)? Устаревший метод PagerAdapter.instantiateItem () Перемещение и исчезновение строк кода; Проблема с XML-редактором Eclipse Как вы получаете / устанавливаете громкость мультимедиа (не громкость мелодии звонка) в Android? Обновить контрольную панель от AsyncTaskLoader? Не удается завершить установку из-за противоречивой зависимости. Ошибка Eclipse для ADT

Может ли папка Android Layout содержать подпапки?

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

Например,

layout -- layout_personal -- personal_detail.xml -- personal_other.xml --layout_address -- address1.xml -- address2.xml 

Подобно тому же, мы хотели бы иметь подпапки для большого приложения, так есть ли способ сделать это внутри проекта Android?

Я могу создать подпапки layout-personal и layout_address внутри папки макета, но когда придет время получить доступ к файлу макета xml, используя R.layout. _ , В это время внутри меню не появляется всплывающее окно xml.

Solutions Collecting From Web of "Может ли папка Android Layout содержать подпапки?"

Вы можете сделать это с помощью градиента. Я сделал демонстрационный проект, показывающий, как это сделать.

Хитрость заключается в использовании способности градиента объединить несколько папок ресурсов и установить папку res, а также вложенные подпапки в блоке sourceSets.

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

Ниже приведен блок sourceSets из файла build.gradle из демонстрации. Обратите внимание, что вложенные папки объявляются первыми.

 sourceSets { main { res.srcDirs = [ 'src/main/res/layouts/layouts_category2', 'src/main/res/layouts', 'src/main/res' ] } } 

Изображение вложенных ресурсов

Кроме того, прямой родительский файл ваших фактических файлов ресурсов (pngs, xml layouts и т. Д.) Все равно должен соответствовать спецификации .

Ответ – нет.

Я хотел бы обратить ваше внимание на эту книгу Pro Android 2, в которой говорится:

Также стоит отметить несколько ограничений в отношении ресурсов. Во-первых, Android поддерживает только линейный список файлов в предопределенных папках под res. Например, он не поддерживает вложенные папки в папке макета (или в других папках под res).

Во-вторых, есть несколько сходств между папкой с ресурсами и необработанной папкой под res. Обе папки могут содержать необработанные файлы, но файлы в raw считаются ресурсами, а файлы в активах – нет.

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

Я просто хотел добавить фантастический ответ eskis для людей, у которых проблемы. (Примечание. Это будет работать и будет выглядеть как отдельные каталоги внутри «проекта», а не «андроид», к сожалению).

Протестировано следующим. BuildToolsVersion = 23.0.0 gradle 1.2.3 и 1.3.0

Вот как я получил свою работу с уже построенным проектом.

  1. Скопируйте все XML-файлы из своего каталога макета и поместите их в каталог на рабочем столе или что-то для резервного копирования.
  2. Удалите всю директорию макета (убедитесь, что вы скопировали все с шага 1 !!!)
  3. Щелкните правой кнопкой мыши каталог res и выберите команду new>.
  4. Назовите этот новый каталог «layouts». (Это может быть то, что вы хотите, но это не будет каталог «фрагмент» или «активность», который будет представлен позже).
  5. Щелкните правой кнопкой мыши новый каталог «layouts» и выберите команду new>. (Это будет имя типа XML-файлов, которые вы будете иметь в нем, например, «фрагменты» и «действия»).
  6. Щелкните правой кнопкой мыши каталог «фрагмент» или «деятельность» (примечание: это не обязательно «фрагмент» или «действия», это то, что я использую в качестве примера) и снова выберите новую> директорию и назовите этот каталог «макет». (Примечание: Это ДОЛЖНО быть названо «макет» !!! Очень важно).
  7. Поместите XML-файлы в новый каталог «layout» из резервной копии, сделанной на рабочем столе.
  8. Повторите шаги 5 – 7 для как можно большего количества настраиваемых каталогов.
  9. Как только это будет завершено, зайдите в свой файл gradly.build и создайте определение sourceSets, подобное этому … (Убедитесь, что 'src / main / res / layouts' & 'src / main / res' всегда являются нижними двумя! Как я показываю ниже).

     sourceSets { main { res.srcDirs = [ 'src/main/res/layouts/activities', 'src/main/res/layouts/fragments', 'src/main/res/layouts/content', 'src/main/res/layouts', 'src/main/res' ] } } 
  10. Прибыль $$$$

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

Картинки стоят больше, чем слов.

Структура каталога

Невозможно, но папка макета сортируется по имени. Итак, я добавляю имена файлов макетов с именами пакетов. Например, для двух пакетов «покупка» и «игра»:

 buying_bought_tracks.xml buying_buy_tracks.xml playing_edit_playlist.xml playing_play_playlist.xml playing_show_playlists.xml 

Теперь с Android Studio и Gradle вы можете иметь несколько папок ресурсов в своем проекте. Позволяет организовать не только ваши файлы макета, но и любые ресурсы.

Это не совсем подпапка, но может разделять части вашего приложения.

Конфигурация выглядит так:

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

Проверьте документацию .

Я использую плагин Android File Grouping для Android Studio. Он не позволяет создавать подпапки, но он может отображать ваши файлы и ресурсы, так как они находятся в разных папках. И это именно то, что я хотел.

Вы можете установить плагин «Android File Grouping» на

Окна:

Android Studio -> Файл -> Настройки -> Плагины.

Mac:

Android Studio -> Android Studio Tab (вверху слева) -> Настройки -> Плагины -> Установка плагина JetBrains ..

Для Mac я смог проверить его и не смог найти плагин. Поэтому я загрузил плагин и использовал параметр « Install plugin from disk из приведенной выше настройки.

Я думаю, что самым изящным решением этой проблемы (учитывая, что вложенные папки не разрешены) является добавление имен файлов с именем папки, в которую вы разместили бы ее внутри. Например, если у вас есть куча макетов для Activity, Fragment или просто общего вида, называемого «местами», вы должны просто добавить его с помощью place_my_layout_name. По крайней мере, это решает проблему их организации таким образом, что их легче найти в среде IDE. Это не самое удивительное решение, но это лучше, чем ничего.

Маленькая проблема

Я могу получить подпапки, следуя главному ответу на этот вопрос.

Однако по мере роста проекта у вас будет много подпапок:

 sourceSets { main { res.srcDirs = [ 'src/main/res/layouts/somethingA', 'src/main/res/layouts/somethingB', 'src/main/res/layouts/somethingC', 'src/main/res/layouts/somethingD', 'src/main/res/layouts/somethingE', 'src/main/res/layouts/somethingF', 'src/main/res/layouts/somethingG', 'src/main/res/layouts/somethingH', 'src/main/res/layouts/...many more', 'src/main/res' ] } } 

Не большая проблема, но:

  • Это некрасиво, так как список становится очень длинным.
  • Вам нужно изменить app/build.gradle каждый раз, когда вы добавляете новую папку.

улучшение

Поэтому я написал простой метод Groovy для захвата всех вложенных папок:

 def getLayoutList(path) { File file = new File(path) def throwAway = file.path.split("/")[0] def newPath = file.path.substring(throwAway.length() + 1) def array = file.list().collect { "${newPath}/${it}" } array.push("src/main/res"); return array } 

Вставьте этот метод вне блока android {...} в вашем app/build.gradle .


Как использовать

Для такой структуры:

 <project root> ├── app <---------- TAKE NOTE ├── build ├── build.gradle ├── gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle 

Используйте его так:

 android { sourceSets { main { res.srcDirs = getLayoutList("app/src/main/res/layouts/") } } } 

Если у вас есть такая структура:

 <project root> ├── my_special_app_name <---------- TAKE NOTE ├── build ├── build.gradle ├── gradle ├── gradle.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle 

Вы будете использовать его так:

 android { sourceSets { main { res.srcDirs = getLayoutList("my_special_app_name/src/main/res/layouts/") } } } 

объяснение

getLayoutList() принимает a relative path в качестве аргумента. relative path относится к корню проекта. Поэтому, когда мы вводим "app/src/main/res/layouts/" , он возвращает все имена подпапок в виде массива, который будет точно таким же, как:

  [ 'src/main/res/layouts/somethingA', 'src/main/res/layouts/somethingB', 'src/main/res/layouts/somethingC', 'src/main/res/layouts/somethingD', 'src/main/res/layouts/somethingE', 'src/main/res/layouts/somethingF', 'src/main/res/layouts/somethingG', 'src/main/res/layouts/somethingH', 'src/main/res/layouts/...many more', 'src/main/res' ] 

Вот сценарий с комментариями для понимания:

 def getLayoutList(path) { // let's say path = "app/src/main/res/layouts/ File file = new File(path) def throwAway = file.path.split("/")[0] // throwAway = 'app' def newPath = file.path.substring(throwAway.length() + 1) // +1 is for '/' // newPath = src/main/res/layouts/ def array = file.list().collect { // println "filename: ${it}" // uncomment for debugging "${newPath}/${it}" } array.push("src/main/res"); // println "result: ${array}" // uncomment for debugging return array } 

Надеюсь, поможет!

Проверьте скрипт Bash Flatten Folder, который преобразует иерархию папок в одну папку

Если вы разрабатываете Linux или Mac-поле, обходным решением будет создание подпапок, которые включают символические ссылки на ваши макеты. Просто используйте команду ln с -s

Ln -s PATH_TO_YOUR_FILE

Проблема заключается в том, что папка Layout все еще содержит все XML-файлы. Но вы можете выбрать их, используя подпапки. Это самое близкое, к тому, что вы хотели бы иметь.

Я просто читал, что это может работать и с Windows, если вы используете Vista или позже. Это mklink . Просто Google, он никогда не использовал его сам.

Другая проблема заключается в том, что если вы открыли файл и попытаетесь открыть его снова, плагин выдает исключение NULL Pointer Exception. Но он не вешает трубку.

Хотя все предложения для нескольких наборов ресурсов могут работать, проблема в том, что текущая логика подключаемого модуля Android Studio Gradle не будет обновлять файлы ресурсов после их изменения для вложенных наборов ресурсов. Текущая реализация пытается проверить каталоги ресурсов с помощью startsWith (), поэтому структура каталога, которая является вложенной (т.е. src / main / res / layout / layouts и src / main / res / layout / layouts_category2), выберет src / main / res / Layout / layouts последовательно и никогда не обновлять изменения. Конечным результатом является то, что вам нужно каждый раз перестраивать / очищать проект.

Я отправил патч на https://android-review.googlesource.com/#/c/157971/, чтобы попытаться помочь решить все проблемы.

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

 sourceSets.each { def rootResDir = it.res.srcDirs[0] def getSubDirs = { dirName -> def layoutsDir = new File(rootResDir, dirName) def subLayoutDirs = [] if (layoutsDir.exists()) { layoutsDir.eachDir { subLayoutDirs.add it } } return subLayoutDirs } def resDirs = [ "anims", "colors", "drawables", "drawables-hdpi", "drawables-mdpi", "drawables-xhdpi", "drawables-xxhdpi", "layouts", "valuess", ] def srcDirs = resDirs.collect { getSubDirs(it) } it.res.srcDirs = [srcDirs, rootResDir] } 

Как это делается на практике?

Например, я хочу создать подпапку с именем activity for layout , добавить строку любым именем в переменную resDirs такую ​​как layouts , тогда файл xml макета следует поместить в res\layouts\activity\layout\xxx.xml .

Если я хочу создать подпапку с именем selectors для drawable , добавьте строку любым именем в переменной resDirs например drawables , тогда выталкиваемый XML-файл следует поместить в res\drawables\selectors\drawable\xxx.xml .

Имя папки, например layouts и drawables , определяется в переменной resDirs , это может быть любая строка. Вся вложенная папка, созданная вами, такая как activity или selectors , считается такой же, как папка res . Поэтому в папке selectors мы должны дополнительно создать drawable папку и поместить файлы xml в папку с возможностью рисования, после этого град может распознавать файлы xml как обычно доступные.

Ну, короткий ответ – нет. Но вы определенно можете иметь несколько папок res . Это, я думаю, так же близко, как вы можете получить подпапки для папки layout . Вот как вы это делаете.

Я сделал это, чтобы создать отдельную папку res на том же уровне, что и фактическая папка res в вашем проекте, тогда вы можете использовать ее в своих приложениях build.gradle

 android { //other stuff sourceSets { main.res.srcDirs = ['src/main/res', file('src/main/layouts').listFiles()] } } 

Пример структуры папок

То каждая вложенная папка вашей новой папки res может быть чем-то относящимся к каждому конкретному экрану или что-то в вашем приложении, и каждая папка будет иметь свой собственный layout / drawable / values т. Д., Сохраняя организованные вещи, и вам не нужно вручную обновлять файл градиента, как некоторые Из этих других ответов.