安卓可选列表视图

6

我在开发Android应用方面还比较新手。我已经创建了自己的列表适配器,如下所示,并且希望该列表可以被勾选。那么我需要做什么才能让每一行都包含一个复选框呢?

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;
        //}
     }
   } 
}
2个回答

8

我喜欢卡洛斯·塞萨(Carlos Sessa)在他的书《50个Android黑客技巧》中提出的解决方案。

我的activity_favorites.xml看起来像这样:

<?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>

我的FavoritesActivity.java如下:

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

}

我的ListView适配器(FavoritesPackageArrayAdapter.java)非常简单:

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

}

为了使列表项可选中,您的视图必须实现Checkable接口。 我的PackageView.java如下所示:
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();
    }

}

最后是每个列表项的 XML 布局(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>

如果您想在布局中使用实际复选框,它的xml应该如下所示:
<CheckBox
       android:id="@+id/checkBoxId"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:clickable="false"
       android:focusable="false"
       android:focusableInTouchMode="false"/>

如果您让复选框可点击,那么只能通过单击复选框本身来选中它。 此外,请勿将布局设置为可点击,因为某些原因它与可检查接口不兼容。

2
在这些类中,onSelect(...)方法是如何工作的? - justin shores

0

看一下这段代码示例

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

--- 编辑 --

您没有发布您的XML文件。要创建自定义列表行,我是这样做的。首先,在您的Java代码中设置包含列表视图的setcontentview。

setContentView(R.layout.list_main);

那么你的list_main.xml文件应该包含一个列表视图

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

之后设置数据适配器

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

要获取自定义列表项,请创建一个list_item.xml文件,其中包含您的自定义行。您可以在此处放置linearlayouts、图像或复选框。
然后获取您的listview。
  ListView listView = getListView();

你可以在这里设置 OnItemClick 监听器

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

然后在您的自定义适配器文件中,您可以实现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;
    }

我无法查看您的代码并指出问题,但这是在Android中实现自定义列表视图行的正确方法。

这是一个通用的例子。你能帮我看看我代码中需要改变什么吗? - Omran
你不应该发送代码并询问哪里出错了。因为我没有项目,也没有查看它在哪里出错,而且如果存在错误,你也没有放置logcat内容。通常只需放置不起作用的代码并编写logcat错误内容即可 :) 让我们回到代码。从你的xml中获取listview。并调用your_list_View_object_here.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - Yekmer Simsek
我按照您的指示去做了,但复选框仍然没有出现在列表项上。 - Omran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接