Android CheckBox中設定padding無效問題解決方法
CheckBox使用本地圖片資源
CheckBox是Android中用的比較多的一個控制元件,不過它自帶的button樣式比較醜,通常都會替換成本地的資源圖片。使用本地資源圖片很簡單,設定android:button屬性為一個自定義的包含selector的drawable檔案即可。例如android:button=”@drawable/radio_style”。radio_style.xml定義如下。checked和unchecked分別是選中和未選中時使用的圖片資源。
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_checked="true" android:drawable="@drawable/checked"></item>
<item android:state_checked="false" android:drawable="@drawable/unchecked"></item>
</selector>
CheckBox點選響應問題
當CheckBox使用本地的圖片資源後,如果本地圖片很小(圖片大小需要和佈局搭配,很多時候為了介面的美觀不能使用太大的圖片),而且右側沒有文字時,會導致CheckBox很難被點中。增加點選區域,通常的做法是增加padding值,擴大控制元件的外部範圍。我們希望可以通過設定CheckBox的padding值,讓圖片的上下左右四個方向都增加一定的範圍,這樣使用者點選圖片的響應上就不會有問題了。
CheckBox padding失效問題
CheckBox分別設定上、下、左、右和全部四個方向各20dp的padding後實際顯示效果如圖所示。這裡為了看得清楚,為CheckBox設定了背景色,並且添加了文字。
從圖示可以看出,CheckBox設定padding值影響的是實際上文字到CheckBox邊界的距離,圖片始終在左側垂直居中的位置。
先看上下padding,當設定上下padding時,由於文字本身距離上下邊界就有一定的距離,如果padding值設定的不夠,整個CheckBox區域根本不會變化,通過設定較大的padding值可以實現擴大CheckBox上下區域的目的。最後一張圖上下各20dp的padding,這時可以看到CheckBox高度增加了。但由於中間文字距離上下邊界的距離和CheckBox圖片高度,文字字號,文字內部padding等很多因素有關,很難通過對上下padding設定精確控制CheckBox區域,很可能出現在這個手機上高度被拉的很大,而另一個手機上根本沒有效果。
再看左右padding,當設定左右padding時,無論是左padding還是右padding,影響的只是文字的位置。圖片始終都在整個CheckBox的左側,對圖片來說,增大的都是右側區域。所以設定的左右padding不能解決CheckBox點選響應的問題,不僅會導致圖片位置偏左,還會出現點選左側區域無法點中的情況。
標題中所說的padding無效問題,實際上是有效的,只是設定paddingLeft增加的是右邊區域,paddingTop和paddingBottom只有設定較大的值才能看到效果。
CheckBox padding失效問題原因
要想知道CheckBox padding失效問題原因,得要檢視Android原始碼,CheckBox是繼承自CompoundButton,CheckBox左側的圖片是在CompoundButton的onDraw()方法中繪製的,onDraw()方法程式碼如下,mButtonDrawable就是要繪製的圖片對應的Drawable物件,可以看到left始終為0,而top位置和Grivity有關(上述例子中Gravity是居中的)。
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
final Drawable buttonDrawable = mButtonDrawable;
if (buttonDrawable != null) {
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int drawableHeight = buttonDrawable.getIntrinsicHeight();
final int drawableWidth = buttonDrawable.getIntrinsicWidth();
int top = 0;
switch (verticalGravity) {
case Gravity.BOTTOM:
top = getHeight() - drawableHeight;
break;
case Gravity.CENTER_VERTICAL:
top = (getHeight() - drawableHeight) / 2;
break;
}
int bottom = top + drawableHeight;
int left = isLayoutRtl() ? getWidth() - drawableWidth : 0;
int right = isLayoutRtl() ? getWidth() : drawableWidth;
buttonDrawable.setBounds(left, top, right, bottom);
buttonDrawable.draw(canvas);
}
}
解決CheckBox點選響應問題
由於CheckBox和CompoundButton沒有提供任何方法設定圖片的位置,要想解決CheckBox點選響應的問題似乎唯一的方法就是重寫一個新的控制元件,然後在onDraw方法中確定圖片位置時把padding也考慮進去。不過這樣做實在是太麻煩了。
這裡給出另外一種簡單的方法,那就是將圖片擴大。CheckBox點選響應問題本身是由於圖片過小,如果將圖片擴大就不存在這個問題了,但前面說之所以用小的圖片是為了佈局搭配和介面美觀,如果將圖片擴大不是又回到最開始的問題了嗎!
其實這裡說的圖片擴大,不是將圖片整體放大,而是圖片內容不變,在原先的圖片外圍增加透明畫素,由於透明畫素不可見,圖片看起來的實際大小仍然和以前一樣,但由於透明畫素的存在,CheckBox的區域也會隨之增大。
要在圖片外網增加透明畫素前提是圖片必須是png格式的,不過這並不是問題,通常資原始檔都是png格式的,即使不是png格式的圖片,也可以先轉換成png格式,然後再增加透明畫素。
增加透明畫素的方法也很簡單,用Photoshop開啟png圖片,然後選擇“影象”–“畫布大小”,然後輸入新的大小就可以了。