自定義View從實作到原理(六)
終于回到了實作這一部分,經過了之前的決議,我們從實作到原理,這次再次回到實作,這一次的實作·就不會是像之前那次的簡單實作了,經過梳理我們已經有能力寫出一些復雜的自定義View,實作自定義組合控制元件,
實作自定義組合控制元件
所謂自定義組合控制元件,就是多個控制元件組合起來成為了一個新的控制元件,主要用于解決多次重復的使用同一型別的布局,就比如說我們常用的頂部標題欄以及彈出的樣式dialog等,這些都很常用,所以將他們所需要的控制元件組合起來形成一個新的控制元件,就可以提高代碼可讀性以及實作效率,那么這一次我們就來實作一個頂部的標題欄,
定義標題欄(組合控制元件)的布局
首先我們來布置一下這個標題欄的布局,很簡單,就是兩張圖片加一串文字,代碼如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/titleBar"
android:layout_width="match_parent"
android:layout_height="45dp">
<ImageView
android:id="@+id/titleBarLeft"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/titlebarleft"
android:layout_alignParentStart="true"
android:layout_centerHorizontal="true"
android:layout_marginStart="15dp"/>
<TextView
android:id="@+id/titleBarTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:maxLength="11"
android:singleLine="true"
android:ellipsize="end"
android:textStyle="bold"/>
<ImageView
android:id="@+id/titleBarRight"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/titlebarright"
android:layout_alignParentEnd="true"
android:layout_centerHorizontal="true"
android:layout_marginEnd="15dp"/>
</RelativeLayout>
就是這樣,包含兩個ImageView以及一個TextView,其中maxLength含義是最多顯示的文本數量,ellipsize是設定省略號的位置,textStyle是設定文本字體,其他的沒什么問題,接下來就開始撰寫之前說過的titleattrs.xml這個屬性檔案:
定義View屬性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="TitleBar">
<attr name="titleBackground" format="color"/>
<attr name="titleTextColor" format="color"/>
<attr name="titleText" format="string"/>
</declare-styleable>
</resources>
和之前一樣,先寫好了styleable的name,這個地方在建構式中呼叫,剩下的就是自定義的屬性以及屬性類別了,接下來正式進入Java代碼部分:
自定義組合控制元件
/**
* 自定義的標題欄
*/
public class TitleBar extends RelativeLayout {
//定義屬性中的標題欄背景顏色
private int titleBackground;
//定義屬性中的標題顏色
private int titleTextColor;
//定義屬性中的標題內容
private String titileText;
//定義布局中的控制元件
private ImageView titleBarLeft, titleBarRight;
private TextView titleBarTitle;
private RelativeLayout titleBar;
public TitleBar(Context context) {
this(context, null);
}
/**
* 之前的構造方法傳到這里·載入屬性
*
* @param context 當前位置
* @param attrs 也就是
*/
public TitleBar(Context context, AttributeSet attrs) {
super(context, attrs);
@SuppressLint("Recycle")
TypedArray titleTypeArray = context.obtainStyledAttributes(attrs, R.styleable.TitleBar);
titleBackground = titleTypeArray.getColor(R.styleable.TitleBar_titleBackground, Color.BLACK);
titleTextColor = titleTypeArray.getColor(R.styleable.TitleBar_titleTextColor, Color.WHITE);
titileText = titleTypeArray.getString(R.styleable.TitleBar_titleText);
//回收
titleTypeArray.recycle();
initView(context);
}
/**
* 載入布局以及設定屬性
*
* @param context 當前位置
*/
public void initView(Context context) {
LayoutInflater.from(context).inflate(R.layout.titlebar, this, true);
titleBarLeft = findViewById(R.id.titleBarLeft);
titleBarRight = findViewById(R.id.titleBarRight);
titleBarTitle = findViewById(R.id.titleBarTitle);
titleBar = findViewById(R.id.titleBar);
//設定布局的背景顏色以及標題文字顏色
titleBar.setBackgroundColor(titleBackground);
titleBarTitle.setTextColor(titleTextColor);
}
/**
* 設定標題的函式
*
* @param TitleText 標題內容
*/
public void setTitle(String TitleText) {
if (TitleText != null) {
titleBarTitle.setText(TitleText);
}
}
/**
* 點擊左側圖片的點擊事件
*
* @param onClickListener 點擊事件:eg:new View.OnCLickListener(){}
*/
public void setLeftListener(OnClickListener onClickListener) {
//外部設定的點擊事件就是組合控制元件中左面圖片的點擊事件
titleBarLeft.setOnClickListener(onClickListener);
}
/**
* 點擊右側圖片的點擊事件
*
* @param onClickListener 點擊事件:eg:new View.OnCLickListener(){}
*/
public void setRightListener(OnClickListener onClickListener) {
//外部設定的點擊事件就是組合控制元件中右面圖片的點擊事件
titleBarRight.setOnClickListener(onClickListener);
}
}
注釋已經寫的很詳細了,反正我寫的時候我是明白了,就這樣,我們定義組合控制元件已經完成,下面在我們想要實作的界面參考:
xml參考
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Activity.ShelfActivity">
<com.example.day1.View.TitleBar
android:id="@+id/shelfTitleBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
截取了一部分,我們下面會在對應的Activity中進行設定標題內容以及點擊事件:
代碼(Activity)參考
private TitleBar shelfTitleBar;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_shelf);
shelfTitleBar = findViewById(R.id.shelfTitleBar);
shelfTitleBar.setTitle("自定義組合控制元件");
shelfTitleBar.setLeftListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ShelfActivity.this, "點擊左側控制元件", Toast.LENGTH_SHORT).show();
}
});
shelfTitleBar.setRightListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(ShelfActivity.this, "點擊右側控制元件", Toast.LENGTH_SHORT).show();
}
});
}
如此這樣,我這個也是截取了一部分,不全面,運行可能會有點小錯誤沒截取完整,見諒,那么就讓我們來看看最終運行效果:

好的,成功,點擊事件也是ok的,當然現在看起來不好看,所以以后會慢慢完善的,小場面,溜了,

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/240557.html
標籤:其他
