2012-06-06 32 views
11

Tôi có một ListView với CheckBox trên đó. và tôi đang sử dụng Custom Adapter để điền ListView.Cách nhận các mục danh sách được chọn từ một Listview với checkBox và Custom Adaptor?

Trong tệp xml tôi có một Button ở dưới cùng. những gì tôi muốn là cho phép người dùng chọn số hàng trong ListView và khi anh/cô ấy nhấp vào Button lấy vị trí của các mục đã chọn để tôi có thể lấy đối tượng cho hàng cụ thể để tính toán thêm.

+0

http://stackoverflow.com/questions/10895763/checkbox-unchecked-when-i-scroll-listview-in-android/10896140#comment14205583_10896140 –

Trả lời

10

Dưới đây Đoạn trích thực hiện chính xác những gì bạn muốn.

package com.windrealm.android; 

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.List; 

import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.view.ViewGroup; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.Button; 
import android.widget.CheckBox; 
import android.widget.ListView; 
import android.widget.TextView; 
import android.widget.Toast; 

public class PlanetsActivity extends Activity 
{ 

    private ListView mainListView; 
    private Planet[] planets; 
    private ArrayAdapter<Planet> listAdapter; 
    private Button check; 
    private Context context; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     context = PlanetsActivity.this; 
     check = (Button) findViewById(R.id.check); 
     // Find the ListView resource. 
     mainListView = (ListView) findViewById(R.id.mainListView); 

     // When item is tapped, toggle checked properties of CheckBox and 
     // Planet. 
     mainListView 
       .setOnItemClickListener(new AdapterView.OnItemClickListener() 
       { 
        @Override 
        public void onItemClick(AdapterView<?> parent, View item, 
          int position, long id) 
        { 
         Planet planet = listAdapter.getItem(position); 
         planet.toggleChecked(); 
         PlanetViewHolder viewHolder = (PlanetViewHolder) item 
           .getTag(); 
         viewHolder.getCheckBox().setChecked(planet.isChecked()); 
        } 
       }); 

     // Create and populate planets. 
     planets = (Planet[]) getLastNonConfigurationInstance(); 
     if (planets == null) 
     { 
      planets = new Planet[] 
      { new Planet("Mercury"), new Planet("Venus"), new Planet("Earth"), 
        new Planet("Mars"), new Planet("Jupiter"), 
        new Planet("Saturn"), new Planet("Uranus"), 
        new Planet("Neptune"), new Planet("Ceres"), 
        new Planet("Pluto"), new Planet("Haumea"), 
        new Planet("Makemake"), new Planet("Eris") }; 
     } 
     ArrayList<Planet> planetList = new ArrayList<Planet>(); 
     planetList.addAll(Arrays.asList(planets)); 

     // Set our custom array adapter as the ListView's adapter. 
     listAdapter = new PlanetArrayAdapter(this, planetList); 
     mainListView.setAdapter(listAdapter); 

