android 中自定义View中的参数

当给的widget不能满足使用的时候就需要自定义。用xml配置view十分方便。如果我们希望通过xmlview中传递参数,就得多写点东西。下面写的例子是对TextView的一个扩展。TextView提供了设置四个方向图片的功能,但是无法设置图片的大小就不太好了。本文实现了一个新的类TextViewPlus,对TextView进行扩展,让其能够在xml中配置图片大小。

改变图片大小不能在xml中做,但是可以在java代码中做。先取得文本周围四个方向的图片Drawable[],然后分别调用drawable.setBounds()设置大小,最后再放回TextView中。然后问题就出在怎么让类读取xml中信息上了。

代码一共分为3部分: 1.main.xml布局文件; 2. TextViewPlus类; 3. attrs.xml文件,用于让系统识别自定义属性。

1.    在目录res/values下创建attrs.xml文件如下:其中name是名称,format是数据类型。系统会自动生成R文件中name的变量。第5~12行写的需要在布局文件中设置的参数。


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

3.  <resources>  

4.    

5.      <declare-styleable name="TextViewPlus">  

6.          <attr name="left_height" format="dimension" />  

7.          <attr name="left_width" format="dimension" />  

8.          <attr name="right_height" format="dimension" />  

9.          <attr name="right_width" format="dimension" />  

10.         <attr name="top_height" format="dimension" />  

11.         <attr name="top_width" format="dimension" />  

12.         <attr name="bottom_height" format="dimension" />  

13.         <attr name="bottom_width" format="dimension" />  

14.     </declare-styleable>  

15.  

16. </resources>  


2.    TextViewPlus : TypedArray可看成是一个Map<Integerkey, Object value>。通过遍历key,来获得各个value。而这个key的值是写在R.stylable中的。


1.  /** 

2.   * 添加可以设置drawable大小的功能 

3.   *  

4.   * @author Daniel 

5.   * @version 创建时间: Jul 26, 2012 5:28:59 PM 

6.   * */  

