2014-05-25 4 views
2

체크 박스의 상태가 변경되면 내 애플리케이션을 데이터베이스로 업데이트 할 수 있지만 애플리케이션을 스크롤하면 체크 박스의 상태가 변경됩니다.안드로이드 ListView보기가 스크롤 될 때 체크 박스가 사라짐

내 질문은 :보기를 스크롤 할 때 변경되지 않도록 확인란의 상태를 저장하려면 어떻게해야합니까?

여기 내 커서 어댑터입니다.

public CustomCursorAdapter(Context context, Cursor c, int flags) { 
    super(context, c, flags); 
    mInflater = (LayoutInflater) 
      context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

@Override 
public View newView(Context context, Cursor cursor, ViewGroup parent) { 
    View view = mInflater.inflate(R.layout.wildlifelist, parent, false); 
    ViewHolder holder = new ViewHolder(); 

    holder.img = (ImageView) view.findViewById(R.id.img); 
    holder.mname = (TextView) view.findViewById(R.id.maori); 
    holder.name = (TextView) view.findViewById(R.id.name);  
    holder.status = (TextView) view.findViewById(R.id.status); 
    holder.check = (CheckBox) view.findViewById(R.id.check); 

    view.setTag(holder);  
    return view;  
} 

@Override 
public void bindView(View view, Context context, Cursor cursor) { 
    ViewHolder holder = (ViewHolder) view.getTag(); 

    final long rowId = cursor.getLong(cursor.getColumnIndex(DBhelper.KEY_ID)); 

    byte[] img = cursor.getBlob(cursor.getColumnIndex(DBhelper.KEY_IMG)); 
    holder.img.setImageBitmap(BitmapFactory.decodeByteArray(img, 0, img.length)); 

    holder.mname.setText(cursor.getString(cursor.getColumnIndex(DBhelper.KEY_MNAME))); 
    holder.name.setText(cursor.getString(cursor.getColumnIndex(DBhelper.KEY_NAME))); 
    holder.status.setText(cursor.getString(cursor.getColumnIndex(DBhelper.KEY_STATUS))); 

    holder.check.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      if (isChecked) {   
       Log.w("Debug","RowID: " + rowId + ", isChecked: " + isChecked); 
       DBhelper.updateRow(rowId, 1); 
      } 
      else { 
       Log.w("Debug","RowID: " + rowId + ", isChecked: " + isChecked); 
       DBhelper.updateRow(rowId, 0); 
      } 
     } 
    }); 
} 

public static class ViewHolder { 
    ImageView img; 
    TextView mname; 
    TextView name; 
    TextView status; 
    CheckBox check; 
} 

답변

0

보기에서 각 항목의 확인 상태를 바인드하려면 array 또는 map을 사용하십시오. 이 코드는 다소 비슷하게 보일 것입니다.

CustomCursorAdapter extends CursorAdapter{ 

    Map<Long, Boolean> checkState = new HashMap<>(); 

    public CustomCursorAdapter(Context context, Cursor c, int flags) { 
     super(context, c, flags); 
     mInflater = (LayoutInflater) 
       context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     ViewHolder holder = (ViewHolder) view.getTag(); 

     ///set other views 

     holder.check.setOnCheckedChangeListener(null); //unregister the check listener 

     //I like to assume all views are unchecked by default 
     Boolean checked = checkState.get(rowId); 
     checked = (checked == null ? false : checked); 

     holder.check.setChecked(checked); 

     holder.check.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
      @Override 
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
       //save the check state 
       checkState.put(rowId, isChecked); 

       if (isChecked) {   
        Log.w("Debug","RowID: " + rowId + ", isChecked: " + isChecked); 
        DBhelper.updateRow(rowId, 1); 
       } 
       else { 
        Log.w("Debug","RowID: " + rowId + ", isChecked: " + isChecked); 
        DBhelper.updateRow(rowId, 0); 
       } 
      } 
     }); 
    } 
} 
+0

나는 당신이 제안한 것을 시도했지만 여전히 상태가 상실된 확인란의 문제점이 있습니다. onCheckedChanged 메소드에서 with-final 변수이기 때문에 커서를 참조 할 수 없기 때문에'Cursor cursor'를'final Cursor cursor'로 변경해야했습니다. 이것이이 문제의 원인이 될 수 있습니까? – FusionFox

+0

@FusionFox 오류를 확인할 수 있도록 전체 코드를 공유 할 것을 권합니다. 크기가 너무 큰 경우 pastebin 또는 sth를 사용하십시오 – Olayinka

+0

@FusionFox 두 번째 생각에 커서가 어댑터에 연결될 때 완전히로드되지 않으면 원인이 * 될 수 있습니다. 이 경우 Map 이 더 좋습니다. 그래서 각 행 ID에 대한 체크 상태를 추적 할 수 있습니다 – Olayinka

0

ListView는 스크롤 할 때 행을 다시 사용합니다. BindView() 메서드는 행을 전달합니다 (재사용 될 가능성이 있음). 그러면 커서 객체의 속성에 따라 행을 설정할 수 있습니다. BindView()에서 holder.check를 설정하는 것처럼 보이지는 않습니다. ListView가 스크롤 될 때 잘못된 이유 일 수 있습니다.

관련 문제