2017-01-20 8 views
0

ユーザが複数の項目を選択できるように多肢選択ダイアログを実装しました。私はダイアログ内でsearchviewを実装したいと思います。しかし、問題は次のとおりです。 複数選択ダイアログで配列が処理されるため、検索結果に基づいてリストビューを変更できません。私は、この実装をプロジェクトのいくつかのアクティビティでいくつかの で使用しました。これらの多肢選択ダイアログに検索ビューを含めたいと思っています。ですから、私は別のアプローチ、すなわち、検索ビューとカスタムリストビューを含むレイアウトをダイアログに設定するのではなく、マルチチェックダイアログ内でこの方法で修正しようとしています( )。このコードは ArrayIndexOutOfBoundsExceptionをスローします。チェックリスト を変更しようとすると、checkedColours配列とbuildingNames配列の項目の数が最初の長さと異なるためです。このように検索ビューを機能させることはできますか?この方法がうまくいかない場合は、もう1つの方法 に従うようにヒントを提案してください(searchviewとカスタムlistviewのレイアウトをダイアログに使用する)。これに関する助けをいただければ幸いです。前もって感謝します。マルチチェックダイアログでSearchViewを実装する - Android

The dialog looks like the image in this link

protected void showSelectBuildingsDialog(final ArrayList<ResourceModel> buildings) { 

    final boolean[] checkedColours = new boolean[buildings.size()+1]; 
    final HashMap<String,Boolean> tempCheckBuilding=new HashMap<String, Boolean>(); 
    int count = buildings.size(); 
    checkedColours[0]=all; 
    String s=""; 
    for(int i = 0; i < count; i++) { 
     if(flag) { 
      for(int j=0;j<sm.getServiceResourceMaps().size();j++) { 
       if(sm.getServiceResourceMaps().get(j).getResource()!=null) { 
        if (buildings.get(i).getId() == sm.getServiceResourceMaps().get(j).getResource().getId()) { 
         checkedColours[i + 1] = true; 
         if (!s.contains(buildings.get(i).getResourceCode())) { 
          if(s.trim().length()==0) 
           s += buildings.get(i).getResourceCode(); 
          else 
           s += ", "+buildings.get(i).getResourceCode(); 
          tempCheckBuilding.put(buildings.get(i).getResourceCode(), true); 
         } 
        } 
       } 
      } 
     } else 
      checkedColours[i+1]=checkBuilding.get(resourcemodel.get(i).getResourceCode()); 

    } 
    if(flag) { 
     chooseBuildings.setText(s); 

    } 

    final DialogInterface.OnMultiChoiceClickListener coloursDialogListener = new DialogInterface.OnMultiChoiceClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which, boolean isChecked) { 
      ListView list = ((AlertDialog) dialog).getListView(); 
      if(isChecked) { 
       if(which==0) { 
        checkedColours[0] = true; 
        all=true; 
        selectedBuildings.clear(); 

        for (int i=0; i < list.getCount(); i++) { 

         checkedColours[i]=true; 
         list.setItemChecked(i, true); 
         if(i>0) 
          tempCheckBuilding.put(resourcemodel.get(i-1).getResourceCode(),true); 
        } 
        for(int i=0;i<buildings.size();i++) { 
         selectedBuildings.add(buildings.get(i)); 
        } 
       } else { 
        boolean flag=true; 
        for(int i=1;i<checkedColours.length;i++) { 
         if(checkedColours[i]==false) 
          flag=false; 
        } 
        if(flag) 
         list.setItemChecked(0,true); 
        selectedBuildings.add(buildings.get(which - 1)); 
        checkedColours[which]=true; 
        tempCheckBuilding.put(resourcemodel.get(which - 1).getResourceCode(), true); 
       } 
      } else { 
       if(which==0) { 
        checkedColours[0] = false; 
        all=false; 
        for (int i=0; i < list.getCount(); i++) { 

         checkedColours[i]=false; 
         list.setItemChecked(i, false); 
         if(i>0) 
          tempCheckBuilding.put(resourcemodel.get(i-1).getResourceCode(),false); 
        } 
        for(int i=0;i<buildings.size();i++) { 
         selectedBuildings.remove(buildings.get(i)); 
        } 
       } else { 
        checkedColours[0]=false; 
        list.setItemChecked(0,false); 
        selectedBuildings.remove(buildings.get(which - 1)); 
        tempCheckBuilding.put(resourcemodel.get(which-1).getResourceCode(), false); 
        checkedColours[which]=false; 
       } 
      } 

     } 

    }; 

    final AlertDialog.Builder builder = new AlertDialog.Builder(this); 
    builder.setTitle("Select Buildings"); 
    final String[] buildingNames=new String[buildings.size()+1]; 
    buildingNames[0]="Select All Buildings"; 
    for(int i=0;i<buildings.size();i++) { 
     buildingNames[i+1]=buildings.get(i).getResourceCode(); 
    } 
    builder.setPositiveButton("Ok", 
      new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        for(String key:tempCheckBuilding.keySet()) { 
         checkBuilding.put(key,tempCheckBuilding.get(key)); 
        } 
        onChangeSelectedBuildings(); 
        chooseLevels.setText(null); 
        chooseUnits.setText(null); 

        if(chooseBuildings.getText().toString().trim().length()!=0) { 
         //proceed by calling appropriate method 
         } 
        } 
       } 
      }); 
    builder.setNegativeButton("Cancel", 
      new DialogInterface.OnClickListener() { 

       @Override 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 
    builder.setCancelable(true); 
    builder.setMultiChoiceItems(buildingNames, checkedColours, coloursDialogListener); 
    final SearchView searchView=new SearchView(this); 
    builder.setView(searchView); // setting a searchView to the multi choice dialog 
    final AlertDialog dialog = builder.create(); 
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
     @Override 
     public boolean onQueryTextSubmit(String query) { 
//I want to modify the listview in this method, but since 'coloursDialogListener' is dealing with arrays such as 'checkedColours, buildingNames etc, 
//I can't do so. I tried setting an adapter to the listview, but it doesn't seem to help for this reason. 
      ListView listView=((AlertDialog)dialog).getListView(); 
      List<String> list=new ArrayList<String>(); 
      List<Boolean> checkList=new ArrayList<Boolean>(); 
      list.add(buildingNames[0]); 
      checkList.add(checkedColours[0]); 
      try { 
       for (int i = 1; i < buildingNames.length;i++) { 
        listView.getChildAt(i).setVisibility(View.GONE); 
        Log.d("test i",""+i); 
        if (buildingNames[i].contains(query)) { 
         listView.getChildAt(i).setVisibility(View.VISIBLE); 
         list.add(buildingNames[i]); 
         if (i < checkedColours.length) 
          checkList.add(checkedColours[i]); 
        } 
       } 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      return false; 
     } 

     @Override 
     public boolean onQueryTextChange(String newText) { 
      return false; 
     } 
    }); 
    ListView list; 
    if(checkedColours[0]) { 
     selectedBuildings.clear(); 
     list = ((AlertDialog) dialog).getListView(); 
     for (int i=0; i < list.getCount(); i++) { 
      list.setItemChecked(i, true); 
     } 
     for(int i=0;i<buildings.size();i++) { 
      selectedBuildings.add(buildings.get(i)); 
     } 
    } else { 
     list = ((AlertDialog) dialog).getListView(); 
     for (int i=0; i < list.getCount(); i++) { 
      list.setItemChecked(i, false); 
     } 
     for(int i=0;i<buildings.size();i++) { 
      selectedBuildings.remove(buildings.get(i)); 
     } 
    } 
    if(all) 
     list.setItemChecked(0,true); 
    else 
     list.setItemChecked(0,false); 
    dialog.show(); 
} 

