學習筆記:Dialog重用類

  項目用到Dialog的彈出對話框來選擇參數,要設置大量顯示選擇內容的Dialog,如下圖,點擊文字TextView之後可以彈出一堆選擇項自定義的Dialog一個一個地建立Dialog太麻煩,所以我想要寫一個用於方便的可重用的建立Dialog彈出選擇框的類。

點擊後可彈出Dialog:

未使用重用類時

要這樣一個一個地建立Dialog:

public class ProudctParameter_select extends Activity {

      private TextView textView;


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


        //參數選擇按鈕初始化監聽
        textView =(TextView)findViewById(R.id.text2);
        //TextView綁定點擊監聽
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View arg0) {
                AlertDialog.Builder builder = new AlertDialog.Builder(ProudctParameter_select.this);
                builder.setTitle("選擇一個參數");
                //    指定下拉列表的顯示數據
                final String[] productType = {"電子電器零件", "建築材料", "醫療器械", "家用五金", "食用器皿", "交通器材", "運動器材", "照明設備", "家電產品", "辦公器具", "光學用品"};

                //    設置一個下拉的列表選擇項
                builder.setItems(productType, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        textView.setText(productType[which]);
                    }
                });
                builder.show();
            }
        });

    //...之後就是重複上面的操作
}

像這樣一個一個Dialog重複寫的話會弄出很多的代碼,非常難看,所以我就想着能不能弄一個類,來可以大量地重用這種Dialog的創建。

建立重用類來重用Dialog

  由於建立Dialog彈出選擇框需要綁定兩個點擊監聽器,一個用來監聽對TextView的點擊,一個用來監聽對Dialog裏面選項列表的點擊,在裏面的點擊操作需要用到textView和設置內容時候可供選擇內容字符串productType,用上面的自帶點擊監聽器是不能傳入參數的,而且把它寫成匿名內部類的話,這兩個參數也傳不進去,你想在裏面的Onclick函數裏面操作textview也做不到,所以需要寫兩個新的點擊監聽器。
  通過對點擊監聽器的瞭解可以知道,點擊監聽器的作用就是監聽被綁定控件的點擊狀態,被點擊之後就會調用onClick函數,所以寫新的OnClickListener只需要繼承原來的點擊監聽器,然後重寫onClick函數就能實現想要的效果了。

看代碼
DialogReuse.java:

package scut.dialogreuse;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.View;
import android.widget.TextView;

import java.util.List;


//對話框大量重用類
public class DialogReuse {


    //重用選擇對話框使用入口,調用此方法,輸入三個參數:上下文,綁定後的TextView列表,選擇內容列表數組。
    public void DialogChooseList(final Context context, List<TextView> textViews,List<String[]> selectedDataList){
        for (int i = 0;i<textViews.size();i++){
            textViews.get(i).setOnClickListener(new DialogOnClickListener(textViews.get(i),selectedDataList.get(i),context));
        }
    }


    //重寫TextView的點擊監聽器,讓它可以傳入TextView,List<String>等參數
    class DialogOnClickListener implements View.OnClickListener{
        private TextView textView;
        private String[] selectedList;
        private Context mcontext;
        public DialogOnClickListener(TextView tv,String[] sList,Context context){
            textView = tv;
            selectedList = sList;
            mcontext = context;
        }

        //設置點擊事件,點擊TextView後彈出Dialog
        @Override
        public void onClick(View v) {
            AlertDialog.Builder builder = new AlertDialog.Builder(mcontext);
            builder.setTitle("選擇一個參數");
            //    設置一個下拉的列表選擇項
            builder.setItems(selectedList, new DialogSelectedItemOnClickListener(textView,selectedList));
            builder.show();
        }
    }


