項目用到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,如果改爲其他的話可能會要重寫很多。
不過畢竟是全靠自己寫出來的東西,解決了一個效率問題,積累了經驗,在這裏分享出來方便自己和其他人查閱,這條路還很長,慢慢走。