好久没有更新博客,写这篇技术时,感觉很多东西生疏了好多。于是心有感慨:我们做技术的,要是长时间不搞技术,那就是被技术搞!所以攻守之间,大家谨慎思量。
冬天已过,放假出去玩耍时,看到两旁嫩嫩的树叶,想起贺知章的诗句:
《咏柳》
碧玉妆成一树高,
万条垂下绿丝绦。
不知细叶谁裁出,
二月春风似剪刀。
犹自感叹,春天来了,美腿还会远么。
好了,闲言少叙,言归正传。
代码效果
前两天一个朋友提出的需求,用RadioButton实现的应用页面切换。效果图如下
这种想法很好,但也出现了两个问题:其一,界面扩展性很差;其二,RadioButton设置图片后,无法在xml中设置图片大小,导致布局不美观。那么问题来了?如何设置这个图片的大小。
百度常见的回答是,在代码中动态设置图片大小。然后设置在布局上。代码如下:
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图片设置边界,即要显示的大小。
达到同样效果的还有一个方法:
setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);进入源码查看该方法的具体实现:
public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) { if (left != null) { left.setBounds(0, 0, left.getIntrinsicWidth(), left.getIntrinsicHeight()); } if (right != null) { right.setBounds(0, 0, right.getIntrinsicWidth(), right.getIntrinsicHeight()); } if (top != null) { top.setBounds(0, 0, top.getIntrinsicWidth(), top.getIntrinsicHeight()); } if (bottom != null) { bottom.setBounds(0, 0, bottom.getIntrinsicWidth(), bottom.getIntrinsicHeight()); } setCompoundDrawables(left, top, right, bottom); }原来这个方法,同样调用了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文件的内容为:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="MyRadioButton"> <attr name="drawableSize" format="dimension"/> <attr name="drawableTop" format="reference"/> <attr name="drawableLeft" format="reference"/> <attr name="drawableRight" format="reference"/> <attr name="drawableBottom" format="reference"/> </declare-styleable> </resources>
获取属性的代码如下:
Drawable drawableLeft = null, drawableTop = null, drawableRight = null, drawableBottom = null; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyRadioButton); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); Log.i("MyRadioButton", "attr:" + attr); switch (attr) { case R.styleable.MyRadioButton_drawableSize: mDrawableSize = a.getDimensionPixelSize(R.styleable.MyRadioButton_drawableSize, 50); Log.i("MyRadioButton", "mDrawableSize:" + mDrawableSize); break; case R.styleable.MyRadioButton_drawableTop: drawableTop = a.getDrawable(attr); break; case R.styleable.MyRadioButton_drawableBottom: drawableRight = a.getDrawable(attr); break; case R.styleable.MyRadioButton_drawableRight: drawableBottom = a.getDrawable(attr); break; case R.styleable.MyRadioButton_drawableLeft: drawableLeft = a.getDrawable(attr); break; default : break; } } a.recycle();
public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) { if (left != null) { left.setBounds(0, 0, mDrawableSize, mDrawableSize); } if (right != null) { right.setBounds(0, 0, mDrawableSize, mDrawableSize); } if (top != null) { top.setBounds(0, 0, mDrawableSize, mDrawableSize); } if (bottom != null) { bottom.setBounds(0, 0, mDrawableSize, mDrawableSize); } setCompoundDrawables(left, top, right, bottom); }
到此,我们代码部分已经编写完毕。
接下来添加需要的图片资源以及xml布局设置。
xml布局如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myradio="http://schemas.android.com/apk/res/com.example.test" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <FrameLayout android:id="@+id/tab_content" android:layout_width="fill_parent" android:layout_height="0dp" android:layout_weight="1.0" android:background="#FFFFFF" /> <RadioGroup android:id="@+id/rgs" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/whiet" android:gravity="center" android:orientation="horizontal" > <com.example.test.MyRadioButton android:id="@+id/tab_a" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/whiet" android:button="@null" android:clickable="true" myradio:drawableTop="@drawable/shouye_radiobutton" myradio:drawableSize="20dp" android:gravity="center" android:text="首页" android:textSize="13sp" /> <com.example.test.MyRadioButton android:id="@+id/tab_b" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@color/whiet" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:button="@null" android:checked="true" android:clickable="true" myradio:drawableTop="@drawable/fenlei_radiobutton" myradio:drawableSize="30dp" android:gravity="center" android:text="分类" android:textSize="13sp" /> <RadioButton android:id="@+id/tab_c" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:background="@color/whiet" android:button="@null" android:drawableTop="@drawable/gouwuche_bg" android:gravity="center" android:paddingTop="10dip" /> <RadioButton android:id="@+id/tab_d" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:background="@color/whiet" android:button="@null" android:drawableTop="@drawable/faxian_radiobutton" android:gravity="center" android:text="发现" android:textSize="13sp" /> <RadioButton android:id="@+id/tab_e" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:background="@color/whiet" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:button="@null" android:drawableTop="@drawable/wode_radiobutton" android:gravity="center" android:text="我的" android:textSize="13sp" /> </RadioGroup> </LinearLayout> </RelativeLayout>
自定义RadioButton的完整源码如下:
package com.example.test; import android.R.integer; import android.R.raw; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.util.Log; import android.widget.RadioButton; public class MyRadioButton extends RadioButton { private int mDrawableSize;// xml文件中设置的大小 public MyRadioButton(Context context) { this(context, null, 0); } public MyRadioButton(Context context, AttributeSet attrs) { this(context, attrs, 0); } public MyRadioButton(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub Drawable drawableLeft = null, drawableTop = null, drawableRight = null, drawableBottom = null; TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyRadioButton); int n = a.getIndexCount(); for (int i = 0; i < n; i++) { int attr = a.getIndex(i); Log.i("MyRadioButton", "attr:" + attr); switch (attr) { case R.styleable.MyRadioButton_drawableSize: mDrawableSize = a.getDimensionPixelSize(R.styleable.MyRadioButton_drawableSize, 50); Log.i("MyRadioButton", "mDrawableSize:" + mDrawableSize); break; case R.styleable.MyRadioButton_drawableTop: drawableTop = a.getDrawable(attr); break; case R.styleable.MyRadioButton_drawableBottom: drawableRight = a.getDrawable(attr); break; case R.styleable.MyRadioButton_drawableRight: drawableBottom = a.getDrawable(attr); break; case R.styleable.MyRadioButton_drawableLeft: drawableLeft = a.getDrawable(attr); break; default : break; } } a.recycle(); setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom); } public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) { if (left != null) { left.setBounds(0, 0, mDrawableSize, mDrawableSize); } if (right != null) { right.setBounds(0, 0, mDrawableSize, mDrawableSize); } if (top != null) { top.setBounds(0, 0, mDrawableSize, mDrawableSize); } if (bottom != null) { bottom.setBounds(0, 0, mDrawableSize, mDrawableSize); } setCompoundDrawables(left, top, right, bottom); } }
至此自定义改变Drawable图片大小的RadioButton已经完成。经此一役,我们可以定义任何想要的东东。没有做不到,只有想不到。
源码下载地址
转载请注明出处