项目用到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,如果改为其他的话可能会要重写很多。
不过毕竟是全靠自己写出来的东西,解决了一个效率问题,积累了经验,在这里分享出来方便自己和其他人查阅,这条路还很长,慢慢走。