有人可以解释一下这个例子中的 declare-styleable XML 标签以及其使用背后的理论吗?

10

我正在阅读《Beginning Android 4 Development》,第5章中谈到了GalleryImageViews,并引入了declare-styleable XML标签,但没有解释其目的.. 我也在参考资料中试图找到一些信息,但没有成功..例如我们有以下内容:

res/values/attrs.xml

<?xml version=”1.0” encoding=”utf-8”?> 
<resources>
    <declare-styleable name=”Gallery1”>
        <attr name=”android:galleryItemBackground” />
    </declare-styleable>
</resources>

example.java

->

example.java

public class GalleryActivity extends Activity {
[...]
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState);    
        setContentView(R.layout.main);
        Gallery gallery = (Gallery) findViewById(R.id.gallery1);
        gallery.setAdapter(new ImageAdapter(this)); 
        [...]
    }

    [...]

    public class ImageAdapter extends BaseAdapter {
        [...]
        int itemBackground;

        public ImageAdapter(Context c) {
            context = c;
            //---setting the style---
            TypedArray a = obtainStyledAttributes(
            R.styleable.Gallery1); 
            itemBackground = a.getResourceId(
                        R.styleable.Gallery1_android_galleryItemBackground, 0);
            a.recycle();
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            ImageView imageView;
            [...]
            imageView.setBackgroundResource(itemBackground);
            return imageView; 
        }
    }
}

我已经仔细阅读了代码,但仍不太理解定义这个名为 Gallery1 的可样式化对象时,只使用一个带有 name 属性的 attr 子元素的目的是什么。你能帮帮我吗?这个 galleryItemBackground 是系统提供的还是我们自己定义的?在这段代码中,我们在做什么?

非常感谢您提供的任何帮助!

1个回答

15
这个标签是预制的 Android 属性集合 R.Styleable 中的一部分,可以通过属性名称前缀 android: 的 xml 命名空间来区分自定义 styleable 标签。
这个特定的属性被描述为:
优选的画廊项背景。应该将其设置为 Adapter 提供的任何 View 的背景。
然而,你是正确的,自定义属性标签不仅需要属性名称,还需要知道其类型,例如在 attrs.xml 文件中添加一个自定义元素可能会像这样:
<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="MyCustomView"> 
        <attr name=”android:galleryItemBackground” />              
        <attr name="myCustomAttr" format="string" /> 
    </declare-styleable> 
</resources>

Note the lack of the android: namespace on the second attribute as well. Edit:

是否有官方文档页面深入解释了这个Styleables?

查看R.attr(单击链接)以获取包含在Android中的各种属性。您不需要为它们声明类型,因为它们已经被声明了。要知道特定属性已声明哪种类型,请找到您感兴趣的属性的描述。galleryItemBackground是一个引用另一个资源的引用;其他可能性是布尔值、浮点数、颜色等。
其他参考资料:Andtoid使用<declare-styleable>标签创建AttributeSetTypedArray用于解析AttributeSet
如果上面的代码只是为了获取视图背景的默认Drawable,那么我能否使用getDrawable(android.R.attr.galleryItemBackground)设置变量itemBackground?
在这个例子中,当只有一个属性时很难看出这种模式的有用性。你可以做你要求的事情,这可能更容易。然而,这种构造是Android将UI的“外观”与其“功能”分离的口号的一部分,它允许您在xml中设置某些属性,而不必在代码中完成所有工作。以View类为例,它有超过30个属性可以在xml文件中设置(大小、填充、可单击、可聚焦等);制作自定义View子类的人可以在xml中设置其中的一些、全部或没有属性,在创建视图时,这些属性会自动处理。如果需要,也有代码等效设置属性,但想象一下,每次你子类化View都必须在代码中设置所有属性,而没有在xml中设置它们的选项。

如果你只是想为自己的类制作完全相同的资源,那也是一件微不足道的事情,但是如果你不覆盖这些内置样式,使用内置样式将提供与 Android 框架外观和感觉匹配的默认资源。

希望这可以帮到你。


我仍然有一些困难理解书中在我写的主要帖子中的Java代码片段正在做什么... 代码itemBackground = a.getResourceId(R.styleable.Gallery1_android_galleryItemBackground, 0)正在检索一个ID,但是返回哪个ID,因为在XML中我只定义了一个attr name?是否有任何官方文档页面深入解释这个Styleables?谢谢回答。 - Gianni Costanzi
如果上面的代码和使用styleable Gallery1的目的只是为了获取视图背景的默认Drawable,那么我不能使用getDrawable(android.R.attr.galleryItemBackground)来设置变量itemBackground吗?你能再解释一下吗? - Gianni Costanzi
1
嗨,请查看对原回答的编辑。我希望它们能解决您的问题。 - happydude
非常感谢您的回答... 我仍然有一些难以理解 declare-styleable 背后逻辑的困难.. <attr name=”android:galleryItemBackground” /> 到底对 styleable MyCustomView 是在说什么呢?它是在说:你有一个属性 galleryItemBackground,其值与 android:galleryItemBackground 相同吗?很抱歉,但我读得越多,就越感到困惑 O_o - Gianni Costanzi
谢谢,我喜欢你的解释。现在我明白它是如何工作的了。 - Aron Lorincz
这个能用来在运行时更改主题吗? - RoCkDevstack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接