1

У меня есть список, содержащий в каждой строке текстовое поле с флажком, поэтому, когда флажок установлен и мы прокручиваем вниз по списку, экземпляр флажка будет взят из места в другое (повторно ..) и у меня есть несколько флажков проверили, как исправить, что я пытался связать флажок в ListView, но которые не работали мой код:Как связать флажок с списком

SimpleCursorAdapter adapter =new SimpleCursorAdapter(this,R.layout.rating,cu,new String[]{"Title","Favorites"}, new int[]{R.id.text1,R.id.bt_rating},CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); 
     listv.setAdapter(adapter); 

     adapter.setViewBinder(new SimpleCursorAdapter.ViewBinder(){ 
       /** Binds the Cursor column defined by the specified index to the specified view */ 
       public boolean setViewValue(View view, Cursor cursor, int columnIndex){ 
        if(view.getId() == R.id.bt_rating){ 

         ((CheckBox)view).setChecked(Boolean.valueOf(cursor.getString(cursor.getColumnIndex("Favorites")))); 
         ((CheckBox)view).setOnCheckedChangeListener(myCheckChangList); 
         return true; //true because the data was bound to the view 
        } 
        return false; 
       } 
      }); 


OnCheckedChangeListener myCheckChangList = new OnCheckedChangeListener() { 
      public void onCheckedChanged(CompoundButton buttonView, 
        boolean isChecked) { 
       buttonView.setChecked(isChecked); 
      } 
     }; 

Мой XML код содержания строки мой список наблюдения:

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

    <CheckBox 
android:id="@+id/bt_rating" 
android:focusable="false" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:layout_gravity="center_vertical" 
android:button="@android:drawable/btn_star"/> 

<TextView 

android:id="@+id/text1" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 
android:textSize="@dimen/fsinlistview" 

/> 
</LinearLayout> 
+1

http://www.vogella.com/tutorials/AndroidListView/article.html#listviewselection –

+0

не нашел то, что мне там там печально ... продолжит мой поиск .. спасибо в любом случае .. –

ответ

0

Похоже, ваш OnCheckedChangedListener проблема здесь. Если вы посмотрите на свой код, посмотрите, что каждый checkbox получает ссылку на тот же слушатель. Поэтому, когда вы проверяете один флажок, вы также устанавливаете каждый другой флажок, а также вы не обновляете данные резервного копирования.

Ваш OnCheckedChangedListener не должен обновлять состояние представления флажка - обратный вызов запускается, поскольку состояние уже изменено.

Так что вам нужно сделать следующие шаги, когда пользователь проверяет флажок:

  1. Выяснить, который был проверен элемент, и как это соответствует вашим данным
  2. Обновите свою информацию в соответствии с новым проверено/бесконтрольно состояние
  3. Уведомить адаптер об изменении данных/обновить курсор

Вы могли бы это сделать что-то вроде следующего, помечать вид с идентификатором строки его повторно представляет:

public boolean setViewValue(View view, Cursor cursor, int columnIndex){ 
    if(view.getId() == R.id.bt_rating){ 
     view.setTag(cursor.getInt(cursor.getColumnIndex(SomeDBContract.ID))); 
     ((CheckBox)view).setChecked(Boolean.valueOf(cursor.getString(cursor.getColumnIndex("Favorites")))); 
     ((CheckBox)view).setOnCheckedChangeListener(myCheckChangList); 
     return true; //true because the data was bound to the view 
    } 
    return false; 
} 

Затем в прослушивателе вы можете обновить базу данных в соответствии с этим ID:

CheckedChangeListener myCheckChangList = new OnCheckedChangeListener() { 
     public void onCheckedChanged(CompoundButton buttonView, 
       boolean isChecked) { 
      int rowId = (int) buttonView.getTag(); 
      // Handle updating the database as per normal 
      updateSomeDbRowAsChecked(rowId, isChecked); 
     } 
    }; 

Наконец, вам нужно обновить адаптер курсора с новым курсором один раз в строке базы данных обновлено:

myAdapter.swapCursor(newCursor); 

вы должны настроить все это в соответствии с вашим кодом, но это должно дать вам представление о том, так вы можете подойти к этой проблеме.

+0

ok исправит это, но и мой видоискатель не вызван, потому что я поместил log.d внутри него, и он не вызывается .. –

+0

также содержимое слушателя было просто добавлено напрямую, чтобы проверить результат, что мне нужно сделать заключается в добавлении изменений в мою базу данных; но почему видоискатель не вызван? –

+0

Я не уверен в этом, извините - код для настройки вставки выглядит корректно. –

0

В любом представлении Listview вид повторно используется. Когда вы просматриваете список, те, которые просматривают экран и выходят за рамки, перерабатываются и используются с более новой информацией, как показано ниже.

Вам нужно отслеживать свои флажки с разреженным массивом. Отметьте индекс в массиве, как чернокнижник/непроверенный, когда пользователь касается каждого. Затем вы устанавливаете состояние флажка на основе значения в массиве.

Вот пример кода из старого приложения, которое выполняет как флажок «выбрать все», так и управляет полным списком отмеченных и непроверенных. Это было для приложения для занятий в классе, которое я написал, поэтому учителю было намного легче выбрать «ВСЕ», находясь в классе, а затем отменить выбор тех, которые отсутствовали.

У меня есть два флажка в этом списке и два разреженных массива, itemCheckedHere и itemCheckedLate (есть ли ученик в классе или был поздним).

public class MyDataAdapter extends SimpleCursorAdapter { 
    private Cursor c; 
    private Context context; 
    private Long classnum; 
    private gradeBookDbAdapter mDbHelper; 

    public static final int LATE=2; 
    public static final int ATTEND=1; 
    int idxCol; 
    int idx; 

    // itemChecked will store the position of the checked items. 

    public MyDataAdapter(Context context, int layout, Cursor c, String[] from, 
      int[] to, Long mRowId) { 
     super(context, layout, c, from, to); 
     this.c = c; 
     this.context = context; 
     mDbHelper = new gradeBookDbAdapter(context); 
     mDbHelper.open(); 
     classnum = mRowId; 
     c.moveToFirst(); 



    } 
    public class ViewHolder{ 
     public TextView text; 
     public TextView text2; 
     public ImageView image; 
     public CheckBox here; 
     public CheckBox late; 
    } 


    public View getView(final int pos, View inView, ViewGroup parent) { 
     Bitmap bm; 
     ImageView studentPhoto; 
     View vi=inView; 
     final ViewHolder holder; 

     if (inView == null) { 
      LayoutInflater inflater = (LayoutInflater) context 
        .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      vi = inflater.inflate(R.layout.show_attendance, null); 

      holder=new ViewHolder(); 
      holder.text=(TextView)vi.findViewById(R.id.stuname); 
      holder.text2=(TextView)vi.findViewById(R.id.stuIndex); 
      holder.image=(ImageView)vi.findViewById(R.id.icon); 
      holder.here=(CheckBox)vi.findViewById(R.id.attend); 
      holder.late=(CheckBox)vi.findViewById(R.id.late); 
      vi.setTag(holder); 

     } 
     else 
      holder=(ViewHolder)vi.getTag(); 


     c.moveToPosition(pos); 
     int index = c.getColumnIndex(gradeBookDbAdapter.KEY_NAME); 
     String name = c.getString(index); 
     holder.text.setText(name); 
     index = c.getColumnIndex(gradeBookDbAdapter.KEY_ROWID); 
     String Index = c.getString(index); 
     holder.text2.setText(Index); 

     bm = gradeBookDbAdapter.getStudentPhoto(name); 
     if (bm != null) { 
      holder.image.setImageBitmap(bm); 
     }   
     else { 
      // use icon image 
      holder.image.setImageResource(R.drawable.person_icon); 
     } 


     // pull out existing attend/late fields and set accordingly 
     int attend = c.getInt(c.getColumnIndex(gradeBookDbAdapter.KEY_ATTEND)); 
     if(attend==1){ 
      holder.here.setChecked(true); 
      itemCheckedHere.set(pos, true); 
     } 
     //else { 
     // holder.here.setChecked(false); 
     // itemCheckedHere.set(pos, false); 
     //} 

     int late = c.getInt(c.getColumnIndex(gradeBookDbAdapter.KEY_LATE)); 
     if (late==1){ 
      holder.late.setChecked(true); 
      itemCheckedLate.set(pos, true); 
     } 
     //else { 
     // holder.late.setChecked(false); 
     // itemCheckedLate.set(pos, false); 
     //} 


     if (selectAllTouched) { 
      if(selectAll){ 
       holder.here.setChecked(true); 
       itemCheckedHere.set(pos, true); 
       int who= new Integer(holder.text2.getText().toString()); 
       mDbHelper.updateAttend(who, classnum, ATTEND, 1, attendDate); 
      } 
      else{ 
       holder.here.setChecked(false); 
       itemCheckedHere.set(pos, false); 
       int who = new Integer(holder.text2.getText().toString()); 
       mDbHelper.updateAttend(who, classnum, ATTEND, 0, attendDate); 
      } 
     } 


     holder.here.setOnClickListener(new OnClickListener() { 

      public void onClick(View v) { 

       CheckBox cb = (CheckBox) v.findViewById(R.id.attend); 

       if (cb.isChecked()) { 
        itemCheckedHere.set(pos, true); 
        int Index = new Integer(holder.text2.getText().toString()); 
        mDbHelper.updateAttend(Index, classnum, ATTEND, 1, attendDate); 
       } else if (!cb.isChecked()) { 
        itemCheckedHere.set(pos, false); 
        int Index = new Integer(holder.text2.getText().toString()); 
        mDbHelper.updateAttend(Index, classnum, ATTEND, 0, attendDate); 
       } 
      } 
     }); 
     holder.late.setOnClickListener(new OnClickListener() { 

      public void onClick(View v) { 
       CheckBox cb = (CheckBox) v.findViewById(R.id.late); 

       if (cb.isChecked()) { 
        itemCheckedLate.set(pos, true); 
        int Index = new Integer(holder.text2.getText().toString()); 
        mDbHelper.updateAttend(Index, classnum, LATE, 1, attendDate); 
       } else if (!cb.isChecked()) { 
        itemCheckedLate.set(pos, false); 
        int Index = new Integer(holder.text2.getText().toString()); 
        mDbHelper.updateAttend(Index, classnum, LATE, 0, attendDate); 
       } 
      } 
     }); 


     holder.here.setChecked(itemCheckedHere.get(pos)); // this will Check or Uncheck the 
     holder.late.setChecked(itemCheckedLate.get(pos)); // this will Check or Uncheck the 
     // CheckBox in ListView 
     // according to their original 
     // position and CheckBox never 
     // loss his State when you 
     // Scroll the List Items. 

     return vi; 
    } 

} 

}

+0

большое спасибо martin, но этот код отличается от моего, будет видно, если у меня кончились решения :) –

+0

да, он отличается от вашего. Мое намерение заключалось в том, чтобы не писать код для вас, а скорее приводить пример того, как обращаться с флажками в списке. Если вы ищете код plug-n-play, который вы можете просто добавить в свой проект, мне нужно сначала предоставить вам мою учетную запись PayPal, в которую вы можете заплатить мне деньги за свои усилия. – Martin

Смежные вопросы