2012-06-06 15 views
11

Mam na nim ListView z CheckBox. i używam Custom Adapter do wypełniania ListView.Jak uzyskać wybrane elementy listy z widoku listy przy pomocy checkBox i niestandardowego adaptera?

W moim pliku mam na dole Button. Chcę tylko, aby użytkownik wybrał liczbę wierszy w ListView, a kiedy kliknął na Button, uzyskał pozycję wybranych elementów, dzięki czemu mógłbym uzyskać obiekt dla określonego wiersza do dalszych obliczeń.

+0

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

Odpowiedz

10

Poniżej Snippet robi dokładnie to, co chcesz.

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)' to nie zadziała. –

+0

@Akki Yups jego praca jest w porządku. Przetestowałem to :) –

0

Aby rozwiązać ten problem, należy utworzyć niestandardową klasę pozycji, która będzie reprezentować poszczególne pola wyboru na liście. Tablica tych elementów zostanie następnie użyta przez klasę adaptera do wyświetlenia twoich pól wyboru.

klasa

Pozycja ta będzie mieć logiczną zmienną IsSelected który określi, czy jest zaznaczone pole wyboru, czy nie. trzeba będzie ustawić wartość tej zmiennej w Metodzie OnClick z niestandardowego klasy adaptera

Dla przykładu

class CheckBoxItem{ 

    boolean isSelected; 


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

     boolean isSelected(){ 
      return isSelected; 

     } 

    } 

dla swojej klasy CustomAdapter które wyglądają jak następuje:

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());    
     } 

    } 

później will zadeklaruje i uszereguje klasę CheckBoxItem, która będzie zawarta przez twoją klasę Adapter w tym przypadku będzie to klasa ItemsAdapter.

Następnie, gdy użytkownik naciśnie przycisk, można przejrzeć wszystkie elementy w tablicy i sprawdzić, który z nich jest wybrany przy użyciu metody isSelected() klasy CheckBoxItem.

W swojej działalności trzeba będzie:

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

miałem dokładnie ten sam problem. Rozwiązałem go w ten sposób:

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; 
}** 

} 

} 

Mam nadzieję, że to pomoże.

+0

Dlaczego używasz wskaźników w java? – Roel

2

W metodzie getview w customadapter, wykonaj

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

teraz pole wyboru jest klikalny jak jest listitem.

Powiązane problemy