天天看點

Android中基類BaseActivity的設計與實作

最近在做項目的時候,項目涉及到了與伺服器的互動,那麼自然而然的在與伺服器互動的過程中,會出現網絡連接配接失敗的情況,那麼我們這時候就應該在界面上顯示“網絡故障”之類的提示語來提醒使用者,一個activity的實作這種功能還好,就是在xml裡放一個布局,平常時候設定屬性android:visibility=”gone”,而一旦捕獲到網絡異常的情況,設定這個布局的屬性為android:visibility=”visible”,可是一旦activity數量一多,那這個布局也就要重複的findViewById,頻繁的設定View visibility屬性,很明顯,代碼備援了,那麼怎麼解決這個問題呢?這裡就要用到安卓中基類的設計了。筆者寫了一個小DEMO實作了一下,運作效果圖如下:

Android中基類BaseActivity的設計與實作

看了這個動态圖,不少人大呼:你這是什麼?點兩個按鈕?點了兩個textview?彈出了兩下toast?就完了?事實上兩個按鈕是為了模拟網絡環境的變化,而textview的顯示與後退的箭頭退出應用程式都用到了基類,如果我們一個項目有幾十個activity,那麼我們要把回退箭頭findViewById幾十遍?然後設定幾十遍點選事件嗎?很明顯寫重複的代碼不是我們所想要的,好了,現在開工吧。

建立一個BaseActivity繼承與Activity,在這個基類中寫好一些代碼,然後讓其它的activity繼承于BaseActivity就可以了,BaseActivity的xml檔案如下:

base_activity.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:orientation="vertical" >

     <include 
        layout="@layout/title_bar_layout"
        />

    <include 
        layout="@layout/exception_layout"
        />


</RelativeLayout>
           

其中包含了兩個layout,其中的title_bar_layout.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="46dip"
    android:orientation="vertical"
    android:background="#0374D9" >

    <ImageView
        android:id="@+id/iv_back"
        android:layout_width="50dip"
        android:layout_height="match_parent"
        android:scaleType="centerInside"
        android:layout_alignParentLeft="true"
        android:layout_centerVertical="true"
        android:src="@drawable/back_arrow_left" />

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="18sp"
        android:textColor="#ffffff"
        android:text="頁面标題" />

</RelativeLayout>
           

exception_layout.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"
   >
     <TextView
        android:id="@+id/tv_no_net"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="20sp"
        android:textColor="#000"
        android:visibility="gone"
        android:text="暫無網絡" />

      <TextView
        android:id="@+id/tv_no_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textSize="20sp"
        android:textColor="#000"
        android:visibility="gone"
        android:text="暫無資料" />


</RelativeLayout>
           

exception_layout裡面放了兩個textview,就是頁面無資料時候顯示的内容,還有是網絡連接配接失敗時顯示的内容。

好了,現在來看看BaseActivity代碼:

public abstract class BaseActivity extends Activity {
    //沒有網絡的提示資訊
     TextView tv_no_net;
     //伺服器傳回的json資料為空,那麼應該顯示沒有資料的頁面
     TextView tv_no_info;
     //标題欄的傳回按鈕
     ImageView iv_back;
     //标題欄的标題文字
     TextView tv_title;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.base_activity);
   initContentView(savedInstanceState);
   init();


}
private void init() {
    tv_no_net=(TextView) findViewById(R.id.tv_no_net);
    tv_no_info=(TextView) findViewById(R.id.tv_no_info);
    iv_back=(ImageView) findViewById(R.id.iv_back);
    tv_title=(TextView) findViewById(R.id.tv_title);
    tv_no_net.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            OnNoNetClick(v);;
        }
    });
    tv_no_info.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            OnNoInfoClick(v);

        }
    });
    iv_back.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            OnBackClick(v);

        }
    });
    tv_title.setText(SetTitleString());

}
//一些抽象方法,繼承了BaseActivity的類必須實作這些方法
protected abstract String SetTitleString();
protected abstract void OnBackClick(View v);
protected abstract void OnNoNetClick(View v);
protected abstract void OnNoInfoClick(View v);
protected abstract void initContentView(Bundle savedInstanceState);
protected void setNoNet(){
    tv_no_net.setVisibility(View.VISIBLE);
    tv_no_info.setVisibility(View.GONE);
}
protected void setNoInfo(){
    tv_no_net.setVisibility(View.GONE);
    tv_no_info.setVisibility(View.VISIBLE);
}

}

           

BaseActivity類添加了abstract關鍵字,那麼說明該類是抽象類,

一個抽象類裡面可以有抽象方法,也可以沒有抽象方法;

可以有普通方法,也可以沒有普通方法;

但是,如果一個類裡面有abstract修飾的方法,那麼該類肯定是抽象類。

一個類繼承了一個抽象父類,那麼必須要實作父類中所有的抽象方法;

建議對abstract概念模糊的同學了解一下基礎,再來看這篇文章。

好了,那麼,我們的MainActivity就繼承BaseActivity了~~~自然而然要實作父類的抽象方法,具體看MainActivity代碼:

public class MainActivity extends BaseActivity {

    @Override
    protected void initContentView(Bundle savedInstanceState) {
        setContentView(R.layout.activity_main);

        Button bt_no_info=(Button) findViewById(R.id.bt_no_info);
        Button bt_no_net=(Button) findViewById(R.id.bt_no_net);
        //這兩個按鈕是模拟兩種情況,
        bt_no_info.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //當網絡故障時,調用該方法
                setNoNet();

            }
        });
        bt_no_net.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                //當這個頁面沒有資料顯示時,調用該方法
                setNoInfo();
            }
        });
    }

    @Override
    protected void OnNoNetClick(View v) {
        Toast.makeText(getApplicationContext(), "no net click", ).show();

    }

    @Override
    protected void OnNoInfoClick(View v) {
        Toast.makeText(getApplicationContext(), "no info click", ).show();

    }

    @Override
    protected String SetTitleString() {

        return "這是第一個頁面";
    }

    @Override
    protected void OnBackClick(View v) {
        finish();

    }

}
           

MainActivity中的兩個button點選事件是為了模拟網絡環境的變化,

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rl_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <include
        android:id="@+id/title_bar"
        layout="@layout/title_bar_layout" />

    <include layout="@layout/exception_layout" />

    <Button
        android:id="@+id/bt_no_net"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/title_bar"
        android:text="顯示無網絡情況" />

    <Button
        android:id="@+id/bt_no_info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title_bar"
        android:layout_toRightOf="@+id/bt_no_net"
        android:text="顯示無資料情況" />

</RelativeLayout>
           

好了,就說這麼多了,具體還是要自己體會abstract這個關鍵點~~