android 定制组件的三种方式

本文详细介绍了如何通过继承原有组件、组合已有元素或完全重写组件来实现Android系统的自定义功能。以一个具体示例展示了如何在布局文件中使用自定义命名空间来定制图像TextView,并解析配置文件中的属性。

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

虽然Android 系统提供了大量的组件, 但也可以通过定制组件的方式来实现更复杂、更特殊的功能,

可以通过如下 3 种方式来定制组件

1  继承原有的组件   2 组合原有的组件   3 完全重写组件

先看一个示例: 继承原有的组件————带图像的TextView

 实现定制组件的一个重要环节就是读取配置文件中相应标签的属性值

 先看布局文件main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:mobile="http://net.blogjava.mobile" android:orientation="vertical"
 android:layout_width="fill_parent" android:layout_height="fill_parent">

 <net.blogjava.mobile.widget.IconTextView
  android:layout_width="fill_parent" android:layout_height="wrap_content"
  android:text="第一个笑脸" mobile:iconSrc="@drawable/small" />

</LinearLayout>

注意在所有的标签属性如android:text 都有一个命名空间(android),  这是系统命名空间. 也可以使用用户自定义命名空间,例如 使用命名空间 mobile, 并其中定义一个属性mobilce:src

public class IconTextView extends TextView  {
 //  命名空间的值
 private final String namespace = "http://net.blogjava.mobile";
 //  图像资源ID
 private int resourceId = 0;
 private Bitmap bitmap;
 public IconTextView(Context context, AttributeSet attrs)   {
  super(context, attrs);
  resourceId = attrs.getAttributeResourceValue(namespace, "iconSrc", 0);
  if (resourceId > 0)
   bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
 }
 @Override
 protected void onDraw(Canvas canvas)   {
  if (bitmap != null)   {
   //  从原图上截取图像的区域,在本例中为整个图像
   Rect src = new Rect();
   //  将截取的图像复制到bitmap上的目标区域,在本例中与复制区域相同
   Rect target = new Rect();
   src.left = 0;
   src.top = 0;
   src.right = bitmap.getWidth();
   src.bottom = bitmap.getHeight();
   int textHeight = (int) getTextSize();
   target.left = 0;
   //  计算图像复制到目录区域的纵坐标。由于TextView中文本内容并不是从最顶端开始绘制的,因此,需要重新计算绘制图像的纵坐标
   target.top = (int) ((getMeasuredHeight() - getTextSize()) / 2) + 1;
   target.bottom = target.top + textHeight;
   //  为了保证图像不变形,需要根据图像高度重新计算图像的宽度
   target.right = (int) (textHeight * (bitmap.getWidth() / (float) bitmap
     .getHeight()));
   //  开始绘制图像
   canvas.drawBitmap(bitmap, src, target, getPaint());
   //  将TextView中的文本向右移动一定的距离(在本例中移动了图像宽度加2个象素点的位置)
   canvas.translate(target.right + 2, 0);
  }
  super.onDraw(canvas);
 }
}

需要注意

1.  这里要指定命名空间的值,该值就是 xmlns:mobile="http://net.blogjava.mobile",引号内部分,

2. 如果在配置组件的属性指定了命名空间,需要定义 resourceId = attrs.getAttributeResourceValue(namespace, "iconSrc", 0);, 其中每一个参数是命名空间的值,第二个参数是不带命名空间的属性名

如图所示

具体代码请参见 ch04_icontextview  工程 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值