これは、クラッシュログです:

java.lang.ArrayIndexOutOfBoundsException: length=3; index=3 
at android.support.v7.app.AlertController$AlertParams$1.getView(AlertController.java:891) 
at android.widget.AbsListView.obtainView(AbsListView.java:2346) 
at android.widget.ListView.measureHeightOfChildren(ListView.java:1281) 
at android.widget.ListView.onMeasure(ListView.java:1188) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954) 
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) 
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) 
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954) 
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1465) 
at android.widget.LinearLayout.measureVertical(LinearLayout.java:748) 
at android.widget.LinearLayout.onMeasure(LinearLayout.java:630) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5954) 
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194) 
at com.android.internal.policy.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2643) 
at android.view.View.measure(View.java:18809) 
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2112) 
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1203) 
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1464) 
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1119) 
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6060) 
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858) 
at android.view.Choreographer.doCallbacks(Choreographer.java:670) 
at android.view.Choreographer.doFrame(Choreographer.java:606) 
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844) 
at android.os.Handler.handleCallback(Handler.java:746) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5443) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 

答えて

0

それはあなたのすべてを助ける可能性があり:

MultiSelectSpinnerれスピナーとSEARCH /フィルタ項目から複数の項目を選択することができますスピナーアイテムから。

public class MultiSpinnerSearch extends Spinner implements OnCancelListener { 

private List<KeyPairBoolData> items; 
//private boolean[] selected; 
private String defaultText; 
private MultiSpinnerSearchListener listener; 
MyAdapter adapter; 

public MultiSpinnerSearch(Context context) { 
    super(context); 
} 

public MultiSpinnerSearch(Context arg0, AttributeSet arg1) { 
    super(arg0, arg1); 
} 

public MultiSpinnerSearch(Context arg0, AttributeSet arg1, int arg2) { 
    super(arg0, arg1, arg2); 
} 

@Override 
public void onCancel(DialogInterface dialog) { 
    // refresh text on spinner 

    StringBuffer spinnerBuffer = new StringBuffer(); 

    for (int i = 0; i < items.size(); i++) { 
     if (items.get(i).isSelected() == true) { 
      spinnerBuffer.append(items.get(i).getName()); 
      spinnerBuffer.append(", "); 
     } 
    } 

    String spinnerText = ""; 
    spinnerText = spinnerBuffer.toString(); 
    if (spinnerText.length() > 2) 
     spinnerText = spinnerText.substring(0, spinnerText.length() - 2); 
    else 
     spinnerText = defaultText; 

    ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(), 
      R.layout.textview_for_spinner, 
      new String[] { spinnerText }); 
    setAdapter(adapterSpinner); 

