Можно ли создать представление из XML-файла в каталоге ресурсов? - PullRequest
2 голосов
/ 30 марта 2011

У меня есть приложение, и размещение всех макетов в папке res / layout становится довольно большим и сложным в управлении. Я хотел бы иметь папки для всех макетов. Я прочитал, что в папке макета не может быть подкаталогов, но они могут быть в папке ресурсов. Итак, мой вопрос, как мне получить доступ к файлу и установить его в качестве моего представления из файла в каталоге ресурсов? Что-то вроде следующего

int assetId = getAssets().open("main.xml");
setContentView(assetId)

Будет ли работать приведенный выше код? Как бы я установить этот XML-файл для моего просмотра? Спасибо.

Ответы [ 4 ]

1 голос
/ 11 августа 2012

Этого можно добиться, используя собственный сценарий и запустив его до выполнения сборки. Похоже, Android ничего не игнорирует в подкаталогах макетов, поэтому вы можете спокойно помещать в них свои файлы. Следующий скрипт ruby ​​(написанный для Linux, но легко конвертируемый на другие платформы) затем удалит все, что не является каталогом в res / layout /, и скопирует каждый файл из подкаталогов в res / layout /:

#!/usr/bin/ruby</p> <pre><code>require "fileutils" def collect_files(directory) FileUtils.cd(directory) FileUtils.rm(Dir.entries(directory).reject{|x| File.directory?(x)}) #Remove all layout files in base dir files_to_copy=Dir.glob("**/*").reject{|x| File.directory?(x)} files_to_copy.each{|x| print "Copying #{x} to #{directory}\n"} FileUtils.cp(files_to_copy, directory) #Copy all files in subdir into base dir end if ARGV[0]!=nil && File.directory?(ARGV[0]) xml_dir=ARGV[0] layout_dir="#{xml_dir}/layout" collect_files(layout_dir) else puts("Must specify a valid directory!") end

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

Если вы работаете с Eclipse, вы можете настроить внешний инструмент, который вы сможете добавить к своим сборщикам позже. Просто откройте «Выполнить» -> «Внешние инструменты» -> «Конфигурации внешних инструментов» и создайте новый инструмент в разделе «Программы». Вот скриншот моих настроек:

External tool configuration

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

Теперь вы можете добавить инструмент в конструкторы для вашего проекта. Выберите ваш проект и откройте Project -> Properties. Теперь выберите пункт «Строители» и нажмите «Импорт». Вы должны увидеть свой инструмент там, если вы определили его успешно. Он должен быть запущен до завершения процесса сборки, поэтому обязательно переместите его в начало списка. Вот как это должно выглядеть, когда вы закончите:

Project Builders configuration

Теперь вы просто перемещаете файлы макетов в подкаталоги (но следите за коллизиями имен, помните, что все файлы окажутся в одном каталоге для сборки!) И создайте свой проект. Вы увидите, как они волшебным образом появятся в корне / res / layout /, когда вы сделаете это, и ваше приложение должно будет нормально работать.

Caveat Scriptor: Если вы указываете несколько макетов или что-то еще, что использует больше, чем просто каталог / res / layout /, вам нужно будет расширить этот скрипт или добавить инструмент несколько раз для разных каталогов, чтобы справиться с этим. Лично я не использую эту технику, и поэтому не видел, где она падает, но выполнил тест с помощью основного приложения Hello World для Android с парой макетов в некоторых подкаталогах.

Кроме того, мой скрипт сломается, если будет использоваться с путями, содержащими пробелы!

0 голосов
/ 30 марта 2011

Я не думаю, что это хорошая идея, и, вероятно, просто не работает.Что сделал бы фреймворк, если бы думал, что ему нужна версия вашего макета в формате hdpi?

Вы можете попытаться найти основную причину распространения вашего макета:

  • МожетВы разрабатываете лучшие соглашения по присвоению имен для своих макетов?
  • Не могли бы вы реорганизовать определенные макеты, чтобы больше компонентов могли использовать одни и те же макеты?
  • Вы вручную управляете ориентациями вместо того, чтобы полагаться на -portrait и -landscape?
0 голосов
/ 30 марта 2011

Краткий ответ: это невозможно сделать таким образом. Основные причины:

  • В папке res/layout все файлы .xml предварительно скомпилированы, поэтому Android может использовать их в качестве ресурсов. В папке assets все файлы остаются нетронутыми, поэтому приложение может читать их как обычные файлы. (В вашем примере кода вы получаете InputStream, а не идентификатор ресурса).
  • Android автоматически управляет макетами, расположенными в папке res/layout, в поисках наиболее подходящих для текущего разрешения экрана, ориентации, локали и т. Д.
0 голосов
/ 30 марта 2011

layoutinflator может помочь вам Смотри сюда Что делает LayoutInflater в Android?

...