标签:
第一种方法,直接设置属性值,通过attrs.getAttributeResourceValue拿到这个属性值。
(1)在xml文件中设置属性值
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" tools:context=".MainActivity"> <com.example.lenovo.custom_textview.ImageTextView1 android:id="@+id/itv" iamgeBoolean="true" iamgeColor="#00ff00" iamgeDimension="100dp" iamgeEnum1="enum2" iamgeFlag="flag3" iamgeFloat="0.8" iamgeFraction="200%p" iamgeInteger="100" iamgeString="自定义属性" imageReference="@drawable/trash" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
(2)在构造函数中拿到这个值
package com.example.lenovo.custom_textview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.TextView; /** * Created by lenovo on 2016/2/18. */ public class ImageTextView1 extends TextView { public ImageTextView1(Context context) { super(context); } public ImageTextView1(Context context, AttributeSet attrs) { super(context, attrs); //可以获取所有属性值的字符串表示,int,flat,boolea,reference,string 类型能获取准确值 String iamgeDimension = attrs.getAttributeValue(null, "iamgeDimension"); int imageReference = attrs.getAttributeResourceValue(null, "imageReference", 0); if (imageReference > 0) { bitmap = BitmapFactory.decodeResource(getResources(), imageReference); } String iamgeColor = attrs.getAttributeValue(null, "iamgeColor"); String iamgeString = attrs.getAttributeValue(null, "iamgeString"); int iamgeInteger = attrs.getAttributeIntValue(null, "iamgeInteger", 0); float iamgeFloat = attrs.getAttributeFloatValue(null, "iamgeFloat", 0); boolean iamgeBoolean = attrs.getAttributeBooleanValue(null, "iamgeBoolean", false); String iamgeFraction = attrs.getAttributeValue(null, "iamgeFraction"); String iamgeEnum1 = attrs.getAttributeValue(null, "iamgeEnum1"); String iamgeFlag = attrs.getAttributeValue(null, "iamgeFlag"); StringBuffer str = new StringBuffer(); str.append("iamgeDimension= " + iamgeDimension + "\n"); str.append("imageReference= " + imageReference + "\n"); str.append("iamgeColor= " + iamgeColor + "\n"); str.append("iamgeBoolean= " + iamgeBoolean + "\n"); str.append("iamgeString= " + iamgeString + "\n"); str.append("iamgeInteger= " + iamgeInteger + "\n"); str.append("iamgeFloat= " + iamgeFloat + "\n"); str.append("iamgeFraction= " + iamgeFraction + "\n"); str.append("iamgeEnum1= " + iamgeEnum1 + "\n"); str.append("iamgeFlag= " + iamgeFlag + "\n"); setText(str.toString()); } public ImageTextView1(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private Bitmap bitmap; @Override public void onDraw(Canvas canvas) { if (bitmap != null) { Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); Rect target = new Rect(); int textHeight = (int) getTextSize(); target.left = 0; 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()); canvas.translate(target.right + 2, 0); } super.onDraw(canvas); } }
结果:
第二种方法,使用自己的命名空间,通过attrs.getAttributeResourceValue拿到这个属性值。
(1)注意在xml文件中,需要声明一个命名空间,形式一般为为http:// + 这个view的包名(其实这个名字可以随便取名只要是个名字就行,只是一般遵循这个格式)如果为http://com.example.activity,注意的是xml 中的命名空间名字要和获取属性attrs.getAttributeValue(“http://com.example.activity”, "iamgeDimension")中的命名空间名字一样
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:mobile="http://com.example.activity" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" tools:context=".MainActivity"> <com.example.lenovo.custom_textview.ImageTextView2 android:layout_width="wrap_content" android:layout_height="wrap_content" mobile:iamgeBoolean="true" mobile:iamgeColor="@color/material_blue_grey_800" mobile:iamgeDimension="100dp" mobile:iamgeEnum1="enum2" mobile:iamgeFlag="flag3" mobile:iamgeFloat="0.8" mobile:iamgeFraction="200%p" mobile:iamgeInteger="100" mobile:iamgeString="自定义属性" mobile:imageReference="@drawable/trash" /> </LinearLayout>
(2)通过attrs.getAttributeResourceValue,其中第一个参数为命名空间。
package com.example.lenovo.custom_textview; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Rect; import android.util.AttributeSet; import android.widget.TextView; /** * Created by lenovo on 2016/2/18. */ public class ImageTextView2 extends TextView { public ImageTextView2(Context context) { super(context); } //命名空间 private final String namespace = "http://com.example.activity"; String tag = "ldq"; public ImageTextView2(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public ImageTextView2(Context context, AttributeSet attrs) { super(context, attrs); //可以获取所有属性值的字符串表示,int,flat,boolea,reference,string 类型能获取准确值 String iamgeDimension = attrs.getAttributeValue(namespace, "iamgeDimension"); int imageReference = attrs.getAttributeResourceValue(namespace, "imageReference", 0); if (imageReference > 0) { bitmap = BitmapFactory.decodeResource(getResources(), imageReference); } String iamgeColor = attrs.getAttributeValue(namespace, "iamgeColor"); String iamgeString = attrs.getAttributeValue(namespace, "iamgeString"); int iamgeInteger = attrs.getAttributeIntValue(namespace, "iamgeInteger", 0); float iamgeFloat = attrs.getAttributeFloatValue(namespace, "iamgeFloat", 0); boolean iamgeBoolean = attrs.getAttributeBooleanValue(namespace, "iamgeBoolean", false); String iamgeFraction = attrs.getAttributeValue(namespace, "iamgeFraction"); String iamgeEnum1 = attrs.getAttributeValue(namespace, "iamgeEnum1"); String iamgeFlag = attrs.getAttributeValue(namespace, "iamgeFlag"); StringBuffer str = new StringBuffer(); str.append("iamgeDimension= " + iamgeDimension + "\n"); str.append("imageReference= " + imageReference + "\n"); str.append("iamgeColor= " + iamgeColor + "\n"); str.append("iamgeBoolean= " + iamgeBoolean + "\n"); str.append("iamgeString= " + iamgeString + "\n"); str.append("iamgeInteger= " + iamgeInteger + "\n"); str.append("iamgeFloat= " + iamgeFloat + "\n"); str.append("iamgeFraction= " + iamgeFraction + "\n"); str.append("iamgeEnum1= " + iamgeEnum1 + "\n"); str.append("iamgeFlag= " + iamgeFlag + "\n"); setText(str.toString()); } private Bitmap bitmap; @Override public void onDraw(Canvas canvas) { if (bitmap != null) { Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); Rect target = new Rect(); int textHeight = (int) getTextSize(); target.left = 0; 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()); canvas.translate(target.right + 2, 0); } super.onDraw(canvas); } }
结果:
第三种方法,通过自定义attrs.xml来实现 ,通过context.obtainStyledAttributes(attrs,R.styleable.ImageTextView).getString()方法拿到属性值
(1)自定义一个attrs.xml文件
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="ImageTextView"> <attr name="iamgeDimension" format="dimension" /> <attr name="imageReference" format="reference" /> <attr name="iamgeColor" format="color" /> <attr name="iamgeString" format="string" /> <attr name="iamgeInteger" format="integer" /> <attr name="iamgeFloat" format="float" /> <attr name="iamgeBoolean" format="boolean" /> <attr name="iamgeFraction" format="fraction" /> <attr name="iamgeEnum1"> <enum name="enum1" value="1"></enum> <enum name="enum2" value="2"></enum> </attr> <attr name="iamgeFlag"> <flag name="flag1" value="1"></flag> <flag name="flag2" value="2"></flag> <flag name="flag3" value="3"></flag> </attr> </declare-styleable> </resources>
(2)在xml文件中使用这一属性,注意此时命名空间的书写规范。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:ImageTextView="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center" tools:context=".MainActivity"> <com.example.lenovo.custom_textview.ImageTextView3 android:layout_width="wrap_content" android:layout_height="wrap_content" ImageTextView:iamgeDimension="100dp" ImageTextView:imageReference="@drawable/trash" ImageTextView:iamgeColor="@color/material_blue_grey_800" ImageTextView:iamgeString="自定义属性" ImageTextView:iamgeInteger="100" ImageTextView:iamgeFloat="0.8" ImageTextView:iamgeBoolean="true" ImageTextView:iamgeFraction="200%p" ImageTextView:iamgeEnum1="enum2" ImageTextView:iamgeFlag="flag3" /> </LinearLayout>
(3)在代码中使用context.obtainStyledAttributes获得属性值
<attr name="iamgeString" format="string" />
指定为一个declare-styleable,而在declare-styleable 下的attr (即各属性)Android 的ADT 将会自动生成为declare-styleable的name 名字加上“_”加上对应attr(即属性名称)的名称,如上(ImageTextView_String)我们要得到Text 就需要R.styleable.ImageTextView_String,这一点的话可以看看R.java生成文件
package com.example.lenovo.custom_textview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.widget.TextView; /** * Created by lenovo on 2016/2/18. */ public class ImageTextView3 extends TextView { public ImageTextView3(Context context) { super(context); } public ImageTextView3(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ImageTextView); double iamgeDimension = typedArray.getDimension(R.styleable.ImageTextView_iamgeDimension, 0); int imageReference = typedArray.getResourceId(R.styleable.ImageTextView_imageReference, 0); bitmap = BitmapFactory.decodeResource(getResources(), imageReference); Drawable drawable = typedArray.getDrawable(R.styleable.ImageTextView_imageReference); double iamgeColor = typedArray.getColor(R.styleable.ImageTextView_iamgeColor, 0); String iamgeString = typedArray.getString(R.styleable.ImageTextView_iamgeString); double iamgeInteger = typedArray.getInteger(R.styleable.ImageTextView_iamgeInteger, 0); double iamgeFloat = typedArray.getFloat(R.styleable.ImageTextView_iamgeFloat, 0); boolean iamgeBoolean = typedArray.getBoolean(R.styleable.ImageTextView_iamgeBoolean, false); // ImageTextView:iamgeFraction="200%" // ImageTextView:iamgeFraction="200%p" // double iamgeFraction = typedArray.getFraction(R.styleable.ImageTextView_iamgeFraction, 4, 5, 1); // 1)如果mageTextView_iamgeFraction 是200%,那么result就是:200%*4 ~ 8 // 2)如果mageTextView_iamgeFraction 是200%p,那么result就是:200%*5 ~ 10 double iamgeFraction = typedArray.getFraction(R.styleable.ImageTextView_iamgeFraction, 4, 5, 1); double iamgeEnum1 = typedArray.getInteger(R.styleable.ImageTextView_iamgeEnum1, 0); double iamgeFlag = typedArray.getInteger(R.styleable.ImageTextView_iamgeFlag, 0); typedArray.recycle(); //调用结束后务必调用recycle()方法,否则这次的设定会对下次的使用造成影响 StringBuffer str = new StringBuffer(); str.append("iamgeDimension= " + iamgeDimension + "\n"); str.append("imageReference= " + imageReference + "\n"); str.append("iamgeColor= " + iamgeColor + "\n"); str.append("iamgeBoolean= " + iamgeBoolean + "\n"); str.append("iamgeString= " + iamgeString + "\n"); str.append("iamgeInteger= " + iamgeInteger + "\n"); str.append("iamgeFloat= " + iamgeFloat + "\n"); str.append("iamgeFraction= " + iamgeFraction + "\n"); str.append("iamgeEnum1= " + iamgeEnum1 + "\n"); str.append("iamgeFlag= " + iamgeFlag + "\n"); setText(str.toString()); } public ImageTextView3(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } private Bitmap bitmap; @Override public void onDraw(Canvas canvas) { if (bitmap != null) { Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); Rect target = new Rect(); int textHeight = (int) getTextSize(); target.left = 0; 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()); canvas.translate(target.right + 2, 0); } super.onDraw(canvas); } }
结果:
总结:
这是这两种为Android 注册 属性的使用方法,那么两者有什么区别呢?
在这里我认为起码有五点,大家可以找找看还有什么区别:
种种都说明,第二种写法更具规范性,功能更性,代码编写 也更优雅。
标签:
原文地址:http://www.cnblogs.com/ldq2016/p/5200365.html