Android 自訂RadioButton 實現文字上下左右方向的圖片大小設定

來源:互聯網
上載者:User

Android 自訂RadioButton 實現文字上下左右方向的圖片大小設定

好久沒有更新部落格,寫這篇技術時,感覺很多東西生疏了好多。於是心有感慨:我們做技術的,要是長時間不搞技術,那就是被技術搞!所以攻守之間,大家謹慎思量。

冬天已過,放假出去玩耍時,看到兩旁嫩嫩的樹葉,想起賀知章的詩句:

《詠柳》

碧玉妝成一樹高,

萬條垂下綠絲絛。

不知細葉誰裁出,

二月春風似剪刀。

猶自感歎,春天來了,美腿還會遠麼。

 

好了,閑言少敘,言歸正傳。

代碼效果

前兩天一個朋友提出的需求,用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檔案的內容為:

 

                                                                        

規定了屬性後,我們需要在代碼中擷取到這些屬性,從而來在視圖中顯示我們需要的情況。

 

擷取屬性的代碼如下:

 

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();

好了,這裡我們已經擷取到設定的圖片,以及需要圖片顯示的大小drawableSize。接下來重寫setCompoundDrawablesWithIntrinsicBounds方法。將我們需要的圖片大小設定給圖片。

 

 

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);}

設定給圖片後,不要忘了調用setCompoundDrawables(left, top, right, bottom)方法,我們要在視圖中顯示圖片。這個方法的內容感興趣的可以自己查閱源碼。

 

到此,我們代碼部分已經編寫完畢。

接下來添加需要的圖片資源以及xml布局設定。

xml布局如下:

 

            <frameLayout            android:id="@+id/tab_content"            android:layout_width="fill_parent"            android:layout_height="0dp"            android:layout_weight="1.0"            android:background="#FFFFFF" />                                                                                                            

其中,頭兩個RadioButton用了自訂的。另外的是系統的,用來做對比。不要忘了用自訂屬性時的命名空間和自訂的RadioButton的可點擊屬性。android:clickable="true"。

 

自訂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 stubDrawable 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已經完成。經此一役,我們可以定義任何想要的東東。沒有做不到,只有想不到。


源碼

轉載請註明出處

 

 

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.