android Defining custom attrs

本文详细介绍了如何在Android中定义和使用自定义属性,包括属性的声明方式、类型定义及在自定义视图中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

From: http://stackoverflow.com/questions/3441396/defining-custom-attrs/3441986#3441986


531 down vote accepted

Currently the best documentation is the source. You can take a look at it here (attrs.xml).

You can define attributes in the top <resources> element or inside of a <declare-styleable> element. If I'm going to use an attr in more than one place I put it in the root element. Note, all attributes share the same global namespace. That means that even if you create a new attribute inside of a <declare-styleable> element it can be used outside of it and you cannot create another attribute with the same name of a different type.

An <attr> element has two xml attributes name and format. name lets you call it something and this is how you end up referring to it in code, e.g., R.attr.my_attribute. The format attribute can have different values depending on the 'type' of attribute you want.

  • reference - if it references another resource id (e.g, "@color/my_color", "@layout/my_layout")
  • color
  • boolean
  • dimension
  • float
  • integer
  • string
  • fraction
  • enum - normally implicitly defined
  • flag - normally implicitly defined

You can set the format to multiple types by using |, e.g., format="reference|color".

enum attributes can be defined as follows:

<attr name="my_enum_attr">
  <enum name="value1" value="1" />
  <enum name="value2" value="2" />
</attr>

flag attributes are similar except the values need to be defined so they can be bit ored together:

<attr name="my_flag_attr">
  <flag name="fuzzy" value="0x01" />
  <flag name="cold" value="0x02" />
</attr>

In addition to attributes there is the <declare-styleable> element. This allows you to define attributes a custom view can use. You do this by specifying an <attr> element, if it was previously defined you do not specify the format. If you wish to reuse an android attr, for example, android:gravity, then you can do that in the name, as follows.

An example of a custom view <declare-styleable>:

<declare-styleable name="MyCustomView">
  <attr name="my_custom_attribute" />
  <attr name="android:gravity" />
</declare-styleable>

When defining your custom attributes in XML on your custom view you need to do a few things. First you must declare a namespace to find your attributes. You do this on the root layout element. Normally there is only xmlns:android="http://schemas.android.com/apk/res/android". You must now also add xmlns:whatever="http://schemas.android.com/apk/res-auto".

Example:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:whatever="http://schemas.android.com/apk/res-auto"
  android:orientation="vertical"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

    <org.example.mypackage.MyCustomView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:gravity="center"
      whatever:my_custom_attribute="Hello, world!" />
</LinearLayout>

Finally, to access that custom attribute you normally do so in the constructor of your custom view as follows.

public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);

  TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyCustomView, defStyle, 0);

  String str = a.getString(R.styleable.MyCustomView_my_custom_attribute);

  //do something with str

  a.recycle();
}

The end. :)

share improve this answer
 
10 
Here is a sample project demonstrating custom attributes for use with a custom View: github.com/commonsguy/cw-advandroid/tree/master/Views/… –  CommonsWare Aug 9 '10 at 16:13
 
At this point, one cannot define a layout in a library package and use it in different main projects if it uses custom attributes. This is because of how the XML name space must be declared when using custom attributes. See this discussion on the Android issues list. –  Ted Hopp May 16 '11 at 18:32
7 
If you are using custom attrs from a library project: see this question: stackoverflow.com/questions/5819369/… - It seems to work if you use xmlns:my="http://schemas.android.com/apk/lib/my.namespace" - no copying attrs.xml. Note the namespace URI path must be /apk/*lib* not /apk/res. –  thom_nic Mar 1 '12 at 15:17
 
How may I resolve the issue if there exist the same attribute in two packages? Assume an attribute of <attr name="title" format="string"/> exists in package com.pack1 (in module1) and also that same attribute exists in com.pack2 (in module2) and both modules are referenced in module3 (executable). I received error Attribute "title" has already been defined. –  anonim Aug 28 '12 at 9:37
1 
@ThomNichols the apk/lib trick didn't work for me on custom attributes with reference format from a library project. What did work was to use apk/res-auto, as suggested in stackoverflow.com/a/13420366/22904 just below and also in stackoverflow.com/a/10217752 –  Giulio Piancastelli Jan 14 '13 at 11:28

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值