android 可检查列表视图

发布于 2024-11-05 19:33:51 字数 3950 浏览 0 评论 0原文

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

I am quite new in developing android applications.
I have created my own list adapter as show below and I want that list to be checkable. What do I have to do so that my list contains a checkbox for each row?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦醒时光 2024-11-12 19:33:51

我喜欢 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>

我的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 界面一起使用。

I liked Carlos Sessa solution from his book "50 Android hacks".

my activity_favorites.xml looks like this:

<?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 looks like this:

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

}

My ListView adapter (FavoritesPackageArrayAdapter.java) is quite 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;
    }

}

In order to have list items checkable, your view has to implement Checkable interface.
My PackageView.java looks like:

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

}

And finally xml layout of each list item (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>

If you wanted to have actual checkbox in your layout it's xml should look something like:

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

If you left checkbox clickable, you could only check it only by clicking on checkbox itself.
Also don't make your layout clickable, for some reason it doesn't work with Checkable interface.

痕至 2024-11-12 19:33:51

查看该代码示例

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

--- 编辑 --

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

setContentView(R.layout.list_main);

然后,您的 list_main.xml 文件应包含一个 listview

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

AFterwards 设置数据适配器。

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

要获取自定义列表项,请创建一个包含自定义行的 list_item.xml 文件。您可以在此处放置线性布局、图像或复选框。

然后获取你的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中实现listview自定义行的正确方法。

Look at that code sample

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

--- Edit --

You did not post your xml files. To have a custom list row I did it this way. First I setcontentview which contains my listview in your java code.

setContentView(R.layout.list_main);

Then your list_main.xml file should contain a listview

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

AFterwards set data adapter

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

To get a custom list item, create a list_item.xml file which contains your custom row. You can put linearlayouts, images or checkboxes here.

Then get your listview

  ListView listView = getListView();

You can set onitemclick listener here

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

Then in your custom adapter file you can implement getview function

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

I could not look at your code and say what is wrong, but this is the correct way of implementing custom rows for listview in android.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文