1. 程式人生 > >自定義控制元件01---簡單view的實現

自定義控制元件01---簡單view的實現

對於每一個應用來說幾乎都會有一個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();
    
        }
    });`
    
  • -