2016-03-07 101 views
2

我知道關於ListView回收問題,並嘗試保持我的狀態在模型中,但它似乎不工作。我已經閱讀了許多有同樣問題的主題,但他們的解決方案不適合我,或者我做錯了什麼。 當我在初始狀態下用無線電組上下滾動列表視圖時,沒有任何反應,沒錯。但只要我設置了任何一行中的任何單選按鈕,然後上下滾動單選按鈕就會隨機檢查。RadioGroup在ListView中沒有保持正確的狀態

RadioAdapter.java:

public class RadioAdapter extends ArrayAdapter<Question> { 

List<Question> mSource; 

static class ViewHolder { 
    TextView category = null; 
    TextView question = null; 
    RadioGroup rbGroup = null; 

    ViewHolder(View row) { 
     this.category = (TextView) row.findViewById(R.id.tvQuestionCategory); 
     this.question = (TextView) row.findViewById(R.id.tvQuestion); 
     this.rbGroup = (RadioGroup) row.findViewById(R.id.rgIteration); 
    } 
} 

private LayoutInflater mInflater; 

public RadioAdapter(Context context, List<Question> mSource) { 
    super(context, R.layout.item_question, mSource); 
    mInflater = LayoutInflater.from(context); 
    this.mSource = mSource; 
} 

public View getView(final int position, View convertView, ViewGroup parent) { 
    ViewHolder holder = null; 
    View row = convertView; 

    if (row == null) { 
     row = mInflater.inflate(R.layout.item_question, null); 

     holder = new ViewHolder(row); 

     holder.rbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 

      public void onCheckedChanged(RadioGroup group, int checkedId) { 
       //Get position of current group 
       Integer pos = (Integer) group.getTag(); 
       switch (checkedId) { 
        case R.id.rbIterationYes: 
         //Check 'YES' and uncheck 'NO' 
         mSource.get(pos).setYesChecked(true); 
         mSource.get(pos).setNoChecked(false); 
         break; 

        case R.id.rbIterationNo: 
         //Vice versa 
         mSource.get(pos).setNoChecked(true); 
         mSource.get(pos).setYesChecked(false); 
         break; 
       } 
      } 
     }); 

     row.setTag(holder); 
    } else { 
     holder = (ViewHolder) row.getTag(); 
    } 
    holder.rbGroup.setTag(new Integer(position)); 
    holder.category.setText(mSource.get(position).getCategory()); 
    holder.question.setText(mSource.get(position).getDescription()); 
    //If no one of buttons isn't checked 
    if (!mSource.get(position).isYesChecked() && !mSource.get(position).isNoChecked()) { 
     holder.rbGroup.clearCheck(); 
    }else { 
     //We are supposing 'YES' is checked 
     int c = 0; 
     //Or 'NO' is checked 
     if (mSource.get(position).isNoChecked()){ 
      c = 1; 
     } 
     //Set checked button 
     ((RadioButton)holder.rbGroup.getChildAt(c)).setChecked(true); 
    } 
    return row; 
} 

}

Question.java:

public class Question { 

    private Integer id; 
    private String category; 
    private String description; 
    private boolean yesChecked; 
    private boolean noChecked; 

/* Getters and setters */ 
} 

item_question.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:orientation="vertical" android:layout_width="match_parent" 
android:layout_height="match_parent"> 

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="18dp" 
    android:id="@+id/tvQuestionCategory"/> 
<TextView 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:textSize="18dp" 
    android:id="@+id/tvQuestion"/> 

<RadioGroup 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/rgIteration"> 
     <RadioButton 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:checked="false" 
      android:id="@+id/rbIterationYes" 
      android:text="@string/rbIterationYes" 
      android:textSize="16dp"/> 
     <RadioButton 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:checked="false" 
      android:id="@+id/rbIterationNo" 
      android:text="@string/rbIterationNo" 
      android:textSize="16dp" /> 
</RadioGroup> 

</LinearLayout> 

我希望你能幫助我發現錯誤,因爲我完全厭倦尋求解決方案。謝謝

+0

調試代碼,並檢查整數POS =(整數)group.getTag你獲得正確的位置();和holder.rbGroup.setTag(new Integer(position));在這些代碼行上。 – androidnoobdev

+0

調試顯示正確的位置,但當我上下滾動有時工作公共無效onCheckedChanged(RadioGroup組,int checkedId) – viRUS

+0

我已經解決了這個問題與複選框檢查出來希望它也能與收音機組一起工作。 http://www.androprogrammer.com/2013/10/list-view-with-check-box-using-custom.html – androidnoobdev

回答

0

你可以這樣做重寫getItemId方法並返回你的問題ID,這樣你就可以識別每個問題並用ID回答。

public class RadioAdapter extends ArrayAdapter<Question> { 

    List<Question> mSource; 

    static class ViewHolder { 
     TextView category = null; 
     TextView question = null; 
     RadioGroup rbGroup = null; 

     ViewHolder(View row) { 
      this.category = (TextView) row.findViewById(R.id.tvQuestionCategory); 
      this.question = (TextView) row.findViewById(R.id.tvQuestion); 
      this.rbGroup = (RadioGroup) row.findViewById(R.id.rgIteration); 
     } 
    } 

