步驟一: 先在values 里 新建一個attrs.xml 來設置我們的屬性值:
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="TopBar" > <attr name="title" format="string"/> <attr name="titleTextSize" format="dimension"/> <attr name="titleTextColor" format="color"/> <attr name="leftText" format="string"/> <attr name="leftBackground" format="reference|color"/> <attr name="leftTextColor" format="color"/> <attr name="rightText" format="string"/> <attr name="rightBackground" format="reference|color"/> <attr name="rightTextColor" format="color"/> </declare-styleable> </resources>
步驟二: 新建Topbar類繼承自RelaiveLayout :
/** * Created by Ace on 2016/2/3. */ public class Topbar extends RelativeLayout { //聲明我們需要的控件 private Button leftButton,rightButton; private TextView tv_title; private int leftTextColor; private String leftText; private Drawable leftBackground; private int rightTextColor; private String rightText; private Drawable rightBackground; private String title; private int titleTextColor; private float titleTextSize; //4 定義布局屬性 private LayoutParams leftParams , rightParams,titleParams; public Topbar(Context context, AttributeSet attrs) { super(context, attrs); //1 通過 context.obtainStyledAttributes 得到 TypedArray對象 並拿到屬性值 TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.TopBar); leftText = ta.getString(R.styleable.TopBar_leftText); leftTextColor = ta.getColor(R.styleable.TopBar_leftTextColor, 0); leftBackground = ta.getDrawable(R.styleable.TopBar_leftBackground); rightText = ta.getString(R.styleable.TopBar_rightText); rightTextColor = ta.getColor(R.styleable.TopBar_rightTextColor, 0); rightBackground = ta.getDrawable(R.styleable.TopBar_rightBackground); title = ta.getString(R.styleable.TopBar_title); titleTextColor = ta.getColor(R.styleable.TopBar_titleTextColor, 0); titleTextSize = ta.getDimension(R.styleable.TopBar_titleTextSize, 0); //記得回收下 防止出現一些內存問題 ta.recycle(); // 2 new出控件 leftButton = new Button(context); rightButton = new Button(context); tv_title = new TextView(context); //3 把自定義的屬性賦給控件 leftButton.setTextColor(leftTextColor); leftButton.setBackground(leftBackground); leftButton.setText(leftText); rightButton.setTextColor(rightTextColor); rightButton.setBackground(rightBackground); rightButton.setText(rightText); tv_title.setTextColor(titleTextColor); tv_title.setTextSize(titleTextSize); tv_title.setText(title); tv_title.setGravity(Gravity.CENTER); setBackgroundColor(0xFFF59563); // 5 new出LayoutParams 設置寬高 leftParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); // 6 設置規則 可以看出LayoutParams布局參數就是把你的控件以什么樣的方式顯示在組合控件 leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); //7 添加到布局中(控件,布局參數) addView(leftButton ,leftParams); rightParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT); rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); addView(rightButton, rightParams); titleParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.MATCH_PARENT); titleParams.addRule(RelativeLayout.CENTER_IN_PARENT); addView(tv_title,titleParams); //8 TopBar的靜態部分已經完畢了 到這一步就很明白了 我們采用的組合方式,用系統以及有的控件組合在一起,組成一個新的控件,這個思路是否可以延伸到其他地方呢?思考下 } }
步驟三: 再Activity_main.xml中設置我們的自定義Topbar 重點我用紅色和黃色標出,系統 xmlns(xml name space)的是:android 那么我們自己定義當然要有個個性的名字 我就寫ace了, 再看后面res-auto ,這部分是控件屬性資源地址.用AS的小伙伴
用res-auto就可以了 eslipse的小伙伴要寫完整的地址 xmlns:XXXXXX="http://schemas.android.com/apk/res/包路徑"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:ace="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="zb.com.topbardemo.MainActivity"> <zb.com.topbardemo.Topbar android:id="@+id/topbar" android:layout_width="wrap_content" android:layout_height="40dp" ace:leftTextColor = "#FFFFFF" ace:leftText ="后退" ace:leftBackground = "#4e32b4" ace:rightTextColor = "#FFFFFF" ace:rightText ="設置" ace:rightBackground = "#4e32b4" ace:title = "我是ACE" ace:titleTextColor = "#e20f0f" ace:titleTextSize = "15sp" > </zb.com.topbardemo.Topbar> </RelativeLayout>
靜態部分完成現在寫Topbar的點擊事件 在Topbar類里寫 :
leftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context,"Ace Left",Toast.LENGTH_LONG).show(); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(context,"Ace Right",Toast.LENGTH_LONG).show(); } });
這樣是可以 但是卻把按鈕的點擊事件寫死了,我們要根據不同情況調用不同的點擊事件就無法實現
.要解決這個問題那么要用到接口回調,系統也是如此來做得. OnclickListener是一個接口 那么我們也新建一個接口topbarClickListener,添加兩個方法(左Button的點擊和右Button的點擊)
package zb.com.topbardemo; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; /** * Created by Ace on 2016/2/3. */
//定義一個topbarClickListener private topbarClickListener mListner; //定義一個接口 兩個方法
public interface topbarClickListener{ public void leftClick(); public void rightClick(); } //暴露一個方法用來設置點擊事件 並映射用戶傳進來的listner
public void setTopbarClickListner(topbarClickListener listner){ mListner = listner; } . . . . . .中間的代碼省略跟前面一樣不用變動 . . . . . leftButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mListner.leftClick(); } }); rightButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mListner.rightClick(); } }); } }
這樣 按鈕的點擊按鈕要做什么完全取決於用戶來設置
我們用我們自己的方法來設置點擊事件
MainActivity:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Topbar topbar =(Topbar)findViewById(R.id.topbar); topbar.setTopbarClickListner(new Topbar.topbarClickListener() { @Override public void leftClick() { Toast.makeText(MainActivity.this,"Ace left",Toast.LENGTH_LONG).show(); } @Override public void rightClick() { Toast.makeText(MainActivity.this,"Ace right",Toast.LENGTH_LONG).show(); } }); } }
我的AS出了點問題 暫時沒有截圖 抱歉~~~