typedarray自定义属性的使用 .

本文介绍如何在Android中自定义属性并应用于视图,通过创建attrs.xml文件来定义自定义样式,并在视图类中使用自定义属性进行实例化。以MyView为例,展示如何设置文字颜色和大小,同时在XML布局文件中引用并应用这些自定义属性。

转自:http://blog.youkuaiyun.com/fuuckwtu/article/details/6522090

 

今天本来在AlertDialog源码还有theme,想修改一下AlertDialog的背景,主题什么的,结果看到一个帖子,讲如何修改AlertDialog的背景,看的我晕乎乎的,很多类不知道,typedarray就是其中一个。

于是我网上找了点资料看看。

我们平常在xml文件里面定义,设置控件属性,android:text android:size 这类的,有木有可以自定义的呢

答案是肯定的。android这个做的还是比较人性化的,可以自定义属性,自定义实现风格,主题,之类的。

首先在values文件下,新建一个attrs.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<resources>

   <declare-styleable name="MyView">
       <attr name="textColor" format="color"/>
       <attr name="textSize" format="dimension"/>
   </declare-styleable>
</resources>

 <declare-styleable >估计是个自定义标签吧。

换了别的不行

然后使用自定义属性来设置view

package cn.edu.wtu;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.AttributeSet;
import android.view.View;

public class MyView extends View {

 private Paint               mPaint;
 private Context             mContext;
 private static final String mStr ="welcome to typed-array";
 
 public MyView(Context context){
  super(context);
  mPaint = new Paint();
 }
 public MyView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
  mPaint = new Paint();
  TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView);
//  获取属性,0xFFFFFFFF 16是默认值
  int   textColor = a.getColor(R.styleable.MyView_textColor, 0xFFFFFFFF);
  float textSize  = a.getDimension(R.styleable.MyView_textSize, 16);
  mPaint.setTextSize(textSize);
  mPaint.setColor(textColor);
//  回收,为以后再使用
  a.recycle();
 }
 
 protected void onDraw(Canvas canvas){
  super.onDraw(canvas);
  mPaint.setStyle(Style.FILL);
  canvas.drawRect(10, 10, 100, 100, mPaint);
  mPaint.setColor(Color.BLUE);
  canvas.drawText(mStr,10,110,mPaint);
 }
}
 

注意一下R.styleable.MyView,R.styleable.MyView_textColor,这些命名。

在main.xml文件里面使用myview这个控件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:test="http://schemas.android.com/apk/res/cn.edu.wtu"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
    >
 <TextView 
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:text="@string/hello"
    />
    <cn.edu.wtu.MyView android:layout_width="fill_parent"
                       android:layout_height="fill_parent"
                       test:textSize="20sp"
                       test:textColor="#ffffffff"
    />
   
</LinearLayout>
PS:xmlns:test="http://schemas.android.com/apk/res/cn.edu.wtu"
cn.edu.wtu是我的包名,是我的学校的域名

test是名字。test:textColor="#ffffffff"
 

package cn.edu.wtu;

import android.app.Activity;
import android.app.Dialog;
import android.os.Bundle;

public class Alert extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }


   
}

 

Android 中,自定义属性(Custom Attributes)允许开发者为自定义 View 定义可配置的 XML 属性。这些属性可以在布局文件中使用,并通过 `TypedArray` 在代码中读取。 其中,`getDrawable()` 是 `TypedArray` 提供的一个方法,用于从资源中获取一个 `Drawable` 对象。它会根据你在 XML 中设置的属性值(比如 `@drawable/xxx` 或 `@mipmap/xxx`)自动解析并返回对应的 `Drawable` 实例。 --- ### ✅ 使用步骤详解 #### 1. 定义自定义属性 首先,在 `res/values/attrs.xml` 文件中定义一个可以接收 Drawable 资源的属性: ```xml <!-- res/values/attrs.xml --> <resources> <declare-styleable name="CustomImageView"> <attr name="customSrc" format="reference" /> <attr name="customTint" format="color" /> </declare-styleable> </resources> ``` - `customSrc`:用于接收图片资源(如 drawable/mipmap),类型是 `reference`,表示引用一个资源。 - `format="reference"` 支持 `@drawable/...`, `@mipmap/...`, `@android:drawable/...` 等。 --- #### 2. 在布局 XML 中使用自定义属性 ```xml <!-- activity_main.xml --> <com.example.CustomImageView android:layout_width="wrap_content" android:layout_height="wrap_content" app:customSrc="@drawable/ic_launcher_foreground" app:customTint="#FF5722" xmlns:app="http://schemas.android.com/apk/res-auto" /> ``` > 注意:需要引入命名空间 `xmlns:app="..."` --- #### 3.自定义 View 中使用 TypedArray 获取 Drawable ```java // CustomImageView.java public class CustomImageView extends View { private Drawable mDrawable; private int mTintColor = Color.TRANSPARENT; public CustomImageView(Context context, AttributeSet attrs) { super(context, attrs); // 获取自定义属性 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomImageView); // 使用 getDrawable() 获取 drawable 资源 mDrawable = a.getDrawable(R.styleable.CustomImageView_customSrc); // 如果未设置,默认为空或设置默认图 if (mDrawable == null) { mDrawable = ContextCompat.getDrawable(context, R.drawable.default_image); } // 获取着色颜色 mTintColor = a.getColor(R.styleable.CustomImageView_customTint, Color.TRANSPARENT); // 回收 TypedArray 防止内存泄漏 a.recycle(); // 设置 tint(示例) if (mDrawable != null && mTintColor != Color.TRANSPARENT) { mDrawable.setTint(mTintColor); } } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if (mDrawable != null) { mDrawable.setBounds(0, 0, getWidth(), getHeight()); mDrawable.draw(canvas); } } } ``` --- ### 🔍 关键点解释 - `a.getDrawable(...)`: - 会自动处理各种资源引用(包括矢量图、PNG、SVG 等)。 - 在 API 21+ 上支持 VectorDrawable。 - 推荐使用 `ContextCompat.getDrawable()` 作为后备方案。 - **必须调用 `a.recycle()`**: - `TypedArray` 是池化对象,不回收可能导致内存问题。 - 兼容性建议: ```java Drawable drawable = a.getDrawable(R.styleable.CustomImageView_customSrc); if (drawable == null) { drawable = AppCompatResources.getDrawable(context, R.drawable.fallback); } ``` 使用 `AppCompatResources.getDrawable()` 可更好地兼容 VectorDrawable 在低版本 Android 上的加载。 --- ### 🛠️ 扩展:支持主题属性(Theme-aware) 如果你希望支持类似 `?attr/colorPrimary` 这样的主题属性,应使用 `obtainStyledAttributes` 的完整形式: ```java TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.CustomImageView, 0, 0); ``` 这样也能正确解析主题中的引用。 --- ### ❗注意事项 | 问题 | 建议 | |------|------| | 不要忘记 `recycle()` | 否则可能引发内存泄漏 | | 使用 AppCompat 兼容库 | 更好支持 VectorDrawable | | 检查返回值是否为 null | 用户可能未设置该属性 | --- ### ✅ 总结 `TypedArray.getDrawable()` 是安全且推荐的方式来从自定义属性中加载图像资源。结合 `attrs.xml` 和构造函数中的 `AttributeSet`,你可以灵活地创建高度可配置的自定义 View。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值