    //重寫Dialog的點擊監聽器,讓它可以傳入TextView,List<String>等參數
    class DialogSelectedItemOnClickListener implements DialogInterface.OnClickListener{
        private TextView ctv;
        private String[] selectedList;
        public DialogSelectedItemOnClickListener(TextView ctextView, String[] sList){
            ctv = ctextView;
            selectedList = sList;
        }
        //設置點擊事件
        @Override
        public void onClick(DialogInterface dialog, int which) {
            ctv.setText(selectedList[which]);
        }
    }
}

  在這裏通過新寫的兩個點擊監聽器,把對象傳進去,讓數組裏面的每一個TextView綁定對應的監聽器和選項內容。

重用類的使用

  在MainActivity裏使用這個重用類,只需要把需要綁定的TextViewfindViewById之後和選擇項的內容都一一對應地放進數組(其實這裏後來我想想覺得用List<HashMap<TextView,String[]>>裝裏面的數據是不是會更好),然後調用這個重用類裏的函數DialogChooseList就行了:

package scut.dialogreuse;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private TextView textView1,textView2;
    private List<TextView> textViewList;
    private List<String[]> selectedDataList;
    private final String[] selectedData1 = {"電子電器零件", "建築材料", "醫療器械", "家用五金", "食用器皿", "交通器材", "運動器材", "照明設備", "家電產品", "辦公器具", "光學用品"};
    private final String[] selectedData2 = {"語文","數學","英語"};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView1 = (TextView) findViewById(R.id.textView1);
        textView2 = (TextView) findViewById(R.id.textView2);

        textViewList = new ArrayList<TextView>();//把用到的TextView放入List
        textViewList.add(textView1);
        textViewList.add(textView2);

        selectedDataList = new ArrayList<String[]>();//把用到的選擇內容字符串數組放入List
        selectedDataList.add(selectedData1);
        selectedDataList.add(selectedData2);

        //使用Dialog重用類
        DialogReuse mdialogReuse = new DialogReuse();
        mdialogReuse.DialogChooseList(this,textViewList,selectedDataList);


    }
}

佈局文件(隨手用了個Button做間隔(⊙﹏⊙)b)
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="scut.dialogreuse.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/textView1"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="間隔"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello Man!"
        android:id="@+id/textView2"/>
</LinearLayout>

擴展

  然而需求一不小心就改變了,改成想要一點擊TextView所在的那一行就可以彈出Dialog選擇框,不過這樣在我看來只需要用一個Layout包住每一個TextView,然後把點擊監聽器的綁定對象由TextView改成Layout就行了,由於這個綁定是在DialogChooseList函數裏面的,所以我直接重新加一個函數進去DialogReuse類裏面就行了:

    //點擊Layout就觸發Dialog的綁定函數
    public void DialogChooseListByLayout(final Context context, List<TextView> textViews, List<String[]> selectedDataList, List<ViewGroup> layoutList){
        for (int i = 0;i<layoutList.size();i++){
            layoutList.get(i).setOnClickListener(new DialogOnClickListener(textViews.get(i),selectedDataList.get(i),context));
        }
    }

  然後在Activity裏面傳入多一個Layout數組就行了(PS:由於RelativeLayout和LinearLayout這些都是繼承自ViewGroup類所以直接用List<ViewGroup>數組):

  //實現Layout點擊觸發
        mdialogReuse.DialogChooseListByLayout(this,textViewList2,selectedDataList,layoutList);

具體代碼和上面有很多重複就不貼了,有興趣的可以在我後面的下載我的代碼。

這樣點擊TextView周圍的Layout區域就可以觸發出Dialog了。

總結

  我覺得我寫的這個Dialog重用類還是有很大的改進空間的,就比如我上面說的用List<HashMap<TextView,String[]>>裝數據,還有它的可擴展性也不是很好,就是侷限在TextView,如果改爲其他的話可能會要重寫很多。
  不過畢竟是全靠自己寫出來的東西,解決了一個效率問題,積累了經驗,在這裏分享出來方便自己和其他人查閱,這條路還很長,慢慢走。


代碼地址:https://github.com/totond/DialogReuse

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章