【问题标题】:android checkable listviewandroid 可检查的列表视图
【发布时间】:2011-08-21 19:35:07
【问题描述】:

我在开发 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;
        //}
     }
   } 
}

【问题讨论】:

    标签: android listview checkbox


    【解决方案1】:

    我喜欢 Carlos Sessa 的“50 Android hacks”一书中的解决方案。

    我的 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>
    

    My 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"/>
    

    如果您让复选框可单击,则只能通过单击复选框本身来检查它。 也不要让你的布局可点击,因为某些原因它不适用于 Checkable 界面。

    【讨论】:

    • onSelect(...) 方法如何跨这些类工作?
    【解决方案2】:

    看看那个代码示例

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

    --- 编辑 --

    您没有发布您的 xml 文件。为了有一个自定义列表行,我这样做了。首先,我在你的 java 代码中设置了包含我的列表视图的内容视图。

    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 文件。您可以在此处放置线性布局、图像或复选框。

    然后获取您的列表视图

      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 中为 listview 实现自定义行的正确方法。

    【讨论】:

    • 这是一个通用示例。你能帮我修改我的代码吗
    • 您不应发送代码并询问问题所在。因为我没有项目,所以没有看它在哪里不起作用,如果存在错误,你也没有放置 logcat 内容。一般只要把不起作用的代码写logcat错误内容即可。 :) 让我们回到代码。从您的 xml 中获取您的列表视图。并调用 your_list_View_object_here.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    • 我按照你说的做了,但复选框仍然没有出现在列表项上
    猜你喜欢
    • 1970-01-01
    • 2018-11-11
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多