    if(adapter != null) 
     adapter.notifyDataSetChanged(); 

    listener.onItemsSelected(items); 
} 

@Override 
public boolean performClick() { 

    AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); 
    builder.setTitle(defaultText); 

    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    View view = inflater.inflate(R.layout.alert_dialog_listview_search, null); 
    builder.setView(view); 

    final ListView listView = (ListView) view.findViewById(R.id.alertSearchListView); 
    listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 
    listView.setFastScrollEnabled(false); 
    adapter = new MyAdapter(getContext(), items); 
    listView.setAdapter(adapter); 

    EditText editText = (EditText) view.findViewById(R.id.alertSearchEditText); 
    editText.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      adapter.getFilter().filter(s.toString()); 
     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count, int after) { 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 
     } 
    }); 

    //builder.setMultiChoiceItems(items.toArray(new CharSequence[items.size()]), selected, this); 
    builder.setPositiveButton(android.R.string.ok, 
      new DialogInterface.OnClickListener() { 

     @Override 
     public void onClick(DialogInterface dialog, int which) { 
      Log.i("TAG", " ITEMS : " + items.size()); 
      dialog.cancel(); 
     } 
    }); 

    builder.setOnCancelListener(this); 
    builder.show(); 
    return true; 
} 

public void setItems(List<KeyPairBoolData> items, String allText, int position, 
     MultiSpinnerSearchListener listener) { 

    this.items = items; 
    this.defaultText = allText; 
    this.listener = listener; 

    ArrayAdapter<String> adapterSpinner = new ArrayAdapter<String>(getContext(), 
      R.layout.textview_for_spinner, 
      new String[] { defaultText }); 
    setAdapter(adapterSpinner); 

    if(position != -1) 
    { 
     items.get(position).setSelected(true); 
     //listener.onItemsSelected(items); 
     onCancel(null); 
    } 
} 

public interface MultiSpinnerSearchListener { 
    public void onItemsSelected(List<KeyPairBoolData> items); 
} 

