Android 带有两个文本和一个复选框的 ListView(例如,像一个设置)

Android ListView with Two text and One CheckBox (eg. like a Setting)

我正在创建设置 Activity,其中在右侧包含两个 TextView 和一个 CheckBox。我已经完成了 ListView。我想像单击项目然后选中 CheckBox 并再次单击项目然后取消选中 CheckBox 一样。如何实现 CheckBox 状态?

我的代码。

MainActivity.java

mport android.app.Activity;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;


public class MainActivity extends ActionBarActivity {
    ListView list;
    String[] title = {
            "Google Plus",
            "Twitter",
            "Windows",
            "Bing",
            "Itunes",
            "Wordpress",
            "Drupal"
    };
    String[] descr = {
            "Social Network",
            "Social Network",
            "OS",
            "Search Engine",
            "Music",
            "Blog/Framework",
            "CMS"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        CustomList adapter = new CustomList(MainActivity.this, title, descr);
        list = (ListView) findViewById(R.id.list);
        list.setAdapter(adapter);
        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkBox);
                if (checkBox.isChecked()){
                    checkBox.setChecked(false);
                }else {
                    checkBox.setChecked(true);
                }

                Toast.makeText(MainActivity.this, "You Clicked at " + title[+position], Toast.LENGTH_SHORT).show();
            }
        });


    }

    private class CustomList extends ArrayAdapter<String> {
        private final Activity context;
        private final String[] title;
        private final String[] descr;


        public CustomList(Activity context,
                          String[] title, String[] descr) {
            super(context, R.layout.list_item, title);
            this.context = context;
            this.title = title;
            this.descr = descr;
        }


        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

            LayoutInflater layoutInflater = context.getLayoutInflater();
            View rowView = layoutInflater.inflate(R.layout.list_item, null, true);
            final TextView txtTitle = (TextView) rowView.findViewById(R.id.tv_title);
            TextView txtDescr = (TextView) rowView.findViewById(R.id.tv_descr);
//            CheckBox checkBox = (CheckBox) convertView.findViewById(R.id.checkBox);
            txtTitle.setText(title[position]);
            txtDescr.setText(descr[position]);

            return rowView;
        }

    }

main.xml

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

    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />

</LinearLayout>

list_item.xml

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

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="name"
        android:textSize="18sp" />

    <TextView
        android:id="@+id/tv_descr"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_title" />

    <CheckBox
        android:id="@+id/checkBox"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:focusable="false"
        android:layout_alignParentRight="true" />


</RelativeLayout>

在 onItemClick 中执行此操作:

@Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        CheckBox checkBox = (CheckBox)view.findViewById(R.id.checkBox1);
        checkBox.toggle();  
    }

但是,这里有一个问题,当你向上滚动并且该行不再可见时,复选框将恢复其初始状态。这就是为什么您必须创建自己的具有 MyItemInfo 通用类型的 ArrayAdapter 的原因。这是一个 class,您可以在其中放置您拥有的 3 个信息:复选框的状态和 2 个字符串(TextView1、TextView2)。

方法 2:(更简单)

只需创建第三个名为 state[] 的布尔数组并将其放入构造函数中,在该数组中更新复选框的状态。当然这个数组的初始状态会是false,也就是初始化之后,在构造函数中调用:Arrays.fill(state,false);声明数组state[]中的值为false。

请确保您不会在每次单击时调用 'CustomAdapter',因为我们不想丢失复选框的旧状态。

方法 2(根据要求)

1) 将实例变量添加到您的 CustomList 布尔值 [] 状态;

2) 更改构造函数以获取参数状态: states = new boolean[7]; //默认为假

 CustomList adapter = new CustomList(MainActivity.this, title, descr,states);

3) 给getView中的复选框添加一个监听器:

onCheckedChanged(){
states[position] = checkBox.isChecked();
}

并将之前的代码保留在 onItemClick 中,这样无论何时单击该项目,复选框都会将其状态从 true 切换为 false,反之亦然,并且每当发生状态更改时,您都会通知布尔数组 (州)。

4) 在getView中,请同时添加这一行: checkBox.setChecked(states[position]);textView.setText(..) 之后或 .

之前

在最后一步(第 4 步)之前,如果您选中第一个项目并向下滚动,然后向上滚动,则该项目将再次取消选中。除非你有一个长列表,否则你不会注意到这一点,但是,为了避免这个问题,每次重新创建视图时,你都希望将 CheckBox 状态设置为与最新状态相同 state[] boolean 数组。感谢@Jitu

@Alan Deep 给出的答案毫无疑问会起作用,但是当您滚动列表时,选择值可能会根据对 getView() 方法的调用而改变。为列表项设置一个标记是否选中,并在 getView() 方法中检查该标记条件。

list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                CheckBox selected = (CheckBox) view.findViewById(R.id.checkBox);
                Boolean checked = ((CheckBox) selected).isChecked();
                selected.setChecked(!checked);
            }
        });

这里我们所做的是......我们获得了这个项目点击事件的整个视图,并从该视图中提取复选框作为 "selected"。现在我们找到它的当前状态,如果它已经被选中,我们取消选中它,反之亦然。我希望它有帮助。