     check.setOnClickListener(new OnClickListener() 
     { 

      @Override 
      public void onClick(View view) 
      { 
       for (int i = 0; i < listAdapter.getCount(); i++) 
       { 
        Planet planet = listAdapter.getItem(i); 
        if (planet.isChecked()) 
        { 
         Toast.makeText(context, 
           planet.getName() + " is Checked!!", 
           Toast.LENGTH_SHORT).show(); 
        } 
       } 

      } 
     }); 
    } 

    /** Holds planet data. */ 
    private static class Planet 
    { 
     private String name = ""; 
     private boolean checked = false; 

     public Planet() 
     { 
     } 

     public Planet(String name) 
     { 
      this.name = name; 
     } 

     public Planet(String name, boolean checked) 
     { 
      this.name = name; 
      this.checked = checked; 
     } 

     public String getName() 
     { 
      return name; 
     } 

     public void setName(String name) 
     { 
      this.name = name; 
     } 

     public boolean isChecked() 
     { 
      return checked; 
     } 

     public void setChecked(boolean checked) 
     { 
      this.checked = checked; 
     } 

     public String toString() 
     { 
      return name; 
     } 

     public void toggleChecked() 
     { 
      checked = !checked; 
     } 
    } 

    /** Holds child views for one row. */ 
    private static class PlanetViewHolder 
    { 
     private CheckBox checkBox; 
     private TextView textView; 

     public PlanetViewHolder() 
     { 
     } 

     public PlanetViewHolder(TextView textView, CheckBox checkBox) 
     { 
      this.checkBox = checkBox; 
      this.textView = textView; 
     } 

     public CheckBox getCheckBox() 
     { 
      return checkBox; 
     } 

     public void setCheckBox(CheckBox checkBox) 
     { 
      this.checkBox = checkBox; 
     } 

     public TextView getTextView() 
     { 
      return textView; 
     } 

     public void setTextView(TextView textView) 
     { 
      this.textView = textView; 
     } 
    } 

    /** Custom adapter for displaying an array of Planet objects. */ 
    private static class PlanetArrayAdapter extends ArrayAdapter<Planet> 
    { 

     private LayoutInflater inflater; 

     public PlanetArrayAdapter(Context context, List<Planet> planetList) 
     { 
      super(context, R.layout.simplerow, R.id.rowTextView, planetList); 
      // Cache the LayoutInflate to avoid asking for a new one each time. 
      inflater = LayoutInflater.from(context); 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) 
     { 
      // Planet to display 
      Planet planet = (Planet) this.getItem(position); 

      // The child views in each row. 
      CheckBox checkBox; 
      TextView textView; 

      // Create a new row view 
      if (convertView == null) 
      { 
       convertView = inflater.inflate(R.layout.simplerow, null); 

       // Find the child views. 
       textView = (TextView) convertView 
         .findViewById(R.id.rowTextView); 
       checkBox = (CheckBox) convertView.findViewById(R.id.CheckBox01); 

       // Optimization: Tag the row with it's child views, so we don't 
       // have to 
       // call findViewById() later when we reuse the row. 
       convertView.setTag(new PlanetViewHolder(textView, checkBox)); 

       // If CheckBox is toggled, update the planet it is tagged with. 
       checkBox.setOnClickListener(new View.OnClickListener() 
       { 
        public void onClick(View v) 
        { 
         CheckBox cb = (CheckBox) v; 
         Planet planet = (Planet) cb.getTag(); 
         planet.setChecked(cb.isChecked()); 
        } 
       }); 
      } 
      // Reuse existing row view 
      else 
      { 
       // Because we use a ViewHolder, we avoid having to call 
       // findViewById(). 
       PlanetViewHolder viewHolder = (PlanetViewHolder) convertView 
         .getTag(); 
       checkBox = viewHolder.getCheckBox(); 
       textView = viewHolder.getTextView(); 
      } 

      // Tag the CheckBox with the Planet it is displaying, so that we can 
      // access the planet in onClick() when the CheckBox is toggled. 
      checkBox.setTag(planet); 

      // Display planet data 
      checkBox.setChecked(planet.isChecked()); 
      textView.setText(planet.getName()); 

      return convertView; 
     } 

    } 

    public Object onRetainNonConfigurationInstance() 
    { 
     return planets; 
    } 
} 
+3

'mainListView.isItemChecked (i)' điều này sẽ không hoạt động. –

+0

@Akki Yups công việc của nó tốt. Đã thử nghiệm nó :) –

0

Để giải quyết vấn đề này, bạn sẽ phải tạo một Hạng mục tùy chỉnh sẽ đại diện cho các hộp kiểm riêng lẻ của bạn trong danh sách. Sau đó, mảng các mục này sẽ được lớp bộ điều hợp sử dụng để hiển thị các hộp kiểm của bạn.

Hạng mục này sẽ có biến boolean được chọn sẽ xác định xem hộp kiểm có được chọn hay không. Bạn sẽ phải thiết lập giá trị của biến này trong Phương pháp OnClick bạn của lớp bộ chuyển đổi tùy chỉnh của bạn

Ví dụ

class CheckBoxItem{ 

    boolean isSelected; 


    public void setSelected(boolean val) { 
      this.isSelected = val; 
     } 

     boolean isSelected(){ 
      return isSelected; 

     } 

    } 

Đối CustomAdapter Lớp của bạn mà trông giống như sau:

public class ItemsAdapter extends ArrayAdapter implements OnClickListener { 

// you will have to initialize below in the constructor 
    CheckBoxItem items[]; 



    // You will have to create your check boxes here and set the position of your check box 
    /// with help of setTag method of View as defined in below method, you will use this later // in your onClick method 

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



      CheckBox cBox = null; 

      if (v == null) { 
       LayoutInflater vi = (LayoutInflater) apUI.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       v = vi.inflate(R.layout.attachphoto, null);  

      } 



      CheckBoxItemItem it = items[position];  

      cBox =(CheckBox) v.findViewById(R.id.apCheckBox); 
      cBox.setOnClickListener(this); 
      cBox.setTag(""+position);  


      Log.d(TAG, " CHECK BOX IS: "+cBox+ " Check Box selected Value: "+cBox.isChecked()+" Selection: "+it.isSelected()); 
      if(cBox != null){ 
       cBox.setText(""); 
       cBox.setChecked(it.isSelected()); 
      }  


      return v; 
     } 


     public void onClick(View v) { 
      CheckBox cBox =(CheckBox) v.findViewById(R.id.apCheckBox); 
      int position = Integer.parseInt((String) v.getTag()); 

      Log.d(TAG, "CLicked ..."+cBox.isChecked()); 

      items[position].setSelected(cBox.isChecked());    
     } 

    } 

