Android 自定义RadioButton 实现文字上下左右方向的图片大小设置

代码效果


前两天一个朋友提出的需求,用RadioButton实现的应用页面切换。效果图如下


这种想法很好,但也出现了两个问题:其一,界面扩展性很差;其二,RadioButton设置图片后,无法在xml中设置图片大小,导致布局不美观。那么问题来了?如何设置这个图片的大小。

百度常见的回答是,在代码中动态设置图片大小。然后设置在布局上。代码如下:

[java] view plaincopy

  1. mRadioButton.setCompoundDrawables(left, top, right, bottom);  

 参数类型都是Drawable,分别是左,上,右,下四个方向要显示的Drawable图片我们查看setCompoundDrawables(left, top, right, bottom)方法:有这样的一段说明:

Sets the Drawables (if any) to appear to the left of, above, to the right of, and below the text. Use null if you do not want a Drawable there. The Drawables must already have hadDrawable.setBounds called.

意思是说,用次方法之前,需要用Drawable.setBounds()方法来为Drawable图片设置边界,即要显示的大小。

达到同样效果的还有一个方法:

[java] view plaincopy

  1. setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);  

进入源码查看该方法的具体实现:

[java] view plaincopy

  1. public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top,  

  2.             Drawable right, Drawable bottom) {  

  3.   

  4.         if (left != null) {  

  5.             left.setBounds(00, left.getIntrinsicWidth(), left.getIntrinsicHeight());  

  6.         }  

  7.         if (right != null) {  

  8.             right.setBounds(00, right.getIntrinsicWidth(), right.getIntrinsicHeight());  

  9.         }  

  10.         if (top != null) {  

  11.             top.setBounds(00, top.getIntrinsicWidth(), top.getIntrinsicHeight());  

  12.         }  

  13.         if (bottom != null) {  

  14.             bottom.setBounds(00, bottom.getIntrinsicWidth(), bottom.getIntrinsicHeight());  

  15.         }  

  16.         setCompoundDrawables(left, top, right, bottom);  

  17.     }  

 原来这个方法,同样调用了setCompoundDrawables(left, top, right, bottom)方法,并在调用之前,给传入的图片设置了边界范围,即图片自身的大小。再看这个方法的注释:

Sets the Drawables (if any) to appear to the left of, above, to the right of, and below the text. Use null if you do not want a Drawable there. The Drawables' bounds will be set to their intrinsic bounds.

意思是说:设置drawable图像显示在文字的上下左右的位置,如果不想设置,则传递null参数。drawable图片的边界是其自身固定的边界范围。

OK,一切明了,那么是不是我们自己改变这个边界值参数,就能达到改变图片大小的目的呢?答案是肯定的。下面,是见证奇迹的时刻。
首先,我们要在xml中用到设置图片大小的属性,这里用drawableSize来显示。然后分别给出四个方向的图片属性。最后我们得到的attrs.xml文件的内容为:

[html] view plaincopy

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

  2. <resources>  

  3.       

  4.     <declare-styleable name="MyRadioButton">  

  5.           

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

  7.         <attr name="drawableTop" format="reference"/>  

  8.         <attr name="drawableLeft" format="reference"/>  

  9.         <attr name="drawableRight" format="reference"/>  

  10.         <attr name="drawableBottom" format="reference"/>  

  11.           

  12.     </declare-styleable>  

  13.       

  14. </resources>  


规定了属性后,我们需要在代码中获取到这些属性,从而来在视图中显示我们需要的情况。

获取属性的代码如下:

[java] view plaincopy

  1. Drawable drawableLeft = null, drawableTop = null, drawableRight = null, drawableBottom = null;  

  2.         TypedArray a = context.obtainStyledAttributes(attrs,  

  3.                 R.styleable.MyRadioButton);  

  4.   

  5.         int n = a.getIndexCount();  

  6.         for (int i = 0; i < n; i++) {  

  7.             int attr = a.getIndex(i);  

  8.             Log.i("MyRadioButton""attr:" + attr);  

  9.             switch (attr) {  

  10.             case R.styleable.MyRadioButton_drawableSize:  

  11.                 mDrawableSize = a.getDimensionPixelSize(R.styleable.MyRadioButton_drawableSize, 50);  

  12.                 Log.i("MyRadioButton""mDrawableSize:" + mDrawableSize);  

  13.                 break;  

  14.             case R.styleable.MyRadioButton_drawableTop:  

  15.                 drawableTop = a.getDrawable(attr);  

  16.                 break;  

  17.             case R.styleable.MyRadioButton_drawableBottom:  

  18.                 drawableRight = a.getDrawable(attr);  

  19.                 break;  

  20.             case R.styleable.MyRadioButton_drawableRight:  

  21.                 drawableBottom = a.getDrawable(attr);  

  22.                 break;  

  23.             case R.styleable.MyRadioButton_drawableLeft:  

  24.                 drawableLeft = a.getDrawable(attr);  

  25.                 break;  

  26.             default :  

  27.                     break;  

  28.             }  

  29.         }  

  30.         a.recycle();  


