自定义Combobox
public class Combobox extends TextView { private Context context; private Dialog mDialog; private List<String> mItems; private String title ; private TextView titleText; private List<CodenamePair> pairs; private boolean isMultipleChoice; private HashMap<Integer, String> choiceItemsMap; private boolean argIsList; private int position = -1; private List<Integer> posList; private CboxDialogArrayAdapter adapter; public void setDialogItems(ArrayList<String> mItems) { this.mItems = mItems; argIsList = false; } public void setDialogItems(String[] mItems) { this.mItems = Arrays.asList(mItems); argIsList = false; } public void setDialogItems(List<CodenamePair> cnPairs) { this.pairs = cnPairs; List<String> items = null; argIsList = true; if(cnPairs != null ){ int len = cnPairs.size(); items = new ArrayList<String>(); for (int i = 0; i < len; i++){ items.add(cnPairs.get(i).getName()); } } this.mItems = items; } public Combobox(Context context, ArrayList<String> items) { super(context); init(context, null); this.mItems = items; } public Combobox(Context context, AttributeSet attrs){ super(context, attrs); init(context, attrs); } private void init(Context context, AttributeSet attrs){ this.isMultipleChoice = context.obtainStyledAttributes(attrs, R.styleable.Combobox).getBoolean(R.styleable.Combobox_isMultipleChoice, false); this.context = (context == null ? getContext() :context); this.setBackgroundResource(android.R.drawable.editbox_background_normal); //Combobox的向下的图标 Drawable drawable = getResources().getDrawable(R.drawable.dropdown); drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight()); this.setCompoundDrawables(null, null, drawable, null); this.setOnClickListener(clickListener); titleText = (TextView) LayoutInflater.from(context).inflate(R.layout.layout_combobox_dialog_title, null); } OnClickListener clickListener = new OnClickListener() { @Override public void onClick(View v) { if(choiceItemsMap == null) choiceItemsMap = new HashMap<Integer, String>(); showDialog(); } }; List<Integer> selPostion = new ArrayList<Integer>(); private boolean showDialog() { selPostion.clear(); if(position >= 0){ selPostion.add(position); }else if(posList != null && posList.size() > 0){ selPostion.addAll(posList); } if(mDialog == null){ mDialog = createDialog(); if (mDialog == null) { return false; } } if(posList == null) posList = new ArrayList<Integer>(); mDialog.show(); if(mItems.size() > 5){ mDialog.getWindow().setLayout(mDialog.getWindow().getAttributes().width, 500); }else{ mDialog.getWindow().setLayout(mDialog.getWindow().getAttributes().width, WindowManager.LayoutParams.WRAP_CONTENT); } return true; } private Dialog createDialog() { if(mItems == null){return null;} AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(title); adapter = new CboxDialogArrayAdapter(context, mItems, selPostion, isMultipleChoice); builder.setAdapter(adapter, itemClickListener); builder.setCancelable(true); AlertDialog dialog = builder.create(); dialog.setCustomTitle(titleText); if(isMultipleChoice){ dialog.setButton(DialogInterface.BUTTON_POSITIVE, context.getString(R.string.combobox_button_positive), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { StringBuffer text = new StringBuffer(); if(choiceItemsMap != null && choiceItemsMap.size() > 0){ Iterator<String> iterator = choiceItemsMap.values().iterator(); while (iterator.hasNext()){ if(text.length() != 0) text.append(","); text.append(iterator.next()); } } setText(text); setAutoCloseDialog(dialog, true); dialog.cancel(); } }); dialog.setButton(DialogInterface.BUTTON_NEGATIVE, context.getString(R.string.combobox_button_negative), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { setAutoCloseDialog(dialog, true); dialog.cancel(); } }); } return dialog; } private DialogInterface.OnClickListener itemClickListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int pos) { setAutoCloseDialog(dialog, false); String content = mItems.get(pos); CheckedTextView textView = (CheckedTextView) adapter.getItem(pos); if(isMultipleChoice){ boolean isChecked = !posList.contains(new Integer(pos)); if(isChecked && !choiceItemsMap.containsKey(pos)){ choiceItemsMap.put(pos, content); posList.add(pos); textView.setChecked(true); }else if(choiceItemsMap.containsKey(pos)){ choiceItemsMap.remove(pos); posList.remove(new Integer(pos)); textView.setChecked(false); } }else{ textView.setChecked(true); position = pos; setText(content); setAutoCloseDialog(dialog, true); dialog.cancel(); } } }; private void setAutoCloseDialog(DialogInterface dialog, boolean isClose){ try { Field field = dialog.getClass().getSuperclass().getDeclaredField("mShowing"); field.setAccessible(true); field.set(dialog, isClose); ((AlertDialog)dialog).setCancelable(true); } catch (NoSuchFieldException e) { Log.e("NoSuchFieldException", e.getMessage()); } catch (IllegalAccessException e) { Log.e("IllegalAccessException", e.getMessage()); } } public List<CodenamePair> getSelectedItems(){ if(!isMultipleChoice) return null; List<CodenamePair> selList = new ArrayList<CodenamePair>(); if(argIsList && posList != null){ for (int i = 0; i < posList.size(); i++){ selList.add(pairs.get(posList.get(i))); } }else { if(choiceItemsMap != null){ Iterator<String> iterator = choiceItemsMap.values().iterator(); CodenamePair pair = null; while (iterator.hasNext()){ pair = new CodenamePair(); pair.setName(iterator.next()); selList.add(pair); } } } return selList; } public void setSelectedItems(List<CodenamePair> selItems){ if((selItems == null || selItems.size() <= 0) || !isMultipleChoice || (mItems == null && pairs == null)) return; if(choiceItemsMap == null) choiceItemsMap = new HashMap<Integer, String>(); int size = argIsList ? pairs.size() : mItems.size(); for (int i = 0; i < size; i++){ String code = null; String name = null; if(argIsList){ code = pairs.get(i).getCode(); name = pairs.get(i).getName(); }else{ name = mItems.get(i); } for (CodenamePair pair : selItems){ if ((StringUtil.isNotBlank( code ) && code.equals(pair.getCode())) || (!StringUtil.isNotBlank(pair.getCode()) && name.equals(pair.getName()))){ if(posList == null) posList = new ArrayList<Integer>(); posList.add(new Integer(i)); choiceItemsMap.put(new Integer(i), name); } } } if(posList != null && posList.size() > 0){ StringBuffer text = new StringBuffer(); Iterator<String> iterator = choiceItemsMap.values().iterator(); while (iterator.hasNext()){ if(text.length() != 0) text.append(","); text.append(iterator.next()); } setText(text); } } public CodenamePair getSelectedItem(){ if(isMultipleChoice || position < 0) return null; CodenamePair pair = null; if(argIsList){ pair = pairs.get(position); }else{ pair = new CodenamePair(); pair.setName(mItems.get(position)); } return pair; } public void setSelectedItem(CodenamePair pair){ if(pair == null || isMultipleChoice || (mItems == null && pairs == null)) return; int size = argIsList ? pairs.size() : mItems.size(); for (int i = 0; i < size; i++){ String code = null; String name = null; if(argIsList && pairs != null){ CodenamePair cnPair = pairs.get(i); code= cnPair.getCode(); name = cnPair.getName(); }else if(mItems != null){ name = mItems.get(i); } if (StringUtil.isNotBlank(code) && code.equals(pair.getCode())){ position = i; setText(name); break; }else if(!StringUtil.isNotBlank(pair.getCode()) && name.equals(pair.getName())){ position = i; setText(name); break; } } } public String getTitle() { return title; } public void setTitle(String title) { if(titleText != null){ titleText.setText(title); } this.title = title; } public void clear(){ position = -1; if(posList != null) posList.clear(); if(choiceItemsMap != null) choiceItemsMap.clear(); setText(null); } }
CodenamePair类
public class CodenamePair { private String code; private String name; public CodenamePair(){ disStatus = 2; extraData = new HashMap<String,String>(); } public CodenamePair(String code,String name){ disStatus = 2; extraData = new HashMap<String,String>(); this.code = code; this.name = name; } public String getCode(){ return code; } public String setCode(String code){ return this.code=code; } public String getName(){ return name; } public String setName(String name){ return this.name=name; } }
attrs.xml文件,定义isMultipleChoice属性,Combobox是否多选
<declare-styleable name="Combobox"> <attr name="isMultipleChoice" format="boolean"></attr> </declare-styleable>
Combobox Item 的样式文件 layout_combobox_dialog_item.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="wrap_content"> <CheckedTextView android:visibility="gone" android:id="@+id/combobox_dialog_item_radioButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?android:attr/listPreferredItemHeight" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/textColorAlertDialogListItem" android:gravity="center_vertical" android:paddingLeft="18dp" android:paddingEnd="7dp" android:checkMark="?android:attr/listChoiceIndicatorSingle" android:ellipsize="marquee"/> <CheckedTextView android:visibility="visible" android:id="@+id/combobox_dialog_item_checkBox" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?android:attr/listPreferredItemHeight" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/textColorAlertDialogListItem" android:gravity="center_vertical" android:paddingLeft="18dp" android:paddingEnd="7dp" android:checkMark="?android:attr/listChoiceIndicatorMultiple" android:ellipsize="marquee"/> </RelativeLayout>
Combobox tittle 样式文件layout_combobox_dialog_title.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="15dp" android:paddingTop="15dp" android:paddingLeft="10dp" android:textColor="@color/black" android:background="@color/gray" android:textAppearance="?android:attr/textAppearanceLarge" android:text="combobox_title_text" android:id="@+id/combobox_title" />