7.  public class TextViewPlus extends TextView {  

8.      // 需要从xml中读取的各个方向图片的宽和高  

9.      private int leftHeight = -1;  

10.     private int leftWidth = -1;  

11.     private int rightHeight = -1;  

12.     private int rightWidth = -1;  

13.     private int topHeight = -1;  

14.     private int topWidth = -1;  

15.     private int bottomHeight = -1;  

16.     private int bottomWidth = -1;  

17.   

18.     public TextViewPlus(Context context) {  

19.         super(context);  

20.     }  

21.   

22.     public TextViewPlus(Context context, AttributeSet attrs) {  

23.         super(context, attrs);  

24.         // super一定要在我们的代码之前配置文件  

25.         init(context, attrs, 0);  

26.     }  

27.   

28.     public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {  

29.         super(context, attrs, defStyle);  

30.         // super一定要在我们的代码之前配置文件  

31.         init(context, attrs, defStyle);  

32.     }  

33.   

34.     /** 

35.      * 初始化读取参数 

36.      * */  

37.     private void init(Context context, AttributeSet attrs, int defStyle) {  

38.         // TypeArray中含有我们需要使用的参数  

39.         TypedArray a = context.obtainStyledAttributes(attrs,  

40.                 R.styleable.TextViewPlus, defStyle, 0);  

41.         if (a != null) {  

42.             // 获得参数个数  

43.             int count = a.getIndexCount();  

44.             int index = 0;  

45.             // 遍历参数。先将indexTypedArray中读出来,  

46.             // 得到的这个index对应于attrs.xml中设置的参数名称在R中编译得到的数  

47.             // 这里会得到各个方向的宽和高  

48.             for (int i = 0; i < count; i++) {  

49.                 index = a.getIndex(i);  

50.                 switch (index) {  

51.                 case R.styleable.TextViewPlus_bottom_height:  

52.                     bottomHeight = a.getDimensionPixelSize(index, -1);  

53.                     break;  

54.                 case R.styleable.TextViewPlus_bottom_width:  

55.                     bottomWidth = a.getDimensionPixelSize(index, -1);  

56.                     break;  

57.                 case R.styleable.TextViewPlus_left_height:  

58.                     leftHeight = a.getDimensionPixelSize(index, -1);  

59.                     break;  

60.                 case R.styleable.TextViewPlus_left_width:  

61.                     leftWidth = a.getDimensionPixelSize(index, -1);  

62.                     break;  

63.                 case R.styleable.TextViewPlus_right_height:  

64.                     rightHeight = a.getDimensionPixelSize(index, -1);  

65.                     break;  

66.                 case R.styleable.TextViewPlus_right_width:  

67.                     rightWidth = a.getDimensionPixelSize(index, -1);  

68.                     break;  

69.                 case R.styleable.TextViewPlus_top_height:  

70.                     topHeight = a.getDimensionPixelSize(index, -1);  

71.                     break;  

72.                 case R.styleable.TextViewPlus_top_width:  

73.                     topWidth = a.getDimensionPixelSize(index, -1);  

74.                     break;  

75.                 }  

76.             }  

77.  

78.             // 获取各个方向的图片,按照:左--- 的顺序存于数组中  

79.             Drawable[] drawables = getCompoundDrawables();  

80.             int dir = 0;  

81.             // 0-left; 1-top; 2-right; 3-bottom;  

82.             for (Drawable drawable : drawables) {  

83.                 // 设定图片大小  

84.                 setImageSize(drawable, dir++);  

85.             }  

86.             // 将图片放回到TextView  

87.             setCompoundDrawables(drawables[0], drawables[1], drawables[2],  

88.                     drawables[3]);  

89.   

90.         }  

91.   

92.     }  

93.   

94.     /** 

95.      * 设定图片的大小 

96.      * */  

97.     private void setImageSize(Drawable d, int dir) {  

98.         if (d == null) {  

99.             return;  

100.         }  

101.   

102.         int height = -1;  

103.         int width = -1;  

104.         // 根据方向给宽和高赋值  

105.         switch (dir) {  

106.         case 0:  

107.             // left  

108.             height = leftHeight;  

109.             width = leftWidth;  

110.             break;  

111.         case 1:  

112.             // top  

113.             height = topHeight;  

114.             width = topWidth;  

115.             break;  

116.         case 2:  

117.             // right  

118.             height = rightHeight;  

119.             width = rightWidth;  

120.             break;  

121.         case 3:  

122.             // bottom  

123.             height = bottomHeight;  

124.             width = bottomWidth;  

125.             break;  

126.         }  

127.         // 如果有某个方向的宽或者高没有设定值,则不去设定图片大小  

128.         if (width != -1 && height != -1) {  

129.             d.setBounds(00, width, height);  

130.         }  

131.     }  

132. }  

 

 

3.    布局文件:第3行中的org.daniel.android.tes是应用程序的包名(AndroidManifest.xml中的package)myview为自己定义的命名空间。17~18行就是使用attrs.xml中定义的属性了。3行中的命名空间一定要与17~18行的前缀对应的。

1.  <?xml version="1.0" encoding="utf-8"?>  

2.  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  

3.      xmlns:myview="http://schemas.android.com/apk/res/org.daniel.android.test"  

4.      android:layout_width="fill_parent"  

5.      android:layout_height="fill_parent"  

6.      android:orientation="vertical" >  

7.    

8.      <org.daniel.android.test.TextViewPlus  

9.          android:layout_width="wrap_content"  

10.         android:layout_height="wrap_content"  

11.         android:layout_gravity="center"  

12.         android:drawableBottom="@drawable/ic_launcher"  

13.         android:drawableLeft="@drawable/ic_launcher"  

14.         android:drawableRight="@drawable/ic_launcher"  

15.         android:drawableTop="@drawable/ic_launcher"  

16.         android:text="here is a test"  

17.         myview:left_height="30dp"  

18.         myview:left_width="30dp" />  

19.   

20. </LinearLayout>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值