android開發系列之使用xml自定義控件


      在android開發的過程中,有的時候面對多個Activity里面一些相同的布局,我們需要寫多次相同的代碼,同時這種方法給我們的項目維護也帶來了很大不便。那么有沒有一種可行的辦法能夠將Activity里面相同的布局拆分的很清楚呢?當然是有的,這個時候就輪到自定義控件閃亮登場了。

      其實在android里面有多種方法去實現自定義控件,但是今天這篇博客里面只介紹使用xml的方式進行自定義控件的創建。請看下面的這種場景,不管在哪個頁面里面都有個標題,包括一條居中的文本信息和在左邊的返回按鈕。這個時候我們就可以將上面的標題拆分成一個控件,然后在該控件里面暴露出一個text屬性和一個按鈕的點擊事件。

      首先讓我們先來創建一個前台的xml文件用於放置布局,代碼如下所示:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/test"
    android:gravity="center_vertical">

    <TextView
        android:id="@+id/tvBack"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="<"
        android:layout_alignParentLeft="true" />

    <TextView
        android:id="@+id/tvTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登錄"
        android:layout_centerHorizontal="true"/>

</RelativeLayout>

 可以看到在上面的布局里面,我們只是放置了兩個TextView,一個表示返回,另一個則表示title。

       看到這里聰明的你也許就能猜到了,會不會在自定義控件的時候,我們也同樣需要采用某種方法加載上面的布局文件,然后在加載的時候同時關聯自己定義好的屬性和事件到上面返回的TextView點擊事件和標題的TextView的text屬性呢?是的,請看比較重要的后台關聯代碼類定義:

public class TitleControl extends RelativeLayout {
}

 可以發現TitleControl我們是直接從RelativeLayout繼承而來的,這樣的話TitleControl就屬於一種View控件了。接下來所要做的事情,就是定義屬性和事件了。現在假設我們需要定義一個MyText屬性,那么應該怎么做呢?請看如下代碼:

public class TitleControl extends RelativeLayout {

    private TextView tvBack, tvTitle;
    private String title;

    public TitleControl(Context context) {
        super(context);
    }

    public TitleControl(Context context, AttributeSet attrs) {
        super(context, attrs);

        View view = View.inflate(context, R.layout.activity_title, this);
        tvTitle = (TextView) view.findViewById(R.id.tvTitle);

        tvBack = (TextView) view.findViewById(R.id.tvBack);
        tvBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
               
            }
        });

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.title);
        title = a.getString(R.styleable.title_MyText);
        a.recycle();

        tvTitle.setText(title, TextView.BufferType.SPANNABLE);

    }

    public String getTitle() {
        return this.title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}

 在上面的代碼里面我們通過View的inflate方法加載前台頁面,然后通過findViewById方法就找到了前台需要關聯的控件了。但是我們自己定義的屬性放在哪里呢?一種比較容易維護的做法就是將屬性放置在xml文件里面。下面就讓我們來看看屬性的xml代碼:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="title">
        <attr name="MyText" format="string"/>
    </declare-styleable>
</resources>

        當我們定義好屬性xml之后,就可以通過下面的這段代碼,將我們自己定義的MyText屬性關聯到TextView的Text屬性上面了。這樣就相當於實現了自定義屬性。

TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.title);
title = a.getString(R.styleable.title_MyText);
a.recycle();

tvTitle.setText(title, TextView.BufferType.SPANNABLE);

        做到這里我們就差一個自定義事件了,那么我們怎樣去定義一個事件關聯到TextView的點擊上面呢?答案是通過回調方法的方式實現的,請看回調方法的定義:

private ITitleCallback iTitleCallback;

    public interface ITitleCallback {
        void OnBackClickLinear();
    }

    public void setTitleClickLinear(ITitleCallback iTitleCallback) {
        this.iTitleCallback = iTitleCallback;
    }

 然后在TextView點擊的時候執行如下代碼就可以了:

tvBack = (TextView) view.findViewById(R.id.tvBack);
        tvBack.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if(iTitleCallback!=null){
                    iTitleCallback.OnBackClickLinear();
                }
            }
        });

       好了,今天就到這里吧!如有不對,歡迎拍磚。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM