2011-05-09 23 views
6

Soy bastante nuevo en el desarrollo de aplicaciones de Android. He creado mi propio adaptador de lista como se muestra a continuación y quiero que esa lista sea verificable. ¿Qué debo hacer para que mi lista contenga una casilla de verificación para cada fila?android checkable listview

public class listAvtivity extends ListActivity { 
private LayoutInflater mInflater; 
private Vector<RowData> data; 
RowData rd; 
static final String[] title = new String[] { 
     "*New*Apple iPad Wi-Fi (16GB)", "7 Touch Tablet -2GB Google Android", 
"Apple iPad Wi-Fi (16GB) Rarely Used ","Apple iPad Wi-Fi (16GB) AppleCase"  }; 
static final String[] detail = new String[] { 
     "1h 37m Shipping: $10.00","1h 39m Shipping: Free","58m 6s Shipping:$10.00","59m 30s Shipping: $10.95" }; 
//private Integer[] imgid = { 
// R.drawable.bsfimg,R.drawable.bsfimg4,R.drawable.bsfimg2, 
// R.drawable.bsfimg5 
//}; 
@Override 
public void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState); 
setContentView(R.layout.main); 
mInflater = (LayoutInflater) getSystemService(
Activity.LAYOUT_INFLATER_SERVICE); 
data = new Vector<RowData>(); 
for(int i=0;i<title.length;i++){ 
try { 
    rd = new RowData(i,title[i],detail[i]); 
    } catch (ParseException e) { 
     e.printStackTrace(); 
    } 
    data.add(rd); 
} 
    CustomAdapter adapter = new CustomAdapter(this, R.layout.list, 
            R.id.title, data); 
    setListAdapter(adapter); 
    getListView().setTextFilterEnabled(true); 
} 
    public void onListItemClick(ListView parent, View v, int position, 
                   long id) { 
    Toast.makeText(getApplicationContext(), "You have selected " 
        +(position+1)+"th item", Toast.LENGTH_SHORT).show(); 
} 
     private class RowData { 
     protected int mId; 
     protected String mTitle; 
     protected String mDetail; 
     RowData(int id,String title,String detail){ 
     mId=id; 
     mTitle = title; 
     mDetail=detail; 
    } 
     @Override 
     public String toString() { 
       return mId+" "+mTitle+" "+mDetail; 
     } 
} 
    private class CustomAdapter extends ArrayAdapter<RowData> { 
    public CustomAdapter(Context context, int resource, 
         int textViewResourceId, List<RowData> objects) { 
super(context, resource, textViewResourceId, objects); 
} 
     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
     ViewHolder holder = null; 
     TextView title = null; 
     TextView detail = null; 
     //ImageView i11=null; 
     RowData rowData= getItem(position); 
     if(null == convertView){ 
      convertView = mInflater.inflate(R.layout.list, null); 
      holder = new ViewHolder(convertView); 
      convertView.setTag(holder); 
} 
      holder = (ViewHolder) convertView.getTag(); 
      title = holder.gettitle(); 
      itle.setText(rowData.mTitle); 
      detail = holder.getdetail(); 
      detail.setText(rowData.mDetail); 
      //i11=holder.getImage(); 
      //i11.setImageResource(imgid[rowData.mId]); 
      return convertView; 
} 
      private class ViewHolder { 
      private View mRow; 
      private TextView title = null; 
      private TextView detail = null; 
      //private ImageView i11=null; 
      public ViewHolder(View row) { 
      mRow = row; 
} 
     public TextView gettitle() { 
      if(null == title){ 
       title = (TextView) mRow.findViewById(R.id.title); 
       } 
      return title; 
     } 
     public TextView getdetail() { 
      if(null == detail){ 
        detail = (TextView) mRow.findViewById(R.id.detail); 
        } 
      return detail; 
     } 
     //public ImageView getImage() { 
      // if(null == i11){ 
      //  i11 = (ImageView) mRow.findViewById(R.id.img); 
       //      } 
       //return i11; 
     //} 
    } 
    } 
} 

