Android 的一个通用列表单选AlertDialog封装
package cn.fstudio.util; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import cn.fstudio.haodapush.yr.R; import android.R.integer; import android.R.string; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.CheckBox; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.ArrayAdapter; import android.widget.DatePicker; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.Spinner; import android.widget.TimePicker; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.AdapterView.OnItemSelectedListener; public class AD4ListView implements OnItemLongClickListener { public final String ButtonSure = "Sure"; public final String ButtonCancel = "Cancel"; ListView lv=null; private List<Map<String, Object>> allDatas=null; private List<Map<String, Object>> filterDatas=null; SimpleAdapter adapter = null; private Spinner spGroup=null; public String SelectedGroup="全部"; ArrayList<String> groupList=null; private List<Object> _items=null; private Context _context = null; private OnListViewCallback _callback = null; private String _msg=""; public Object SelectedItem=null; //注意数据类型要匹配,RecId 后面要加L //否则Integer与Long不匹配的 public Object SelectedValue=null; //确定是否当前选择中项字段名称 public String ValueField=""; //分组组用字段名称 public String GroupField=""; private List<AD4ListViewMap> _maps=null; private boolean isSpinnerInit=true; public AD4ListView(Context context, String msg, List items,List<AD4ListViewMap> maps, OnListViewCallback callback) { _context = context; _items = items; _callback = callback; _msg = msg; _maps=maps; } private void initSpinner(){ //==设置下拉框数据========== groupList=new ArrayList<String>(); groupList.add("全部"); HashMap<String, Integer> map=new HashMap<String, Integer>(); for (Object item : _items) { if(StringUtil.isNullOrEmpty(GroupField))break; String groupValueStr=getGroupFieldValue(item); if(!map.containsKey(groupValueStr)){ map.put(groupValueStr, 1); groupList.add(groupValueStr); } } final ArrayAdapter<String> spadapter = new ArrayAdapter<String>(_context, android.R.layout.simple_spinner_item,groupList); // 设置下拉列表的风格 spadapter.setDropDownViewResource(android.R.layout.simple_selectable_list_item); // 将adapter 添加到spinner中 spGroup.setAdapter(spadapter); //设置默认选中项 if (groupList.size() > 1) { for (int i = 0; i < groupList.size(); i++) { String group = groupList.get(i); if (group.equalsIgnoreCase(SelectedGroup)) { spGroup.setSelection(i); } } } spGroup.setOnItemSelectedListener(new OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long arg3) { SelectedGroup=groupList.get(position); if(isSpinnerInit){ isSpinnerInit=false; return; } filterDatas(); adapter.notifyDataSetChanged(); } @Override public void onNothingSelected(AdapterView<?> arg0) { // TODO Auto-generated method stub } }); } private String getGroupFieldValue(Object obj){ try{ if(StringUtil.isNullOrEmpty(GroupField))return ""; String methodName="get" + GroupField; Method method= obj.getClass().getDeclaredMethod(methodName, null); Object fieldVObj= method.invoke(obj, null); if(fieldVObj==null)return ""; return fieldVObj.toString(); }catch(Exception ex){} return ""; } private Object getValueFieldValue(Object obj){ return getFieldValue(obj, ValueField); } private Object getFieldValue(Object obj,String fieldName){ if(StringUtil.isNullOrEmpty(fieldName))return null; try{ String methodName="get" + fieldName; Method method= obj.getClass().getDeclaredMethod(methodName, null); Object fieldVObj= method.invoke(obj, null); return fieldVObj; }catch(Exception ex){} return null; } private void filterDatas() { // TODO Auto-generated method stub if(filterDatas==null){ filterDatas=new ArrayList<Map<String, Object>>(); }else { filterDatas.clear(); } for(int i=0;i<allDatas.size();i++){ Object item=allDatas.get(i).get("item"); String itemGroupValue= getGroupFieldValue(item); if(SelectedGroup.equals("全部")){ filterDatas.add(allDatas.get(i)); }else { if(SelectedGroup.equals(itemGroupValue)){ filterDatas.add(allDatas.get(i)); }; } } } // 调用一次 private void initDatas() { allDatas=new ArrayList<Map<String, Object>>(); for (int i = 0; i < _items.size(); i++) { Object item = _items.get(i); HashMap<String, Object> data = new HashMap<String, Object>(); allDatas.add(data); data.put("my", data); data.put("item", item); if (SelectedValue != null && !StringUtil.isNullOrEmpty(ValueField)) { Object fieldVObj = getValueFieldValue(item); boolean isEq = SelectedValue.equals(fieldVObj); if (isEq) SelectedItem = item; data.put("checked", isEq); } else { data.put("checked", false); } for (AD4ListViewMap map : _maps) { Object fieldVObj = getFieldValue(item,map.FieldName); String fieldVStr = fieldVObj == null ? "" : fieldVObj .toString(); if (fieldVObj!=null && fieldVObj.getClass() == Date.class) { fieldVStr = DateUtil.formatWithMinute((Date) fieldVObj); } data.put("Item" + map.Index, map.FieldTitle + ":" + fieldVStr); } } } private void bindAdapter(){ int[] to = new int[] { R.id.Item0,R.id.Item1,R.id.Item2,R.id.Item3,R.id.Item4,R.id.Item5,R.id.Item6,R.id.ckbIt }; String[] from = new String[] {"Item0","Item1","Item2","Item3","Item4","Item5","Item6","my"}; adapter = new SimpleAdapter(_context, filterDatas, R.layout.list_item_dialog, from, to); // =======添加事件======= SimpleAdapter.ViewBinder binder = new SimpleAdapter.ViewBinder() { private boolean supressEvent=false; @Override public boolean setViewValue(View view, Object data, String textRepresentation) { final Object d = data; if (view instanceof CheckBox) { final Map map=(Map)d; CheckBox ckb = (CheckBox) view; //ckb.setTag(map); supressEvent=true; //需要避免在这里触发OnCheckedChange事件监听处理 ckb.setChecked((Boolean)map.get("checked")); supressEvent=false; ckb.setOnCheckedChangeListener(new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(supressEvent)return; for (Map data : allDatas) { data.put("checked", false); } //Map map=(Map)buttonView.getTag(); map.put("checked", isChecked); Object item=map.get("item"); if(isChecked){ SelectedItem=item; }else{ SelectedItem=null; } if(!StringUtil.isNullOrEmpty(ValueField) ){ Object fieldVObj= getValueFieldValue(item); SelectedValue=fieldVObj; } adapter.notifyDataSetChanged(); } }); return true; //返回true表示不需要父类进行默认设置 //参考http://www.cnblogs.com/carmanloneliness/p/3500832.html //http://www.cnblogs.com/carmanloneliness/p/3500832.html } return false; } }; adapter.setViewBinder(binder); // =======End======= lv.setAdapter(adapter); } public void show() { AlertDialog.Builder builder = new AlertDialog.Builder(_context); builder.setIcon(R.drawable.ic_launcher); builder.setTitle(_msg); // 通过LayoutInflater来加载一个xml的布局文件作为一个View对象 View view = LayoutInflater.from(_context).inflate( R.layout.list_dialog, null); // 设置我们自己定义的布局文件作为弹出框的Content builder.setView(view); lv = (ListView) view.findViewById(R.id.listView1); lv.setOnItemLongClickListener(this); spGroup=(Spinner)view.findViewById(R.id.spGroup); initSpinner(); initDatas(); filterDatas(); bindAdapter(); adapter.notifyDataSetChanged(); builder.setPositiveButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (_callback != null) { _callback.OnClick("Sure", ValueField,SelectedValue,SelectedItem); } } }); builder.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (_callback != null) { _callback.OnClick("Cancel",ValueField,SelectedValue,SelectedItem); } } }); builder.show(); } @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub return false; } //属性反射读取针对private //Field field= item.getClass().getDeclaredField(fieldName); //Class<?> typeClass= field.getType(); //field.setAccessible(true); //if(typeClass==String.class){ // Object vObject= field.get(item); // if(vObject!=null){ // System.out.print(vObject.toString()); // } // } }
//调用代码
private void customerDialogShow(){ List<AD4ListViewMap> maps=new ArrayList<AD4ListViewMap>(); maps.add(new AD4ListViewMap(0,"CustomerName","名称")); maps.add(new AD4ListViewMap(1,"RecId","记录号")); maps.add(new AD4ListViewMap(2,"CustomerNo","客户号")); maps.add(new AD4ListViewMap(3,"GroupNo","分组")); maps.add(new AD4ListViewMap(5,"Memo","备注")); maps.add(new AD4ListViewMap(4,"AddTime","时间")); AD4ListView ad=new AD4ListView(_CurContext, "选择客户", UserSetting.customerList,maps, _customerCallback); ad.SelectedValue="00004"; ad.ValueField="CustomerNo"; ad.GroupField="GroupNo"; ad.SelectedGroup="客户分组1"; ad.show(); }
//UI设计
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="blocksDescendants" android:orientation="horizontal">" <LinearLayout android:layout_width="0dp" android:layout_weight="1" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="0dp" android:orientation="horizontal" > <TextView android:id="@+id/Item0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Item0" android:textColor="#0D17DD" android:textSize="15dp" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <LinearLayout android:layout_width="100dp" android:layout_height="wrap_content" android:layout_marginLeft="0dp" android:layout_weight="0" android:orientation="vertical" > <TextView android:id="@+id/Item1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Item1" android:textColor="#000000" /> <TextView android:id="@+id/Item3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Item3" android:textColor="#000000" /> </LinearLayout> <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginLeft="0dp" android:layout_weight="1" android:orientation="vertical" > <TextView android:id="@+id/Item2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Item2" android:textColor="#000000" /> <TextView android:id="@+id/Item4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Item4" android:textColor="#000000" /> </LinearLayout> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="0dp" android:layout_weight="1" android:orientation="vertical" > <TextView android:id="@+id/Item5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Item5" android:textColor="#000000" /> <TextView android:id="@+id/Item6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Item6" android:textColor="#000000" /> </LinearLayout> </LinearLayout> <CheckBox android:id="@+id/ckbIt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="" /> </LinearLayout>
Listview中采用固定0-6 个TextView,Id分别是Item0-Item6
//设置默认选中项
ad.SelectedValue 需要设置成对应的数据类型,比如
ad.ValueField="RecId"时,其数据类型是Long,
ad.SelectedValue=2L, 其他Double,Boolean,Integer 类似。
内部采用了obj.equals()
可以不指定默认选择项(不设置ad.ValueField)
//关于分组
不设置ad.GroupField="xxx" ;时不填充分组选择下拉框
DTO对应GroupField的类型需要是String
SelectedGroup 默认等于 "全部",可以设置成需要显示的分组
可以不指定默认分组(不设置GroupField)