好了,这里我们已经获取到设置的图片,以及需要图片显示的大小drawableSize。接下来重写setCompoundDrawablesWithIntrinsicBounds方法。将我们需要的图片大小设置给图片。

[java] view plaincopy

  1. public void setCompoundDrawablesWithIntrinsicBounds(Drawable left,  

  2.             Drawable top, Drawable right, Drawable bottom) {  

  3.   

  4.         if (left != null) {  

  5.             left.setBounds(00, mDrawableSize, mDrawableSize);  

  6.         }  

  7.         if (right != null) {  

  8.             right.setBounds(00, mDrawableSize, mDrawableSize);  

  9.         }  

  10.         if (top != null) {  

  11.             top.setBounds(00, mDrawableSize, mDrawableSize);  

  12.         }  

  13.         if (bottom != null) {  

  14.             bottom.setBounds(00, mDrawableSize, mDrawableSize);  

  15.         }  

  16.         setCompoundDrawables(left, top, right, bottom);  

  17.     }  


设置给图片后,不要忘了调用setCompoundDrawables(left, top, right, bottom)方法,我们要在视图中显示图片。这个方法的内容感兴趣的可以自己查阅源码。

到此,我们代码部分已经编写完毕。

接下来添加需要的图片资源以及xml布局设置。

xml布局如下:

[html] view plaincopy

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

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

  3.     xmlns:myradio="http://schemas.android.com/apk/res/com.example.test"  

  4.     android:layout_width="match_parent"  

  5.     android:layout_height="match_parent" >  

  6.   

  7.     <LinearLayout  

  8.         android:layout_width="fill_parent"  

  9.         android:layout_height="fill_parent"  

  10.         android:orientation="vertical" >  

  11.   

  12.         <FrameLayout  

  13.             android:id="@+id/tab_content"  

  14.             android:layout_width="fill_parent"  

  15.             android:layout_height="0dp"  

  16.             android:layout_weight="1.0"  

  17.             android:background="#FFFFFF" />  

  18.           

  19.           

  20.   

  21.         <RadioGroup  

  22.             android:id="@+id/rgs"  

  23.             android:layout_width="match_parent"  

  24.             android:layout_height="wrap_content"  

  25.             android:background="@color/whiet"  

  26.             android:gravity="center"  

  27.             

  28.             android:orientation="horizontal" >  

  29.   

  30.               

  31.             <com.example.test.MyRadioButton  

  32.                 android:id="@+id/tab_a"  

  33.                 android:layout_width="0dp"  

  34.                 android:layout_height="wrap_content"  

  35.                 android:layout_weight="1"  

  36.                 android:layout_marginLeft="10dp"  

  37.                 android:layout_marginRight="10dp"  

  38.                 android:background="@color/whiet"  

  39.                 android:button="@null"  

  40.                 android:clickable="true"  

  41.                   

  42.                 myradio:drawableTop="@drawable/shouye_radiobutton"  

  43.                 myradio:drawableSize="20dp"  

  44.                   

  45.                   

  46.                 android:gravity="center"  

  47.                 android:text="首页"  

  48.                 android:textSize="13sp" />  

  49.   

  50.             <com.example.test.MyRadioButton  

  51.                 android:id="@+id/tab_b"  

  52.                 android:layout_width="0dp"  

  53.                 android:layout_height="wrap_content"  

  54.                 android:layout_weight="1"  

  55.                 android:background="@color/whiet"  

  56.                 android:layout_marginLeft="10dp"  

  57.                 android:layout_marginRight="10dp"  

  58.                 android:button="@null"  

  59.                 android:checked="true"  

  60.                 android:clickable="true"  

  61.                   

  62.                 myradio:drawableTop="@drawable/fenlei_radiobutton"  

  63.                 myradio:drawableSize="30dp"  

  64.                   

  65.                 android:gravity="center"  

  66.                 android:text="分类"  

  67.                 android:textSize="13sp" />  

  68.   

  69.             <RadioButton  

  70.                 android:id="@+id/tab_c"  

  71.                 android:layout_width="wrap_content"  

  72.                 android:layout_height="wrap_content"  

  73.                 android:layout_marginBottom="10dp"  

  74.                 android:background="@color/whiet"  

  75.                 android:button="@null"  

  76.                 android:drawableTop="@drawable/gouwuche_bg"  

  77.                 android:gravity="center"  

  78.                 android:paddingTop="10dip" />  

  79.   

  80.             <RadioButton  

  81.                 android:id="@+id/tab_d"  

  82.                 android:layout_width="0dp"  

  83.                 android:layout_height="wrap_content"  

  84.                 android:layout_weight="1"  

  85.                 android:layout_marginLeft="10dp"  

  86.                 android:layout_marginRight="10dp"  

  87.                 android:background="@color/whiet"  

  88.                 android:button="@null"  

  89.                 android:drawableTop="@drawable/faxian_radiobutton"  

  90.                 android:gravity="center"  

  91.                 android:text="发现"  

  92.                 android:textSize="13sp" />  

  93.   

  94.             <RadioButton  

  95.                 android:id="@+id/tab_e"  

  96.                 android:layout_width="0dp"  

  97.                 android:layout_height="wrap_content"  

  98.                 android:layout_weight="1"  

  99.                 android:background="@color/whiet"  

  100.                 android:layout_marginLeft="10dp"  

  101.                 android:layout_marginRight="10dp"  

  102.                 android:button="@null"  

  103.                 android:drawableTop="@drawable/wode_radiobutton"  

  104.                 android:gravity="center"  

  105.                 android:text="我的"  

  106.                   

  107.                 android:textSize="13sp" />  

  108.         </RadioGroup>  

  109.     </LinearLayout>  

  110.   

  111. </RelativeLayout>  