// // Adapter Class    
public class MyAdapter extends BaseAdapter implements Filterable { 

    List<KeyPairBoolData> arrayList;  
    List<KeyPairBoolData> mOriginalValues; // Original Values 
    LayoutInflater inflater; 

    public MyAdapter(Context context, List<KeyPairBoolData> arrayList) { 
     this.arrayList = arrayList; 
     inflater = LayoutInflater.from(context); 
    } 

    @Override 
    public int getCount() { 
     return arrayList.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return position; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    private class ViewHolder { 
     TextView textView; 
     CheckBox checkBox; 
    } 

    @Override 
    public View getView(final int position, View convertView, ViewGroup parent) { 

     ViewHolder holder = null; 

     if (convertView == null) { 

      holder = new ViewHolder(); 
      convertView = inflater.inflate(R.layout.alert_dialog_listview_search_subview, null); 
      holder.textView = (TextView) convertView.findViewById(R.id.alertTextView); 
      holder.checkBox = (CheckBox) convertView.findViewById(R.id.alertCheckbox); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     final KeyPairBoolData data = arrayList.get(position); 

     holder.textView.setText(data.getName()); 
     holder.checkBox.setChecked(data.isSelected()); 

     convertView.setOnClickListener(new View.OnClickListener() 
     { 
      public void onClick(View v) 
      { 
       ViewHolder temp = (ViewHolder) v.getTag(); 
       temp.checkBox.setChecked(!temp.checkBox.isChecked()); 

       int len = arrayList.size(); 
       for (int i = 0; i < len; i++) 
       { 
        if (i == position) 
        { 
         data.setSelected(!data.isSelected()); 
         Log.i("TAG", "On Click Selected : " + data.getName() + " : " + data.isSelected()); 
         break; 
        } 
       } 
      } 
     }); 

     holder.checkBox.setTag(holder); 

     return convertView; 
    } 

    @SuppressLint("DefaultLocale") 
    @Override 
    public Filter getFilter() { 
     Filter filter = new Filter() { 

      @SuppressWarnings("unchecked") 
      @Override 
      protected void publishResults(CharSequence constraint,FilterResults results) { 

       arrayList = (List<KeyPairBoolData>) results.values; // has the filtered values 
       notifyDataSetChanged(); // notifies the data with new filtered values 
      } 

      @Override 
      protected FilterResults performFiltering(CharSequence constraint) { 
       FilterResults results = new FilterResults();  // Holds the results of a filtering operation in values 
       List<KeyPairBoolData> FilteredArrList = new ArrayList<KeyPairBoolData>(); 

       if (mOriginalValues == null) { 
        mOriginalValues = new ArrayList<KeyPairBoolData>(arrayList); // saves the original data in mOriginalValues 
       } 

       /******** 
       * 
       * If constraint(CharSequence that is received) is null returns the mOriginalValues(Original) values 
       * else does the Filtering and returns FilteredArrList(Filtered) 
       * 
       ********/ 
       if (constraint == null || constraint.length() == 0) { 

        // set the Original result to return 
        results.count = mOriginalValues.size(); 
        results.values = mOriginalValues; 
       } else { 
        constraint = constraint.toString().toLowerCase(); 
        for (int i = 0; i < mOriginalValues.size(); i++) { 
         Log.i("TAG", "Filter : " + mOriginalValues.get(i).getName() + " -> " + mOriginalValues.get(i).isSelected()); 
         String data = mOriginalValues.get(i).getName(); 
         if (data.toLowerCase().contains(constraint.toString())) { 
          FilteredArrList.add(mOriginalValues.get(i)); 
         } 
        } 
        // set the Filtered result to return 
        results.count = FilteredArrList.size(); 
        results.values = FilteredArrList; 
       } 
       return results; 
      } 
     }; 
     return filter; 
    } 
} 

}

+0

私は、この種のいくつかのダイアログを有し、リストなどに追加すること、すなわち、選択された項目に対応するオブジェクトに対処する必要があります。だから、私は別のクラスのオブジェクトに対処する必要があります。上記のライブラリを使用するとこれを達成できますか?もちろん、表示されている文字列に対処しなければならないのであれば、まったく問題なく動作します。 –

関連する問題