Sau đó bạn sẽ khai báo và mảng của lớp CheckBoxItem của bạn sẽ được chứa trong lớp Adapter của bạn trong trường hợp này nó sẽ là lớp ItemsAdapter.

Sau đó, khi người dùng nhấn nút bạn có thể lặp qua tất cả các mục trong mảng và kiểm tra xem mục nào được chọn bằng cách sử dụng phương thức isSelected() của lớp CheckBoxItem.

Trong hoạt động của bạn, bạn sẽ có:

ArrayList getSelectedItems(){ 

ArrayList selectedItems = new ArrayList(); 

int size = items.length; 

     for(int i = 0; i<size; i++){ 
      CheckBoxItem cItem = items[i]; 
      if(cItem.isSelected()){     
       selectedItems.add(cItem);     
      }   
     } 

return selectedItems; 

} 
0

tôi đã có vấn đề chính xác như vậy. Tôi đã giải quyết nó theo cách này

public class myActivity extends Activity { 
//ActionBarSherlock mSherlock = ActionBarSherlock.wrap(this); 
public ListView listview; 
private ArrayList<Object> itemlist=new ArrayList<Object>(); 
Button button; 
private myAdapter adapter; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    listview=(ListView)findViewById(R.id.listview1); 
    button=(Button)findViewById(R.id.button1); 
    /*add some data to ur list*/ itemlist.add(something); 
    adapter=new Adapter(myActivity.this, 0, itemlist); 
    listview.setAdapter(adapter); 
    **listview.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 
    listview.setItemsCanFocus(false);** 
    button.setOnClickListner(new OnClickListner() 
    { 
    @Override 
    public void OnClick(View v) 
    { 
     /* this returns the checked item positions in the listview*/ 
     **ArrayList<Integer> itempositions=adapter.getcheckeditemcount();** 

    for(int i:itempositions) 
    { 
      /* This is the main part...u can retrieve the object in the listview which is checked and do further calculations with it*/ 
     **Object info=adapter.getItem(i);** 
          Log.d(TAG,"checked object info= ",info.something); 
       } 
    } 
    }); 
} 


private class myAdapter extends ArrayAdapter<Object> { 

    private Context context; 
    private ArrayList<Object> list; 
    **private ArrayList<Integer> checkedpositions;** 


    public myAdapter(Context localContext,int textViewResourceId, ArrayList<Object> objects) { 
     super(localContext,textViewResourceId,objects); 
     context = localContext; 
     this.list=objects; 
     this.checkedpositions=new ArrayList<Integer>(); 
     //Log.d("adapter","list size= "+objects.size()); 
    } 

@Override  
    public View getView(int position, View convertView, ViewGroup parent) { 

     ImageView picturesView; 
     View v = convertView; 
     TextView Mainitem; 
     final CheckBox check; 

     if (v == null) 
     { 
      LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(R.layout.albumview, null); 


      Object item=list.get(position); 
      if(item!=null) 
      { 

       check = (CheckBox)v.findViewById(R.id.checkBox1); 
        /* set a tag for chekbox with the current view position */ 
       **check.setTag(position);** 
        /*set a onchecked change listner for listning to state of checkbox toggle */ 
       check.setOnCheckedChangeListener(new OnCheckedChangeListener() 
       { 
        @Override 
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) 
        {    
             /*get the tag of the checkbox...in this case this will give the (position of view)*/ 
         Object tag=check.getTag(); 
         if (isChecked) 
         { 
          // perform logic 
          count++; 
          Log.d("Checkbox","added "+tag); 
          checkedpositions.add((Integer) tag); 
         } 
         else 
         { 
          count--; 
          checkedpositions.remove(tag); 
          Log.d("Checkbox","removed "+(Integer)tag); 
         } 

       /* if u dont have a textview in ur listview then ignore this part */   
       Mainitem = (TextView) v.findViewById(R.id.textView1); 
       Mainitem.setText(item.Album_name); 

       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        Log.d("error", "wall"); 
       } 

      } 

     } 

    return v; 

    } 
    /* Finally create a method which return the checkeditem postions in the listview */ 
**public ArrayList<Integer> getcheckeditemcount() 
{ 
    return this.checkedpositions; 
}** 

} 

} 

Tôi hy vọng điều này sẽ hữu ích.

+0

Tại sao bạn sử dụng con trỏ trong java? – Roel

2

Trong phương pháp getview của customadapter, làm

//use the actual id of your checkbox of course 
Checkbox checkbox = (CheckBox)findViewById(R.id.checkbox); 
checkbox.setFocusable(false); 
checkbox.setFocusableInTouchMode(false); 

tại hộp kiểm là nhấp được như là listitem.

Các vấn đề liên quan