2017-09-14 85 views
-1

我有一個BaseExpandableListAdapter(代碼如下)來操縱ExpandableListView和一個名爲Checklist的模型。在滾動ExpandableListView時複製選擇複選框

清單模型包含一個類別列表。 類別是檢查列表。 檢查是低點列表。 And a Low包含一個布爾項,這個布爾項由視圖中的複選框表示。

我使用ViewHolder模式來處理我的模型:我的GroupView的CategoryViewHolder和我的ChildView的CheckViewHolder。

我遇到的問題是在getChildView方法中,當我在Low(檢查內)中選擇一個複選框並向下滾動時,我發現選中了其他複選框。 當我在Check和I滾動內的edittext對象中寫入內容時,會發生同樣的事情,編輯其他edittext。

我懷疑我的vue回收工作不正常,但我還沒有找到任何解決方案。

任何想法?

public class ChecklistAdapter extends BaseExpandableListAdapter { 
private Context mContext; 
private Checklist mChecklist; 
private boolean isEditable; 
private final int ID_LOW_ADDED = -1; 


public ChecklistAdapter(Context mContext, Checklist mChecklist, boolean editable) { 
    this.mContext = mContext; 
    this.mChecklist = mChecklist; 
    this.isEditable = editable; 
} 

@Override 
public Object getChild(int groupPosition, int childPosition) { 
    return mChecklist.getCategories().get(groupPosition).getChecks().get(childPosition); 
} 


@Override 
public long getChildId(int groupPosition, int childPosition) { 
    return childPosition; 
} 

// ChildView is the Check item with a label and buttons actions 
@Override 
public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, final ViewGroup parent) { 
    final CheckViewHolder holder; 

    final List<Category> mCategories = mChecklist.getCategories(); 
    final Category mCategory = (Category) getGroup(groupPosition); 
    final List<Check> mChecks = mCategory.getChecks(); 
    final Check mCheck = (Check) getChild(groupPosition, childPosition); 
    final List<Low> mLows = mCheck.getLows(); 


    if (convertView != null){ 
     holder = (CheckViewHolder) convertView.getTag(); 
    } 
    else { 
     LayoutInflater inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = inflater.inflate(R.layout.item_check, parent, false); 
     holder = new CheckViewHolder(convertView); 
     convertView.setTag(holder); 
    } 

    Utils.logK("Holder = "+holder); 

    // Prepare checking lows elements 
    addLowsToView(mLows, convertView, holder); 


    // Set Checks elements 
    String label = mCheck.getLabel(); 
    holder.tvCheckLabel.setText(label); 

    // Check the state of button 
    final View finalConvertView = convertView; 
    final ViewGroup finalParent = parent; 
    holder.rgActions.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(RadioGroup radioGroup, @IdRes int rbId) { 

      switch (rbId){ 
       case R.id.rb_ko: 
        holder.llLow.setVisibility(View.VISIBLE); 
        mCheck.setState(Check.KO); 

        //finalParent.scrollTo(0,finalConvertView.getTop()); 

        //((ExpandableListView) parent).smoothScrollToPosition(finalConvertView.getTop()); 
        //((ExpandableListView) parent).setSelection(0); 
        //Utils.logK("Scroll to top = "+finalConvertView.getTop()); 
        break; 
       case R.id.rb_nc: 
        holder.llLow.setVisibility(View.GONE); 
        mCheck.setState(Check.NC); 
        break; 
       case R.id.rb_ok: 
        holder.llLow.setVisibility(View.GONE); 
        mCheck.setState(Check.OK); 
        break; 
       default: 
        //TODO 
      } 

      // Prepere updated checklist object to send 
      mChecks.set(childPosition, mCheck); 
      mCategory.setChecks(mChecks); 
      mCategories.set(groupPosition, mCategory); 
      mChecklist.setCategories(mCategories); 

     } 
    }); 

    /** 
    * Save the state of radioButtons (selection) 
    */ 
    if(mCheck.getState() != null) { 
     switch (mCheck.getState()) { 
      case Check.KO: 
       holder.rbKo.setChecked(true); 
       holder.rbKo.setSelected(true); 
       break; 
      case Check.NC: 
       holder.rbNc.setChecked(true); 
       holder.rbNc.setSelected(true); 
       break; 
      case Check.OK: 
       holder.rbOk.setChecked(true); 
       holder.rbOk.setSelected(true); 
       break; 
     } 
    } 

    holder.cbOther.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

     int lowsSize = mLows.size(); 
     @Override 
     public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) { 
      if (isChecked){ 
       holder.etOther.setEnabled(true); 
      } 
      else{ 
       holder.etOther.setEnabled(false); 
      } 

      // Add the new low and updated checklist object to send 
      final Low mOtherLow = new Low(); 
      mOtherLow.setId(ID_LOW_ADDED); 
      mOtherLow.setSelected(true); 


      // TODO save checklist when text is added 
      holder.etOther.addTextChangedListener(new TextWatcher() { 
       @Override 
       public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

       } 

       @Override 
       public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) { 

       } 

       @Override 
       public void afterTextChanged(Editable editable) { 
        mOtherLow.setLabel(holder.etOther.getText().toString()); 

       } 
      }); 

      Utils.logK("otherLow added = "+mOtherLow.getLabel()); 

       //long idLastLowAdded = mLows.get(mLows.size()-1).getId(); 
       Utils.logK("Low added = "+mOtherLow.getLabel()); 
       mLows.add(mOtherLow); 
       mCheck.setLows(mLows); 
       mChecks.set(childPosition, mCheck); 
       mCategory.setChecks(mChecks); 
       mCategories.set(groupPosition, mCategory); 
       mChecklist.setCategories(mCategories); 


     } 


    }); 

    holder.setViewsEnabled(isEditable); 


    return convertView; 
} 

