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

1

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

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

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

  • 0
    привет @skoko, ты достиг этой точки? У меня то же самое
Теги:
assets

4 ответа

0
Лучший ответ

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

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

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

#!/usr/bin/ruby

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

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

Если вы запускаете Eclipse, вы можете настроить внешний инструмент, который вы можете добавить к своим разработчикам позже. Просто откройте Run → External Tools → External Tools Configurations и создайте новый инструмент в разделе "Программы". Вот пример моих настроек:

Изображение 174551

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

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

Изображение 174551

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

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

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

0

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

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню