在Android应用程序中使用TypedArray

Che*_*eng 28 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();
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

并且代码:

蛇游戏示例

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();
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)
  1. 我可以知道他们为什么需要从XML获取整数值吗?他们为什么不只是编码mGalleryItemBackground = 0;而且mTileSize = 12;?我的猜测是,他们希望能够在不触及Java代码的情况下改变一些东西.但是,我没有看到XML文件本身明确指定任何值.用于演示TypedArray和context.obtainStyledAttributes目的的代码示例非常有用.
  2. 两者都试图读取整数.为什么其中一个例子是使用getResourceId技术,另一个是使用getInt技术?
  3. 我指的是TypedArray JavaDoc,但我很难理解它是什么recycle

返回先前检索的StyledAttributes,以供以后重复使用.

Reu*_*ton 22

  1. 我可以知道他们为什么需要从XML获取整数值吗?为什么他们不只是编码mGalleryItemBackground = 0; 和mTileSize = 12;?

我认为这主要是为了演示从View构造函数中读取XML属性的技术,而不是满足绝对要求.如果你想在其他地方重新使用你的自定义视图(不太可能像Snake那样特别容易的话),那么这是一个非常有用的东西,能够做到...改变背景颜色等而不必触摸Java代码.

特别是对于图块大小,如果不同的设备类型有不同的布局,那么从XML读取可能很有用......您可能需要不同尺寸的图块用于不同的密度和尺寸组合.

  1. 两者都试图读取整数.为什么其中一个例子是使用getResourceId技术,另一个是使用getInt技术?

因为图库背景不是整数...所以它应该是资源标识符(例如@ drawable/foo).是的,它仍然是一个整数,而是一个整数,其值是未知的,直到运行时.相反,tile大小是一个常量值,不需要任何类型的运行时解析.

  1. 我指的是TypedArray JavaDoc,但我很难理解什么是回收呢?

如有疑问,请查看来源.它基本上是一种优化,以避免LayoutInflater必须为它膨胀的每个视图分配其中一个.


Fix*_*int 10

关于可设置的属性

除了能够在不触及Java代码的情况下更改该值之外,它还允许它们根据设备配置将不同的样式应用于其应用程序.而不是在XML中声明:

<com.example.android.snake.SnakeView
    android:id="@+id/snake"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tileSize="24" />
Run Code Online (Sandbox Code Playgroud)

他们可以在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>
Run Code Online (Sandbox Code Playgroud)

然后参考那种风格:

<com.example.android.snake.SnakeView
    android:id="@+id/snake"
    style="@styles/SnakeViewStyle" />
Run Code Online (Sandbox Code Playgroud)

在分离这样的样式后,它们可以styles.xml为每个设备配置提供不同的文件.例如,可能有一个res/values/styles.xml用于纵向模式,另一个res/values-land/styles.xml用于横向模式.

关于资源和整数

如果将一个styleable属性声明为"reference"而不是"integer",那么(1)在为该属性编写XML时会获得IDE内容辅助,(2)编译器会检查您是否未提供对不存在的引用资源.因此,为了得到它你需要使用getResourceId,因为它可能会做一些额外的解决来获得实际的资源ID.

关于回收

我不太确定,但从代码判断TypedArray,似乎内部有一些缓存机制,并recycle()使其工作.