自定義控制元件01---簡單view的實現
阿新 • • 發佈:2018-11-13
對於每一個應用來說幾乎都會有一個Topbar,並且基本都是類似的那麼假如應用有好多個頁面的話,就要寫好多遍,可以在Topbar整合為一個控制元件來使用,針對於這個的學習,總結如下:
1 atts自定義屬性的定義
res–values-atts.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Topbar">
<attr name="titleMiddle" format="string"/>
<attr name="titleTextSize" format="dimension"/>
<attr name="titleTextColor" format="color"/>
<attr name="leftTextColor" format="color"/>
<attr name="leftBackgroubd" format="reference|color"/>
<attr name="leftText" format="string"/>
<attr name ="rightTextColor" format="color"/>
<attr name="rightBackgroubd" format="reference|color"/>
<attr name="rightText" format="string"/>
</declare-styleable>
</resources>
2 自定義Topbar類繼承RelativeLayout
package com.example.mytobbar;
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.widget.Button;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class Topbar extends RelativeLayout{
//定義自定義的屬性對應的控制元件
private Button leftButton,rightButton;
private TextView tvTextView;
private int leftTextColor;
private Drawable leftbackground;
private String leftText;
private int rightTextColor;
private Drawable rightbackground;
private String rightText;
private float titleTextSize;
private int titleTextColor;
private String titleText;
private LayoutParams leftParams,rightParams,titleParams; //用於把控制元件放到佈局中
//定義一個藉口 用於點選事件方法的回撥
public interface TopbarOnClick{
public void leftOnClick();
public void rightOnClick();
public void titleOnClick();
}
//介面的例項,作為類的成員變數
private TopbarOnClick click;
//對外暴露一個方法 把藉口作為引數傳入 就能回撥到介面中的方法
public void setTopbarOnClick(TopbarOnClick click){
this.click=click;
}
public Topbar(Context context, AttributeSet attrs) {
super(context, attrs);
//是控制元件和自定義的屬性相連線
/*
* 1 建立對映,獲取自定義的屬性集合獲取一個typedArray的資料結果,可以在typedArray中取出相應的值
* 2 獲取對應的值,建立對映 1 相當於map的key在atts的名字 2 預設的屬性設定
* 3 使用完回收 避免浪費資源 避免錯誤
* */
//獲取自定義的屬性集合
TypedArray ad=context.obtainStyledAttributes(attrs, R.styleable.Topbar);
//獲取對應的值,建立對映 相當於map的key在atts的名字 0 預設的屬性設定
leftTextColor=ad.getColor(R.styleable.Topbar_leftTextColor, 0);
leftbackground=ad.getDrawable(R.styleable.Topbar_leftBackgroubd);
leftText=ad.getString(R.styleable.Topbar_leftText);
rightTextColor=ad.getColor(R.styleable.Topbar_rightTextColor, 0);
rightbackground=ad.getDrawable(R.styleable.Topbar_rightBackgroubd);
rightText=ad.getString(R.styleable.Topbar_rightText);
titleTextSize=ad.getDimension(R.styleable.Topbar_titleTextSize, 0);
titleTextColor=ad.getColor(R.styleable.Topbar_titleTextColor,0);
titleText=ad.getString(R.styleable.Topbar_titleMiddle);
// 使用完回收 避免浪費資源 避免錯誤
ad.recycle();
//例項化控制元件
leftButton=new Button(context);
rightButton=new Button(context);
tvTextView=new TextView(context);
//將自定義的屬性付給控制元件
leftButton.setText(leftText);
leftButton.setBackground(leftbackground);
leftButton.setTextColor(leftTextColor);
rightButton.setText(rightText);
rightButton.setBackground(rightbackground);
rightButton.setTextColor(rightTextColor);
tvTextView.setText(titleText);
tvTextView.setTextColor(titleTextColor);
tvTextView.setTextSize(titleTextSize);
tvTextView.setGravity(Gravity.CENTER);
setBackgroundColor(0XFFF59563); //給view設定背景色
//把定義的控制元件放到佈局中
leftParams=new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);//控制元件是包裹內容的
leftParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, TRUE); //新增限制條件 居左 相對佈局才有的屬性 自定義控制元件用那上級誰的屬性多最好就繼承誰來自定義
addView(leftButton, leftParams);
//設定button的大小可以設定固定的值 就不會導致背景過大 像效果圖一樣了
rightParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
rightParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
rightParams.setMargins(30, 0, 30, 0);
addView(rightButton, rightParams);
titleParams=new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
titleParams.addRule(RelativeLayout.CENTER_IN_PARENT, TRUE);
addView(tvTextView,titleParams);
//新增點選事件
leftButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//點選事件呼叫類中介面的方法,便會呼叫此介面的實體的方法
click.leftOnClick();
}
});
rightButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
click.rightOnClick();
}
});
tvTextView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
click.titleOnClick();
}
});
}
}
3 佈局檔案中使用自定義的控制元件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
//自定義屬性的名稱空間com.example.mytobbar 為自定義控制元件類的包名
xmlns:demoa="http://schemas.android.com/apk/res/com.example.mytobbar"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.example.mytobbar.Topbar
android:id="@+id/topbar"
android:layout_width="fill_parent"
android:layout_height="50dp"
demoa:titleMiddle="中間標題"
demoa:titleTextSize="15sp"
demoa:titleTextColor="#FFFFFF"
demoa:leftTextColor="#00FF00"
demoa:rightTextColor="#FFFFFF"
demoa:rightBackgroubd="@drawable/nothing_image"
demoa:leftBackgroubd="@drawable/ic_launcher"
demoa:leftText="左邊"
demoa:rightText="右邊"
>
</com.example.mytobbar.Topbar>
</RelativeLayout>
4在activity中使用
package com.example.mytobbar;
import com.example.mytobbar.Topbar.TopbarOnClick;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import android.os.Build;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_main);
Topbar topbar = (Topbar) findViewById(R.id.topbar);
topbar.setTopbarOnClick(new TopbarOnClick() {
@Override
public void titleOnClick() {
Toast.makeText(getApplicationContext(), "title", 0).show();
}
@Override
public void rightOnClick() {
Toast.makeText(getApplicationContext(), "right", 0).show();
}
@Override
public void leftOnClick() {
Toast.makeText(getApplicationContext(), "left", 0).show();
}
});
}
}
其中新增點選事件用到了介面的回撥
新增介面回撥的方法:
- 1 在自定義的類中定義介面,並在介面中定義需要回調的方法
-
//定義一個藉口 用於點選事件方法的回撥
public interface TopbarOnClick{
public void leftOnClick();
public void rightOnClick();
public void titleOnClick();
}
//介面的例項,作為類的成員變數
private TopbarOnClick click;
- 2 在自定義的類中寫一個對外暴露的方法,把定義的介面作為方法的引數
- `
//對外暴露一個方法 把藉口作為引數傳入 就能回撥到介面中的方法
public void setTopbarOnClick(TopbarOnClick click){
this.click=click;
}
- 3 在自定義的類中新增點選事件呼叫介面類的方法進行操作
` //新增點選事件
leftButton.setOnClickListener(new OnClickListener() {@Override public void onClick(View v) { //點選事件呼叫類中介面的方法,便會呼叫此介面的實體的方法 click.leftOnClick(); } });`
- 4 在需要呼叫自定義控制元件作為佈局檔案的activity中呼叫對外暴露的方法,這樣當點選button時便會呼叫介面的方法,進而便會呼叫介面實體中實現的方法,就完成了回撥
`topbar.setTopbarOnClick(new TopbarOnClick() {
@Override public void titleOnClick() { Toast.makeText(getApplicationContext(), "title", 0).show(); } @Override public void rightOnClick() { Toast.makeText(getApplicationContext(), "right", 0).show(); } @Override public void leftOnClick() { Toast.makeText(getApplicationContext(), "left", 0).show(); } });`
-