@Override 
public int getChildrenCount(int groupPosition) { 
    return mChecklist.getCategories().get(groupPosition).getChecks().size(); 
} 

@Override 
public Object getGroup(int groupPosition) { 
    return mChecklist.getCategories().get(groupPosition); 
} 


@Override 
public int getGroupCount() { 
    return mChecklist.getCategories().size(); 
} 

@Override 
public long getGroupId(int groupPosition) { 
    return groupPosition; 
} 


@Override 
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { 
    final CategoryViewHolder groupHolder; 
    final Category mCategory = (Category) getGroup(groupPosition); 


    if (convertView != null){ 
     groupHolder = (CategoryViewHolder) convertView.getTag(); 
    } 
    else { 
     LayoutInflater inflater = (LayoutInflater) this.mContext 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = inflater.inflate(R.layout.item_category, parent, false); 
     groupHolder = new CategoryViewHolder(convertView); 

     convertView.setTag(groupHolder); 
    } 

    groupHolder.tvCategoryTitle.setText(mCategory.getLabel()); 

    return convertView; 
} 


@Override 
public boolean hasStableIds() { 
    return false; 
} 

@Override 
public boolean isChildSelectable(int groupPosition, int childPosition) { 
    return true; 
} 


/** 
* Add the lines of works to my check item (checkboxes) 
* @param lows List of line of work 
* @param v The view will be attached this new view 
*/ 
private void addLowsToView(final List<Low> lows, View v, final CheckViewHolder holder) { 
    LinearLayout llLowPosition = v.findViewById(R.id.ll_low_position); 
    if(((LinearLayout) llLowPosition).getChildCount() > 0) 
     ((LinearLayout) llLowPosition).removeAllViews(); 

    for (int i = 0; i < lows.size(); i++) { 

     final int position = i; 
     final Low low = lows.get(i); 
     // Ignore the "others" lows (id of an other low start at -1 and decrement for each time the 
     // user click on "other" checkbox 
     if (low.getId()<0){ 
      if (isEditable){ 
       break; 
      } 
      else{ 
       holder.cbOther.setSelected(true); 
       holder.etOther.setText(low.getLabel()); 
      } 
     } 
     else { 

      CheckBox cbLow = new CheckBox(mContext); 
      cbLow.setText(lows.get(i).getLabel()); 
      cbLow.setChecked(lows.get(i).isSelected()); 
      //cbLow.setButtonDrawable(ContextCompat.getColor(mContext,R.color.accent)); 
      cbLow.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 
       @Override 
       public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) { 
        low.setSelected(isChecked); 
        lows.set(position, low); 
       } 
      }); 
      llLowPosition.addView(cbLow, 0, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); 
      // Disable if it's not editable mode 
      if (!isEditable){ 
       cbLow.setEnabled(false); 
      } 
     } 



    } 

} 