Respuesta

0

vistazo a ese ejemplo de código

http://www.androidpeople.com/android-listview-multiple-choice-example

--- Edición -

Usted no publicar sus archivos XML. Para tener una fila de lista personalizada lo hice de esta manera. Primero configuro la vista de contenido que contiene mi vista de lista en tu código java.

setContentView(R.layout.list_main); 

A continuación, el archivo de list_main.xml debe contener una vista de lista

<ListView android:id="@android:id/list" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" /> 

definido después adaptador de datos

setListAdapter(new YOUR_ADAPTER_CLASS(this, R.layout.list_item, YOUR_OBJECT)); 

Para obtener un elemento de lista personalizada, crear un archivo que contiene list_item.xml tu fila personalizada Aquí puedes poner linearlayouts, imágenes o casillas de verificación.

A continuación, obtener su vista de lista

ListView listView = getListView(); 

Puede establecer onitemclick oyente aquí

listView.setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, 
      int position, long id) { 
      //YOUR_CODE_HERE 
     } 
     }); 

A continuación, en el archivo de adaptador personalizado se puede implementar la función getView

@Override 
    public View getView(int position, View convertView, ViewGroup parent) 
    { 
      View view = convertView; 
      if (view == null) { 
       LayoutInflater layoutInflator = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
       view = layoutInflator.inflate(R.layout.list_item, null); 
      } 
      //YOU CAN GET EVERY OBJECT AND SET YOUR CUSTOM ROW like below 
      //view.findViewById(R.id.YOUR_OBJECT_ID_HERE); 
      return view; 
    } 

no podía mirar en su código y decir lo que está mal, pero esta es la forma correcta de implementar filas personalizadas para li stview en android.

+0

esto es un ejemplo general. podría ayudarme lo que tengo que cambiar en mi código – Omran

+0

no debería enviar el código y preguntar qué está mal. como no tengo proyecto, no miré dónde no funcionaba y no puse contenido de logcat si existe un error. En general, simplemente coloque el código que no funciona y escriba contenido de error de logcat. :) vuelve al código. obtén tu lista de visitas desde tu xml. y llama a your_list_View_object_here.setChoiceMode (ListView.CHOICE_MODE_MULTIPLE); –

+0

Hice lo que me dijo, pero igual la casilla de verificación no aparece en el elemento de lista – Omran

8

Me gustó la solución de Carlos Sessa de su libro "50 hacks de Android".

mi activity_favorites.xml se parece a esto:

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

    <ListView 
     android:id="@+id/favContainer" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:choiceMode="singleChoice"/> 

</RelativeLayout> 

Mi FavoritesActivity.java se ve así:

package com.myproject; 

import java.util.ArrayList; 

import com.myproject.R; 
import com.myproject.model.Package; 
import com.myproject.adapter.FavoritesPackageArrayAdapter; 
import com.myproject.utils.DatabaseHelper; 

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.View; 
import android.view.Window; 
import android.widget.ListView; 

public class FavoritesActivity extends Activity 
{ 
    protected ListView list; 
    protected String selectedPackage; 
    protected ArrayList<Package> packages; 
    protected FavoritesPackageArrayAdapter adapter; 

    private DatabaseHelper db = new DatabaseHelper(this); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 

     this.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     setContentView(R.layout.activity_favorites); 

     packages = db.getPackages(); 
     adapter = new FavoritesPackageArrayAdapter(this, -1, packages); 
     list = (ListView) findViewById(R.id.favContainer); 
     list.setAdapter(adapter); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) 
    { 
     getMenuInflater().inflate(R.menu.main, menu); 
     return true; 
    } 

    public void onSelect(View view) 
    { 
     int pos = list.getCheckedItemPosition(); 
     if(ListView.INVALID_POSITION != pos) 
      selectedPackage = packages.get(pos).getId(); 
    } 

} 

