有了前面的準備後,現在就可以開始編碼實現了,這裡先看看在xml中如何引入我們自訂的控制項: 1 <com.jarek.library.TitleView 2 android:id="@+id/title_main" 3 android:layout_width="match_parent" 4 android:background="#0093fe" 5 title:title_name="標題" 6 title:right_text="@string/more" 7 title:title_text_color="@android:color/white" 8 title:right_image_two="@mipmap/icon_crop_rotate" 9 title:title_text_size="20sp"10 title:small_text_size="15sp"11 title:left_text="返回"12 title:left_text_drawable_left="@mipmap/back_normal"13 title:right_text_drawable_right="@mipmap/bar_button_right"14 android:layout_height="50dp"/>
這裡的title標籤就是我們自訂,首先建立一個類繼承自RelativeLayout,這裡選擇RelativeLayout作為父類容器,目的在於RelativeLayout便於控制相對位置。
首先我們要獲得TypedArray對象,所有自訂屬性的值通過它來擷取:
TypedArray typeArray = context.obtainStyledAttributes(attrs, R.styleable.TitleAttr);
得到了typedArray對象後,就可以開始添加按鈕到容器中了,首先看看左邊第一個返回按鈕如果添加上去,先看代碼:
int leftText = typeArray.getResourceId(R.styleable.TitleAttr_left_text, 0); CharSequence charSequence = leftText > 0 ? typeArray.getResources().getText(leftText) : typeArray.getString(R.styleable.TitleAttr_left_text);
這裡left_text就是自訂屬性,表明是左側TextView顯示的文字,文字可以是應用資源檔裡的預定義string,也可以是直接輸入文字,取到對應的styleable後,首先判斷是否大於0,大於0表示是定義在string中的,通過typeArray.getResources().getText()擷取值,等於0就直接取值,表示可能是通過直接賦值的方式給值的。取到值後怎麼賦值給TextView,這裡需要首先給他寬高,這是所有控制項都需要的
/** * layout params of RelativeLayout * @return LayoutParams */private LayoutParams initLayoutParams () { return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT); }我們單獨寫一個方法,後續就可以直接通過
LayoutParams params = initLayoutParams();
來擷取預設寬高值了,這裡可以看到都是高度填充父控制項,寬度是自適應。然後就是new一個TextView了:
/** * create TextView * @param context Context * @param id the id of TextView * @param charSequence text to show * @param params relative params * @return the TextView which is inited */ @NonNull private TextView createTextView(Context context, int id, CharSequence charSequence, LayoutParams params) { TextView textView = new TextView(context); textView.setLayoutParams(params); textView.setGravity(Gravity.CENTER); textView.setId(id); textView.setMinWidth((int)getPixelSizeByDp(minViewWidth)); textView.setText(charSequence); return textView; }這裡可以看到我們傳入了預設的id值,需要顯示的內容,以及上面給定的LayoutParams 。建立好TextView後還可以設定TextView的Drawable,通過自訂屬性left_text_drawable_right,left_text_drawable_left設定,這裡是設定了左右,上下對應的可以設定:
/** * drawable of TextView * @param typeArray TypedArray * @param leftDrawableStyleable leftDrawableStyleable * @param rightDrawableStyleable rightDrawableStyleable * @param textView which TextView to set */ private void setTextViewDrawable(TypedArray typeArray, int leftDrawableStyleable, int rightDrawableStyleable, TextView textView) { int leftDrawable = typeArray.getResourceId(leftDrawableStyleable, 0); int rightDrawable = typeArray.getResourceId(rightDrawableStyleable, 0); textView.setCompoundDrawablePadding((int)getPixelSizeByDp(drawablePadding)); textView.setCompoundDrawablesWithIntrinsicBounds(leftDrawable, 0, rightDrawable, 0); }這裡也是抽取了一個方法出來,然後通過:
setTextViewDrawable(typeArray, R.styleable.TitleAttr_left_text_drawable_left, R.styleable.TitleAttr_left_text_drawable_right, mLeftBackTextTv);
即可給指定的TextView設定drawable了。建立好TextView後,前面提到我們用的是相對布局,需要指定位置規則:
params.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
這裡居左顯示。同時還可以設定字型大小,通過自訂屬性:small_text_size(兩側文字大小),title_text_size(標題文字大小)來設定字型:
/** * get the dimension pixel size from typeArray which is defined in attr * @param typeArray TypedArray * @param stylable stylable * @param defaultSize defaultSize * @return the dimension pixel size */ private float getDimensionPixelSize(TypedArray typeArray, int stylable, int defaultSize) { int sizeStyleable = typeArray.getResourceId(stylable, 0); return sizeStyleable > 0 ? typeArray.getResources().getDimensionPixelSize(sizeStyleable) : typeArray.getDimensionPixelSize(stylable, (int)getPiselSizeBySp(defaultSize)); }一樣,這裡也是單獨寫一個方法來做,TypedArray的用法就不多講了,可以查看其它文章瞭解。然後通過如下設定字型大小:
float textSize = getDimensionPixelSize(typeArray, R.styleable.TitleAttr_small_text_size, defaultSmallTextSize); mLeftBackTextTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
文字顏色,同樣的道理:
/** * get textColor * @param typeArray TypedArray * @return textColor */ private int getTextColorFromAttr (TypedArray typeArray) { int textColorStyleable = typeArray.getResourceId(R.styleable.TitleAttr_title_text_color, 0); if (textColorStyleable > 0) { return typeArray.getResources().getColor(textColorStyleable); } else { return typeArray.getColor(R.styleable.TitleAttr_title_text_color, textColor); } }然後調用方法設定顏色:
mLeftBackTextTv.setTextColor(getTextColorFromAttr(typeArray));
到這裡為止,左側的第一個文字按鈕。或者文字帶圖片的按鈕就建立好了,最後就差一步了:
mLeftBackTextTv.setTextColor(getTextColorFromAttr(typeArray));
其它按鈕,同樣的道理,可以依次添加到容器中,就不多講了,到此為止我們需要的titleView就建立好了,以後使用就可以直接調用了,不需要每個地方去重複的coding