Использование TypedArray в приложении для Android
Я наткнулся на код
Пример HelloGallery
ImageAdapter.java - http://developer.android.com/resources/tutorials/views/hello-gallery.html
TypedArray a = obtainStyledAttributes(R.styleable.HelloGallery);
mGalleryItemBackground = a.getResourceId(
R.styleable.HelloGallery_android_galleryItemBackground, 0);
a.recycle();
attrs.xml - http://developer.android.com/resources/tutorials/views/hello-gallery.html
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="HelloGallery">
<attr name="android:galleryItemBackground" />
</declare-styleable>
</resources>
а также код:
Пример игры Snake
TileView.java - http://developer.android.com/resources/samples/Snake/src/com/example/android/snake/TileView.html
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TileView);
mTileSize = a.getInt(R.styleable.TileView_tileSize, 12);
a.recycle();
attrs.html - http://developer.android.com/resources/samples/Snake/res/values/attrs.html
<resources>
<declare-styleable name="TileView">
<attr name="tileSize" format="integer" />
</declare-styleable>
</resources>
- Могу ли я узнать, почему им нужно получить целочисленное значение из XML? Почему бы им просто не закодировать
mGalleryItemBackground = 0;
и mTileSize = 12;
? Я предполагаю, что они хотят что-то изменить, не касаясь кода Java. Но я не вижу, чтобы какое-либо значение указывалось явно в самом XML файле. Пример кода для демонстрации цели TypedArray и context.obtainStyledAttributes очень полезен.
- Оба пытаются прочитать целое число. Почему в одном из примеров используется метод
getResourceId
, другой использует метод getInt
?
- Я ссылаюсь на TypedArray JavaDoc, но я не могу понять, что делает
recycle
?
Вернуть ранее извлеченный StyledAttributes, для последующего повторного использования.
Ответы
Ответ 1
- Могу ли я узнать, почему им нужно получить целочисленное значение из XML? Почему они не просто код mGalleryItemBackground = 0; и mTileSize = 12;?
Я думаю, что в основном это демонстрирует технику чтения атрибутов XML из конструктора View, а не для удовлетворения абсолютного требования. Если вы захотите повторно использовать свой собственный вид в другом месте (не очень-то вероятно, что-то конкретное, как Snake, которого я признаю), то это фантастически полезная вещь, чтобы иметь возможность... изменить цвет фона и т.д., Без необходимости коснитесь кода Java.
В частности, для размера плитки, который может быть полезен для чтения из XML, если существуют разные макеты для разных типов устройств... вам могут понадобиться плитки разного размера для разных комбинаций плотности и размера.
- Оба пытаются прочитать целое число. Почему используется один из примеров getResourceId, другой - используя метод getInt?
Поскольку фон галереи не является целым числом... он должен быть идентификатором ресурса (например, @drawable/foo). Да, это все равно целое число, но целое число, значение которого неизвестно до времени выполнения. Размер плитки, напротив, является постоянным значением и не требует какого-либо разрешения во время выполнения.
- Я имею в виду TypedArray JavaDoc, но я не могу понять, что такое утилизация делает?
Если есть сомнения, посмотрите на источник. Это в основном оптимизация, чтобы избежать того, что LayoutInflater должен выделять один из них для каждого вида, который он раздувает.
Ответ 2
О атрибутах стиля
В дополнение к возможности изменить это значение, не касаясь кода Java, он позволяет им применять разные стили к своему приложению в зависимости от конфигурации устройства. Вместо объявления в XML:
<com.example.android.snake.SnakeView
android:id="@+id/snake"
android:layout_width="match_parent"
android:layout_height="match_parent"
tileSize="24" />
они могут объявить эти значения в res/values/styles.xml
:
<style name="Control.SnakeViewStyle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="tileSize">24</item>
</style>
а затем обратитесь к этому стилю:
<com.example.android.snake.SnakeView
android:id="@+id/snake"
style="@styles/SnakeViewStyle" />
После разделения таких стилей они могут предоставить разные файлы styles.xml
для каждой конфигурации устройства. Например, для портретного режима может быть один res/values/styles.xml
и один res/values-land/styles.xml
для ландшафтного режима.
О ресурсах и целых числах
Если атрибут styleable объявлен как "ссылка" вместо "integer", вы должны (1) получить поддержку IDE-содержимого при написании XML для этого атрибута и (2) компилятор будет проверять, что вы не указали ссылку на несуществующий ресурс. Следовательно, для его получения вам нужно использовать getResourceId
, потому что он может сделать некоторое дополнительное разрешение для получения фактического идентификатора ресурса.
Об утилизации
Я не уверен, но, судя по коду TypedArray
, кажется, что внутри него есть механизм кэширования, а recycle()
заставляет его работать.