Mi adaptador de ListView (FavoritesPackageArrayAdapter.java) es bastante simple:

package com.myproject.adapter; 

import java.util.List; 

import com.myproject.model.Package; 
import com.myproject.view.PackageView; 

import android.content.Context; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 

public class FavoritesPackageArrayAdapter extends ArrayAdapter<Package> 
{ 

    public FavoritesPackageArrayAdapter(Context context, int resource, List<Package> objects) 
    { 
     super(context, resource, objects); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) 
    { 
     if(convertView == null) 
      convertView = new PackageView(getContext()); 

     Package pack = getItem(position); 
     PackageView packView = (PackageView) convertView; 
     packView.setPackage(pack); 

     return convertView; 
    } 

} 

Para que los elementos de la lista sean seleccionables, su vista debe implementar inte cara. Mi PackageView.java parece:

package com.myproject.view; 

import java.util.ArrayList; 

import com.myproject.R; 
import com.myproject.model.Package; 
import com.myproject.model.PackageEvent; 

import android.content.Context; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.widget.Checkable; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.CheckBox; 

public class PackageView extends LinearLayout implements Checkable 
{ 
    private View v; 
    private TextView tv0; 
    private TextView tv1; 
    private TextView tv2; 
    private TextView tv3; 

    private CheckBox testCheckBox; 

    public PackageView(Context context) 
    { 
     super(context); 
     LayoutInflater inflater = LayoutInflater.from(context); 
     v = inflater.inflate(R.layout.favorites_package, this, true); 
     tv0 = (TextView) v.findViewById(R.id.favPackageId); 
     tv1 = (TextView) v.findViewById(R.id.favEventDate); 
     tv2 = (TextView) v.findViewById(R.id.favEventAddres); 
     tv3 = (TextView) v.findViewById(R.id.favEventState); 

     // I don't have checkbox in my layout, but if I had: 
     // testCheckBox = (CheckBox) v.findViewById(R.id.checkBoxId); 
    } 

    public void setPackage(Package pack) 
    { 
     // my custom method where I set package id, date, and time 
     ... 
    } 

    private Boolean checked = false; 

    @Override 
    public boolean isChecked() 
    { 
     return checked; 
     // if I had checkbox in my layout I could 
     // return testCheckBox.checked(); 
    } 

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

     // since I choose not to have check box in my layout, I change background color 
     // according to checked state 
     if(isChecked()) 
      ... 
     else 
      ... 
     // if I had checkbox in my layout I could 
     // testCheckBox.setChecked(checked); 
    } 

    @Override 
    public void toggle() 
    { 
     checked = !checked; 
     // if I had checkbox in my layout I could 
     // return testCheckBox.toggle(); 
    } 

} 

Y, por último diseño xml de cada elemento de la lista (favorites_package.xml):

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

    <TextView 
     android:id="@+id/favPackageId" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <LinearLayout 
     android:id="@+id/favTimeDateContainer" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:weightSum="1"> 

     <TextView 
      android:id="@+id/favEventDate" 
      android:layout_width="0dp" 
      android:layout_height="match_parent" 
      android:layout_weight="0.5"/> 

     <TextView 
      android:id="@+id/favEventAddres" 
      android:layout_width="0dp" 
      android:layout_height="wrap_content" 
      android:layout_weight="0.5"/> 
    </LinearLayout> 


    <TextView 
     android:id="@+id/favEventState" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

</LinearLayout> 

Si quería tener casilla de verificación real en su diseño que es XML debe ser algo como:

<CheckBox 
     android:id="@+id/checkBoxId" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:clickable="false" 
     android:focusable="false" 
     android:focusableInTouchMode="false"/> 

Si la izquierda se puede hacer clic casilla de verificación, sólo se podía comprobar que sólo haciendo clic en la casilla de verificación sí mismo. Además, no haga clic en su diseño, por alguna razón no funciona con la interfaz de Checkable.

+1

¿Cómo funciona el método onSelect (...) en esas clases? –