Android 自訂控制項的使用,android自訂控制項
首先自訂一個attrs.xml的資源檔,聲明自訂屬性
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="TopBar"> <attr name="titleText" format="string"></attr> <attr name="titleTextSize" format="dimension"></attr> <attr name="titleTextColor" format="reference|color"></attr> <attr name="leftButtonText" format="string"></attr> <attr name="leftButtonTextSize" format="dimension"></attr> <attr name="leftButtonBackground" format="reference|color"></attr> <attr name="rightButtonText" format="string"></attr> <attr name="rightButtonTextSize" format="dimension"></attr> <attr name="rightButtonBackground" format="reference|color"></attr> </declare-styleable></resources>
自訂類TopBar,為簡單起見 繼承RelativeLayout
package com.sphere.topbar;import android.annotation.SuppressLint;import android.content.Context;import android.content.res.TypedArray;import android.graphics.drawable.Drawable;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.widget.Button;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;public class TopBar extends RelativeLayout { private String titleText; private float titleTextSize; private int titleTextColor; private String leftButtonText; private float leftButtonTextSize; private Drawable leftButtonBackground; private String rightButtonText; private float rightButtonTextSize; private Drawable rightButtonBackground; private TextView titleTextView; private Button leftButton; private Button rightButton; private LayoutParams titleLayoutParams; private LayoutParams leftBtnLayoutParams; private LayoutParams rightBtnLayoutParams; private TopBarOnClickListener listener; // 定義點擊響應事件回調介面 interface TopBarOnClickListener{ public abstract void onLeftButtonClicked(); public abstract void onRightButtonClicked(); } @SuppressLint("NewApi") public TopBar(Context context, AttributeSet attrs) { super(context, attrs); // 得到xml檔案自定的屬性集合 TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.TopBar); // 得到title的各個屬性 titleText = ta.getString(R.styleable.TopBar_titleText); titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 0); titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0); // 得到left button的各個屬性 leftButtonText = ta.getString(R.styleable.TopBar_leftButtonText); leftButtonTextSize = ta.getDimension(R.styleable.TopBar_leftButtonTextSize, 0); leftButtonBackground = ta.getDrawable(R.styleable.TopBar_leftButtonBackground); // 得到right button的各個屬性 rightButtonText = ta.getString(R.styleable.TopBar_rightButtonText); rightButtonTextSize = ta.getDimension(R.styleable.TopBar_rightButtonTextSize, 0); rightButtonBackground = ta.getDrawable(R.styleable.TopBar_rightButtonBackground); // initial inner basic component leftButton = new Button(context); rightButton = new Button(context); titleTextView = new TextView(context); // 設定屬性 titleTextView.setText(titleText); titleTextView.setTextSize(titleTextSize); titleTextView.setTextColor(titleTextColor); titleLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); titleLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); titleTextView.setLayoutParams(titleLayoutParams); leftButton.setText(leftButtonText); leftButton.setTextSize(leftButtonTextSize); leftButton.setBackground(leftButtonBackground); leftBtnLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); leftBtnLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE); leftButton.setLayoutParams(leftBtnLayoutParams); rightButton.setText(rightButtonText); rightButton.setTextSize(rightButtonTextSize); rightButton.setBackground(rightButtonBackground); rightBtnLayoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT); rightBtnLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE); rightButton.setLayoutParams(rightBtnLayoutParams); // 添加到View中 addView(titleTextView); addView(leftButton); addView(rightButton); //addView(View child, ViewGroup.LayoutParams params); ta.recycle(); leftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onLeftButtonClicked(); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listener.onRightButtonClicked(); } }); } /** * 類的執行個體調用此方法 * 以匿名內部類的形式現實介面中的方法 * @param listener */ public void setTopBarOnClickListener(TopBarOnClickListener listener){ this.listener = listener; } /** * 設定導航背景顏色 * @param color */ public void setTopBarBackgroundColor(int color){ this.setBackgroundColor(color); } /** * 設定按鈕是否可見 * @param show */ public void setLeftButtonVisible(boolean show){ leftButton.setVisibility(show ? View.VISIBLE : View.GONE); } public void setRightButtonVisible(boolean show){ rightButton.setVisibility(show ? View.VISIBLE : View.GONE); }}
需要帶 Context context, AttributeSet attrs這兩個參數的構造方法
從xml檔案中得到各個屬性,並設定給對應的控制項。
別忘了addView() 將內部包含的控制項添加到View中
在main.xml中使用自訂控制項
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:myTopBar="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <com.sphere.topbar.TopBar android:id="@+id/topbar" android:layout_width="match_parent" android:layout_height="48dp" myTopBar:titleText="自訂標題" myTopBar:titleTextColor="#000" myTopBar:titleTextSize="10sp" myTopBar:leftButtonText="Back" myTopBar:leftButtonBackground="#ff00ff" myTopBar:leftButtonTextSize="10sp" myTopBar:rightButtonText="More" myTopBar:rightButtonBackground="#00ff00" myTopBar:rightButtonTextSize="10sp" /></RelativeLayout>
注意要添加名稱空間,xmlns:myTopBar="http://schemas.android.com/apk/res-auto"
如果是ADT開發環境,則需要這麼寫 xmlns:myTopBar="http://schemas.android.com/apk/res/com.sphere.topbar"
注意雖然myTopBar名字可以隨便起,但是不能使用android,否則會與系統衝突,ADT中引用時 需要在res後邊接完整包名才可以。
引用自訂屬性以(myTopBar:屬性名稱)開頭。
MainActivity.java
package com.sphere.topbar;import android.graphics.Color;import android.support.v7.app.ActionBarActivity;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.Toast;public class MainActivity extends ActionBarActivity { private TopBar mTopBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTopBar = (TopBar)findViewById(R.id.topbar); mTopBar.setBackgroundColor(Color.parseColor("#46B4CD")); mTopBar.setTopBarOnClickListener(new TopBar.TopBarOnClickListener() { @Override public void onLeftButtonClicked() { Toast.makeText(MainActivity.this,"Back",Toast.LENGTH_SHORT).show(); } @Override public void onRightButtonClicked() { Toast.makeText(MainActivity.this, "More", Toast.LENGTH_SHORT).show(); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); //noinspection SimplifiableIfStatement if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); }}
這裡我們拿到自訂控制項的執行個體,調用 setTopBarOnClickListener(TopBarOnClickListener listener)方法
為按鈕添加點擊事件監聽器。
如下: