2013-10-07 2 views
0

Я использую ListView с каждым пункте а CheckableLinearLayout, как определено вСохранить флажок состояния из ListView в ArrayList

CheckableLinearLayout

я не могу проверить любую строку в ListView, она даже не зарегистрировать проверьте пользовательский интерфейс. Я не считаю, что есть android:checkMark для CheckableLinearLayout. Правильно ли гнездо CheckedTextView внутри моего CheckableLinearLayout, было бы лучше, если бы я использовал CheckBox. Кроме того, как я могу поместить их в ArrayList, как только они будут проверены, вместо того, чтобы перебирать их таким образом.

Это мой макет:

<com.example.deltest.CheckableLinearLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
> 
<CheckedTextView 
android:id="@android:id/text1" 
android:layout_width="wrap_content" 
android:layout_height="wrap_content" 
android:gravity="center_vertical" 
android:checkMark="?android:attr/listChoiceIndicatorMultiple" 
/> 
<TextView android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/txt_a" 
      /> 
<TextView android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:id="@+id/txt_b" 
    /> 

    </com.example.deltest.CheckableLinearLayout> 

Я реализовал listActivity следующим образом:

public class DeleteList extends ListActivity 
    { 
    ArrayList<Integer> idList=new ArrayList<Integer>(); 
    Cursor c; 
    Handler handler; 
    static final int WHAT=0; 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
    super.onCreate(savedInstanceState); 
    final TumblrDB db=new TumblrDB(this); 
    c=db.query(); 
    startManagingCursor(c); 
    handler=new Handler(); 
    View v=getLayoutInflater().inflate(R.layout.layout_header, null,false); 
    getListView().addHeaderView(v); 
    getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 
    SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.layout_del,c,new String[] {TumblrDB.DATE,TumblrDB.DESC},new int[]{R.id.txt_a,R.id.txt_b}); 
    getListView().setAdapter(adapter); 
    if(handler.hasMessages(WHAT)) 
    { 
     c=db.query(); 
     ((SimpleCursorAdapter)getListView().getAdapter()).swapCursor(c); 
    } 

    Button btn_del=(Button)v.findViewById(R.id.btn_del); 
    btn_del.setOnClickListener(new OnClickListener(){ 

     @Override 
     public void onClick(View view) { 
      // TODO Auto-generated method stub 
      int count=getListView().getCount(); 
      SparseBooleanArray sparseBooleanArray=getListView().getCheckedItemPositions(); 
      for(int i=0;i<count;i++) 
      { 
       if(sparseBooleanArray.get(i)) 
       { 
        c.moveToPosition(i); 
        int _id=c.getInt(c.getColumnIndex(TumblrDB._ID)); 
        Log.d("DeleteList", "The id has been added "+_id); 
        idList.add(_id); 
        new Thread() 
        { 
         public void run() 
         { 
          for(int i:idList) 
          { 
           db.delete(i); 
           Log.d("DeleteList", "The id has been deleted "+i); 
           handler.sendEmptyMessage(WHAT); 
          } 
         } 
        }.start(); 
       } 
      } 
     } 

    }); 

} 

} 

EDIT Попытка другой подход к решению этой проблемы путем расширения SimpleCursorAdapter:

if(row==null) 
    { 
     row=inflater.inflate(layout, null, false); 
     holder=new ViewHolder(row,position); 
     row.setTag(holder); 
     holder.check_del.setTag(position); 
    } 
    else 
    { 
     holder=(ViewHolder)row.getTag(); 
     holder.check_del.setOnClickListener(null); 
     holder.check_del.setTag(position); 
     if(hitList.get(position)) 
      holder.check_del.setChecked(true); 
     else 
      holder.check_del.setChecked(false); 
    } 

Тогда у меня есть implem подарил в OnClickListener для CheckBox:

 OnClickListener cbl=new OnClickListener(){ 

     @Override 
     public void onClick(View view) { 
      // TODO Auto-generated method stub 
      int position=(Integer)view.getTag(); 
      Log.d("CustomCursorAdapter", "The checkbox at postion "+position+" has been clicked"); 
      if(((CheckBox)view).isChecked()) 
      { 
       hitList.set(position, true); 
      } 
      else 
      { 
       hitList.set(position, false); 
      } 
     } 
    }; 

Теперь, когда я пытаюсь получить доступ к ArrayList, который я использую, он бросает ArrayOutOfBoundsException:

btn_del.setOnClickListener(new OnClickListener(){ 
     @Override 
     public void onClick(View view) { 
      // TODO Auto-generated method stub 
      new Thread() 
      { 
       public void run() 
       { 
        int count=lv.getCount(); 
        for(int i=0;i<count;i++) 
        { 
         if(adapter.hitList.get(i)) 
         { 
          db.delete(c.getInt(c.getColumnIndex(TumblrDB._ID))); 
         } 
        } 
       } 
      }.start(); 
      adapter.notifyDataSetChanged(); 
     } 
    }); 
+0

Я понятия не имею, что такое 'CheckableLinearLayout', но если вы пытаетесь выбрать несколько элементов из списка, вы можете выполнить его с помощью' CheckBox'. Вы можете написать пользовательский адаптер для «ListView» и в его методе 'getView' присоединить' onCheckedChangedListener' к элементу 'CheckBox' и добавить/удалить этот элемент из' ArrayList' выбранных элементов в зависимости от проверенного состояния пункт. – Mehedi

+0

При этом переопределяя методы newView и bindView, если флажок установлен, другие флажки автоматически проверяются, если я использую checkBox = null и/или checkBox.setChecked (false), чтобы смягчить это, я обнаружил, что checkbox ранее проверяется, не проверяется, когда представление переработано.Можете ли вы показать мне какой-то код/​​объяснить, как я могу предотвратить эти побочные эффекты при расширении SimpleCursorAdapter – vamsiampolu

+0

Нужно ли добавлять к этому элементу ListView.OnClickListener, чтобы сделать эти элементы доступными. – vamsiampolu

ответ

1

Использование ArrayList для хранения состояния всех флажков в списке.

public static ArrayList<Boolean> hitList; 

Я инициализируюсь и установить все значения ложь:

hitList=new ArrayList<Boolean>(); 
    for(int i=0;i<this.getCount();i++) 
    { 
     hitList.add(i, false); 
    } 

Когда инициализацию флажка для View, он выглядит в массиве по положению и проверяет его, только если значение в ArrayList true. Позиция удерживается CheckBox с использованием метода setTag и извлекается в Listener для определения положения флажка, который был проверен.

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

    if(row==null) 
    { 
     row=inflater.inflate(layout, null, false); 
     holder=new ViewHolder(row); 
     row.setTag(holder); 
     holder.check_del.setTag(position); 
    } 
    else 
    { 
     holder=(ViewHolder)row.getTag(); 
     holder.check_del.setOnClickListener(null); 
     holder.check_del.setTag(position); 
     if(hitList.get(position)) 
      holder.check_del.setChecked(true); 
     else 
      holder.check_del.setChecked(false); 
    } 
    c.moveToPosition(position); 
    holder.txt_a.setText(c.getString(c.getColumnIndex(ItemDB.TITLE))); 
    holder.txt_b.setText(c.getString(c.getColumnIndex(ItemDB.DESCRIPTION))); 

    OnClickListener cbl=new OnClickListener(){ 

     @Override 
     public void onClick(View view) { 
      // TODO Auto-generated method stub 
      int position=(Integer)view.getTag(); 
      Log.d("CustomCursorAdapter", "The checkbox at postion "+position+" has been clicked"); 
      if(((CheckBox)view).isChecked()) 
      { 
       hitList.set(position, true); 
      } 
      else 
      { 
       hitList.set(position, false); 
      } 
     } 
    }; 

    holder.check_del.setOnClickListener(cbl); 
    return row; 
} 

static class ViewHolder 
{ 
    TextView txt_a; 
    TextView txt_b; 
    CheckBox check_del; 
    ViewHolder(View row) 
    { 
     txt_a=(TextView)row.findViewById(R.id.txt_a); 
     txt_b=(TextView)row.findViewById(R.id.txt_b); 
     check_del=(CheckBox)row.findViewById(R.id.check_del); 
    } 
} 

В настоящее время у меня есть заголовок в ListView, который имеет следующую onClickListener:

@SuppressWarnings("deprecation") 
     @Override 
     public void onClick(View view) { 
      // TODO Auto-generated method stub 
      ArrayList<Boolean> killList=CustomCursorAdapter.hitList; 
      int totalDeleted=0; 
      for(int i=0;i<killList.size();i++) 
      { 
       //Log.d(TAG,i+":"+killList.get(i)); 
       c.moveToPosition(i); 
       String title=c.getString(c.getColumnIndex(ItemDB.TITLE)); 
       int _id=c.getInt(c.getColumnIndex(ItemDB._ID)); 
       //Log.d(TAG, "Item has title "+title+" and id "+_id); 
       int rowsAffected=0; 
       if(killList.get(i)) 
       { 
        rowsAffected=db.delete(_id); 
        //Log.d(TAG, "Deleted row with id "+_id); 
        killList.set(i, false); 

       } 
       totalDeleted+=rowsAffected; 

      } 
      //Log.d(TAG, "The total number of rows deleted "+totalDeleted); 
      //if(c.requery()) 
      //{ 
       //Log.d(TAG, "Requerying data,this calls notifyDataSetChanged"); 
      //} 

     }}); 

После того, как вы удалили данные из строки, перед вызовом перезапроса на Cursor (который является устаревшим ... нужно найти лучшую альтернативу), значения в ArrayList должны быть сброшены.

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