/** 
* Allow activity to get the updated checklist 
* @return The updated checklist 
*/ 
public Checklist getChecklist(){ 
    return mChecklist; 
} 


/** 
* Class that define the view holder of a child : the check model 
*/ 
static class CheckViewHolder{ 
    @BindView(R.id.tv_check_label) 
    TextView tvCheckLabel; 

    @BindView(R.id.rg_actions) 
    RadioGroup rgActions; 

    @BindView(R.id.ll_low) 
    LinearLayout llLow; 

    @BindView(R.id.ll_low_position) 
    LinearLayout llLowPosition; 

    @BindView(R.id.cb_other) 
    CheckBox cbOther; 

    @BindView(R.id.et_other) 
    EditText etOther; 

    @BindView(R.id.rb_ko) 
    RadioButton rbKo; 

    @BindView(R.id.rb_nc) 
    RadioButton rbNc; 

    @BindView(R.id.rb_ok) 
    RadioButton rbOk; 

    @BindView(R.id.cv_item_check) 
    CardView cvItemCheck; 


    public CheckViewHolder(View view){ 
     ButterKnife.bind(this, view); 
    } 

    /** 
    * Set actions on the view. If it's not editable, disable all actions. 
    * @param editable : Mode of view : consulting or editing 
    */ 
    public void setViewsEnabled(boolean editable){ 
     rgActions.setEnabled(editable); 
     llLowPosition.setEnabled(editable); 
     rbKo.setEnabled(editable); 
     rbNc.setEnabled(editable); 
     rbOk.setEnabled(editable); 
     cbOther.setEnabled(editable); 
     //etOther.setEnabled(editable); 
    } 
} 

/** 
* Class that define the view holder of a parent : the category model 
*/ 
static class CategoryViewHolder{ 
    @BindView(R.id.tv_category_title) 
    TextView tvCategoryTitle; 

    public CategoryViewHolder(View v){ 
     ButterKnife.bind(this, v); 
    } 

} 


} 
+0

請問您是否可以添加您的佈局/佈局 –

回答

0

在回收視圖,視圖被回收,因此,一些複選框已經選中(這是滾動的,現在前檢查回收)。這是正常行爲,您需要取消選中複選框的狀態並編輯文本。

0

在你的活動相同的大小作爲mChecklist申報的ArrayList具有

,如: - ArrayList的mChecklistBool =新的ArrayList();

for (int i = 0;i<Checklist.size();i++) 
    { 
     mChecklistBool.add(false); 
    } 


When you call adapter send this ArrayList of Boolean 

    new ChecklistAdapter (mContext,mChecklist,mChecklistBool,editable); 



     In Adapter class declare 

    ArrayList<Boolean> mChecklistBool; 

public ChecklistAdapter(Context mContext, Checklist mChecklist, ArrayList<Boolean> mChecklistBool,boolean editable) { 
this.mContext = mContext; 
this.mChecklist = mChecklist; 
this.isEditable = editable; 
this.mChecklistBool =mChecklistBool; 

}

然後在那裏你綁定觀點持有者視圖然後拿到檢查現在的位置之後,你可以設置或重置任何現在的位置。

new View.OnClickListener() { 
      public void onClick(View v) { 
      CheckBox cb = (CheckBox) v; 
      if (mChecklist.contains(v.getTag())) { 
       int ChkPos = mChecklist.indexOf(v.getTag()); 
       mChecklistBool.set(ChkPos, cb.isChecked()); 

      } 

    }