一、自定義帶圖片的組合控件
這次的自定義組合控件在前面Android自定義組合控件(一)的基礎上進行,將添加帶圖片,以及文字可以使用引用的組合空件。具體原理是一樣的,只是現在在佈局裏添加了一個ImageView控件,下面給出具體的步奏:
圖1 帶圖片的組合控件效果圖
1、編寫自定義組合控件佈局。自定義組合控件佈局如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<!-- 添加一個顯示圖片的ImageView控件 -->
<ImageView
android:id="@+id/id_show_icon"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_centerVertical="true"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/id_show_icon"
android:layout_marginLeft="5dp"
android:orientation="vertical" >
<TextView
android:id="@+id/id_title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/id_decscribe_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp" />
</LinearLayout>
</RelativeLayout>
2、創建自定義屬性。在values文件下新建sttrs.xml文件,創建我們需要的屬性。注意:此時文字的format就不在是單一的“string”了,而是引用和字符串結合的“reference|string”,順便也說一下字體顏色、字體大小的設置,由於圖片也可以是純顏色,因此我們也加上顏色的引用。如下代碼中的“showIcon”的format。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- 名稱隨便取,但建議還是要有意義 -->
<declare-styleable name="CustomUI">
<attr name="titleTip" format="reference|string" />
<attr name="describe" format="reference|string" />
<attr name="showIcon" format="reference|color" />
<attr name="titleTextSize" format="dimension" />
<attr name="describeTextSize" format="dimension" />
</declare-styleable>
</resources>
3、構造自定義組合控件類。新建一個類繼承Relativelayout或者LinearLayout,添加它的構造函數,自定義一個函數,將佈局引入進來,並在構造方法裏調用。自定義函數引入佈局代碼如下:
/**
* 將寫好的佈局引入進來
* @param context
*/
private void initView(Context context) {
View.inflate(context, R.layout.item_my_relativelayout, this);
id_show_icon = (ImageView) this.findViewById(R.id.id_show_icon);
id_title_tv = (TextView) this.findViewById(R.id.id_title_tv);
id_decscribe_tv = (TextView) this.findViewById(R.id.id_decscribe_tv);
}
4、獲取自定義屬性的值。獲取屬性的值有兩種(我所熟悉的,要是有更好的辦法,謝謝告知)。
(1)第一種是屬性數組。我們用這種方式來獲取字體大小(不知道是不是我弄錯了,我用直接獲取的方法去獲取dimension屬性,程序直接Over,你可以試一試,也許是我弄錯了),具體代碼如下:
//R.styleable.CustomUI 這裏的CustomUI就是我們定義的屬性名稱
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CustomUI);
//取得文本大小,它需要填寫一個默認值
float titleTextSize = a.getDimension(R.styleable.Relativelayout_titleTextSize, 18);
float describeTextSize = a.getDimension(R.styleable.Relativelayout_describeTextSize, 14);
這樣,我們便得到了設置字體大小的值,就可以直接通過Java代碼設置控件的字體大小了。不不不,彆着急,這裏得到的字體大小的單位是px,我們還要將它轉化爲sp,否則手機不兼容哦!(DensityUtil.px2sp(,)是一個屏幕像素轉換工具類後面會給出)
// 轉化單位
titleTextSize = DensityUtil.px2sp(context, titleTextSize);
describeTextSize = DensityUtil.px2sp(context, describeTextSize);
(2)第二種是直接獲取。首先獲取帶引用的字體屬性吧!帶引用的字符串獲取到後,我們並不能直接得到它的值,他返回該字符串的引用ID,如:“@7f050000”,直接將它設置的話,將會完整的給你顯示出來,我用了一個最笨的方法,就是判斷字符串裏是否含有“@”,如果有,再去獲取資源裏的字符串,沒有說明就是我們想要的字符串(相信你會有更好的辦法)。獲取方法如下:
//我們將命名空間定義爲一個局部常量
private final String NAMESPACE = "http://schemas.android.com/apk/res/com.myinterpserson";
/******************我是華麗的分割線************************/
String titleTip = attrs.getAttributeValue(NAMESPACE, "titleTip");
String describe = attrs.getAttributeValue(NAMESPACE, "describe");
if(titleTip.indexOf("@") != -1){
String temp = StringUtils.substring(titleTip,1, titleTip.length());
titleTip = context.getResources().getString(Integer.parseInt(temp));
}
if(describe.indexOf("@") != -1){
String temp = StringUtils.substring(describe,1, titleTip.length());
describe = context.getResources().getString(Integer.parseInt(temp));
}
圖片的獲取,比字符串簡單多了,都不用判斷了。得到這個ID後,拿着這個ID就往控件上那麼一塞,就O了!
int showIcon = attrs.getAttributeResourceValue(NAMESPACE, "showIcon",R.drawable.img_item_add);
到此,帶圖片,帶引用,帶設置字體大小的組合控件就完成了,其用法和教程(一)中的方法是一樣的,一些get,set方法也是一樣的,不在鰲訴。如有錯誤,還望指正!
屏幕像素轉換工具類DensityUtil.java如下:
/**
* 將dip轉換爲px
* @param context
* @param dpValue
* @return
*/
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale + 0.5f);
}
/**
* 將px轉換爲dip
* @param context
* @param pxValue
* @return
*/
public static int px2dip(Context context, float pxValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (pxValue / scale + 0.5f);
}
/**
* 將px值轉換爲sp值,保證文字大小不變
*
* @param pxValue
* @param fontScale
* (DisplayMetrics類中屬性scaledDensity)
* @return
*/
public static int px2sp(Context context, float pxValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (pxValue / fontScale + 0.5f);
}
/**
* 將sp值轉換爲px值,保證文字大小不變
*
* @param spValue
* @param fontScale
* (DisplayMetrics類中屬性scaledDensity)
* @return
*/
public static int sp2px(Context context, float spValue) {
final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
return (int) (spValue * fontScale + 0.5f);
}