打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Android 自定义RadioButton 实现文字上下左右方向的图片大小设置
转载:Android 自定义RadioButton 实现文字上下左右方向的图片大小设置
好久没有更新博客,写这篇技术时,感觉很多东西生疏了好多。于是心有感慨:我们做技术的,要是长时间不搞技术,那就是被技术搞!所以攻守之间,大家谨慎思量。
代码效果
前两天一个朋友提出的需求,用RadioButton实现的应用页面切换。效果图如下
这种想法很好,但也出现了两个问题:其一,界面扩展性很差;其二,RadioButton设置图片后,无法在xml中设置图片大小,导致布局不美观。那么问题来了?如何设置这个图片的大小。
百度常见的回答是,在代码中动态设置图片大小。然后设置在布局上。代码如下:
1
<span style="font-size:18px;">mRadioButton.setCompoundDrawables(left, top, right, bottom);</span>
参数类型都是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图片设置边界,即要显示的大小。
达到同样效果的还有一个方法:
1
<span style="font-size:18px;">setCompoundDrawablesWithIntrinsicBounds(drawableLeft, drawableTop, drawableRight, drawableBottom);</span>
进入源码查看该方法的具体实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<span style="font-size:18px;">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);
}</span>
原来这个方法,同样调用了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文件的内容为:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<span style="font-size:18px;"><!--?xml version="1.0" encoding="utf-8"-->
<resources>
<declare-styleable name="MyRadioButton">
</attr></attr></attr></attr></attr></declare-styleable>
</resources>
</span>
规定了属性后,我们需要在代码中获取到这些属性,从而来在视图中显示我们需要的情况。
获取属性的代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<span style="font-size:18px;">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();</span>
好了,这里我们已经获取到设置的图片,以及需要图片显示的大小drawableSize。接下来重写setCompoundDrawablesWithIntrinsicBounds方法。将我们需要的图片大小设置给图片。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<span style="font-size:18px;">  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);
}</span>
设置给图片后,不要忘了调用setCompoundDrawables(left, top, right, bottom)方法,我们要在视图中显示图片。这个方法的内容感兴趣的可以自己查阅源码。
到此,我们代码部分已经编写完毕。
接下来添加需要的图片资源以及xml布局设置。
xml布局如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<span style="font-size:18px;"><!--?xml version="1.0" encoding="utf-8"-->
<relativelayout android:layout_height="match_parent" android:layout_width="match_parent" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:myradio="http://schemas.android.com/apk/res/com.example.test">
<linearlayout android:layout_height="fill_parent" android:layout_width="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:background="@color/whiet" android:gravity="center" android:id="@+id/rgs" android:layout_height="wrap_content" android:layout_width="match_parent" android:orientation="horizontal">
<com.example.test.myradiobutton android:background="@color/whiet" android:button="@null" android:clickable="true" android:gravity="center" android:id="@+id/tab_a" android:layout_height="wrap_content" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_weight="1" android:layout_width="0dp" android:text="首页" android:textsize="13sp" myradio:drawablesize="20dp" myradio:drawabletop="@drawable/shouye_radiobutton">
<com.example.test.myradiobutton android:background="@color/whiet" android:button="@null" android:checked="true" android:clickable="true" android:gravity="center" android:id="@+id/tab_b" android:layout_height="wrap_content" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_weight="1" android:layout_width="0dp" android:text="分类" android:textsize="13sp" myradio:drawablesize="30dp" myradio:drawabletop="@drawable/fenlei_radiobutton">
<radiobutton android:background="@color/whiet" android:button="@null" android:drawabletop="@drawable/gouwuche_bg" android:gravity="center" android:id="@+id/tab_c" android:layout_height="wrap_content" android:layout_marginbottom="10dp" android:layout_width="wrap_content" android:paddingtop="10dip">
<radiobutton android:background="@color/whiet" android:button="@null" android:drawabletop="@drawable/faxian_radiobutton" android:gravity="center" android:id="@+id/tab_d" android:layout_height="wrap_content" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_weight="1" android:layout_width="0dp" android:text="发现" android:textsize="13sp">
<radiobutton android:background="@color/whiet" android:button="@null" android:drawabletop="@drawable/wode_radiobutton" android:gravity="center" android:id="@+id/tab_e" android:layout_height="wrap_content" android:layout_marginleft="10dp" android:layout_marginright="10dp" android:layout_weight="1" android:layout_width="0dp" android:text="我的" android:textsize="13sp">
</radiobutton></radiobutton></radiobutton></com.example.test.myradiobutton></com.example.test.myradiobutton></radiogroup>
</linearlayout>
</relativelayout></span>
其中,头两个RadioButton用了自定义的。另外的是系统的,用来做对比。不要忘了用自定义属性时的命名空间和自定义的RadioButton的可点击属性。android:clickable="true"。
自定义RadioButton的完整源码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<span style="font-size:18px;">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);
}
}
</span>
代码很简单,就没有写注释。解释的内容都在文中了。
至此自定义改变Drawable图片大小的RadioButton已经完成。经此一役,我们可以定义任何想要的东东。没有做不到,只有想不到。
源码下载地址
转载请注明出处
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
自定义RadioButton样式2
Android2.2——API中文文档3
5.2.2 Fragment实例精讲
使用Fragment完成Tab选项卡
android:布局参数,控件属性及各种xml的作用
Android夜间模式实现
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服