    private LayoutInflater mInflater; 

    public RadioAdapter(Context context, List<Question> mSource) { 
     super(context, R.layout.item_question, mSource); 
     mInflater = LayoutInflater.from(context); 
     this.mSource = mSource; 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 
     ViewHolder holder = null; 
     View row = convertView; 

     if (row == null) { 
      row = mInflater.inflate(R.layout.item_question, null); 

      holder = new ViewHolder(row); 

      holder.rbGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { 

       public void onCheckedChanged(RadioGroup group, int checkedId) { 
        //Get position of current group 
        //Integer pos = (Integer) group.getTag(); 
        switch (checkedId) { 
         case R.id.rbIterationYes: 
          //Check 'YES' and uncheck 'NO' 
          mSource.get((int) getItemId(position)).setYesChecked(true); 
          mSource.get((int) getItemId(position)).setNoChecked(false); 
          break; 

         case R.id.rbIterationNo: 
          //Vice versa 
          mSource.get((int) getItemId(position)).setNoChecked(true); 
          mSource.get((int) getItemId(position)).setYesChecked(false); 
          break; 
        } 
       } 
      }); 

      row.setTag(holder); 
     } else { 
      holder = (ViewHolder) row.getTag(); 
     } 
     holder.rbGroup.setTag(new Integer(position)); 
     holder.category.setText(mSource.get(position).getCategory()); 
     holder.question.setText(mSource.get(position).getDescription()); 
     //If no one of buttons isn't checked 
     if (!mSource.get((int) getItemId(position)).isYesChecked() && !mSource.get((int) getItemId(position)).isNoChecked()) { 
      holder.rbGroup.clearCheck(); 
     } else { 
      //We are supposing 'YES' is checked 
      int c = 0; 
      //Or 'NO' is checked 
      if (mSource.get((int) getItemId(position)).isNoChecked()) { 
       c = 1; 
      } 
      //Set checked button 
      ((RadioButton) holder.rbGroup.getChildAt(c)).setChecked(true); 
     } 
     return row; 
    } 

    @Override 
    public long getItemId(int position) { 
     return mSource.get(position).getId(); 
    } 
} 
1

要設置選中或取消選中您RadioGroup之前,您應該禁用監聽器,像這樣。希望這可以幫助。 適配器改成這樣

public class RadioAdapter extends ArrayAdapter<Question> { 

    List<Question> mSource; 
    RadioGroup.OnCheckedChangeListener listener; 
    static class ViewHolder { 
     TextView category = null; 
     TextView question = null; 
     RadioGroup rbGroup = null; 

     ViewHolder(View row) { 
      this.category = (TextView) row.findViewById(R.id.tvQuestionCategory); 
      this.question = (TextView) row.findViewById(R.id.tvQuestion); 
      this.rbGroup = (RadioGroup) row.findViewById(R.id.rgIteration); 
     } 
    } 

    private LayoutInflater mInflater; 

    public RadioAdapter(Context context, List<Question> mSource) { 
     super(context, R.layout.item_question, mSource); 
     mInflater = LayoutInflater.from(context); 
     this.mSource = mSource; 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 
     ViewHolder holder = null; 
     View row = convertView; 

     if (row == null) { 
      row = mInflater.inflate(R.layout.item_question, null); 

      holder = new ViewHolder(row); 
      listener = new RadioGroup.OnCheckedChangeListener() { 

       public void onCheckedChanged(RadioGroup group, int checkedId) { 

        //Get position of current group 
        Integer pos = (Integer) group.getTag(); 
        switch (checkedId) { 
         case R.id.rbIterationYes: 
          //Check 'YES' and uncheck 'NO' 
          mSource.get(pos).setYesChecked(true); 
          mSource.get(pos).setNoChecked(false); 
          break; 

         case R.id.rbIterationNo: 
          //Vice versa 
          mSource.get(pos).setNoChecked(true); 
          mSource.get(pos).setYesChecked(false); 
          break; 
        } 
       } 
      }; 
      holder.rbGroup.setOnCheckedChangeListener(listener); 

      row.setTag(holder); 
     } else { 
      holder = (ViewHolder) row.getTag(); 
     } 
     holder.rbGroup.setTag(new Integer(position)); 
     holder.category.setText(mSource.get(position).getCategory()); 
     holder.question.setText(mSource.get(position).getDescription()); 
     //If no one of buttons isn't checked 
     holder.rbGroup.setOnCheckedChangeListener(null); 
     if (!mSource.get(position).isYesChecked() && !mSource.get(position).isNoChecked()) { 
      holder.rbGroup.clearCheck(); 
     }else { 
      //We are supposing 'YES' is checked 
      int c = 0; 
      //Or 'NO' is checked 
      if (mSource.get(position).isNoChecked()){ 
       c = 1; 
      } 
      //Set checked button 

      ((RadioButton)holder.rbGroup.getChildAt(c)).setChecked(true); 

     } 
     holder.rbGroup.setOnCheckedChangeListener(listener); 
     return row; 
    } 

}