其中,头两个RadioButton用了自定义的。另外的是系统的,用来做对比。不要忘了用自定义属性时的命名空间和自定义的RadioButton的可点击属性。android:clickable="true"。

自定义RadioButton的完整源码如下:

[java] view plaincopy

  1. package com.example.test;  

  2.   

  3. import android.R.integer;  

  4. import android.R.raw;  

  5. import android.content.Context;  

  6. import android.content.res.Resources;  

  7. import android.content.res.TypedArray;  

  8. import android.graphics.drawable.Drawable;  

  9. import android.util.AttributeSet;  

  10. import android.util.Log;  

  11. import android.widget.RadioButton;  

  12.   

  13. public class MyRadioButton extends RadioButton {  

  14.   

  15.     private int mDrawableSize;// xml文件中设置的大小  

  16.   

  17.     public MyRadioButton(Context context) {  

  18.         this(context, null0);  

  19.     }  

  20.   

  21.     public MyRadioButton(Context context, AttributeSet attrs) {  

  22.         this(context, attrs, 0);  

  23.     }  

  24.   

  25.     public MyRadioButton(Context context, AttributeSet attrs, int defStyle) {  

  26.         super(context, attrs, defStyle);  

  27.         // TODO Auto-generated constructor stub  

  28.         Drawable drawableLeft = null, drawableTop = null, drawableRight = null, drawableBottom = null;  

  29.         TypedArray a = context.obtainStyledAttributes(attrs,  

  30.                 R.styleable.MyRadioButton);  

  31.   

  32.         int n = a.getIndexCount();  

  33.         for (int i = 0; i < n; i++) {  

  34.             int attr = a.getIndex(i);  

  35.             Log.i("MyRadioButton""attr:" + attr);  

  36.             switch (attr) {  

  37.             case R.styleable.MyRadioButton_drawableSize:  

  38.                 mDrawableSize = a.getDimensionPixelSize(R.styleable.MyRadioButton_drawableSize, 50);  

  39.                 Log.i("MyRadioButton""mDrawableSize:" + mDrawableSize);  

  40.                 break;  

  41.             case R.styleable.MyRadioButton_drawableTop:  

  42.                 drawableTop = a.getDrawable(attr);  

  43.                 break;  

  44.             case R.styleable.MyRadioButton_drawableBottom:  

  45.                 drawableRight = a.getDrawable(attr);  

  46.                 break;  

  47.             case R.styleable.MyRadioButton_drawableRight:  

  48.                 drawableBottom = a.getDrawable(attr);  

  49.                 break;  

  50.             case R.styleable.MyRadioButton_drawableLeft:  

  51.                 drawableLeft = a.getDrawable(attr);  

  52.                 break;  

  53.             default :  

  54.                     break;  

  55.             }  

  56.         }  

  57.         a.recycle();  

  58.           

  59.         setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);  

  60.   

  61.     }  

  62.   

  63.     public void setCompoundDrawablesWithIntrinsicBounds(Drawable left,  

  64.             Drawable top, Drawable right, Drawable bottom) {  

  65.   

  66.         if (left != null) {  

  67.             left.setBounds(00, mDrawableSize, mDrawableSize);  

  68.         }  

  69.         if (right != null) {  

  70.             right.setBounds(00, mDrawableSize, mDrawableSize);  

  71.         }  

  72.         if (top != null) {  

  73.             top.setBounds(00, mDrawableSize, mDrawableSize);  

  74.         }  

  75.         if (bottom != null) {  

  76.             bottom.setBounds(00, mDrawableSize, mDrawableSize);  

  77.         }  

  78.         setCompoundDrawables(left, top, right, bottom);  

  79.     }  

  80.   

  81. }  


代码很简单,就没有写注释。解释的内容都在文中了。

至此自定义改变Drawable图片大小的RadioButton已经完成。经此一役,我们可以定义任何想要的东东。没有做不到,只有想不到。


源码下载地址

转载请注明出处



转载于:https://my.oschina.net/moziqi/blog/485217

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值