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"。现在我们找到它的当前状态,如果它已经被选中,我们取消选中它,反之亦然。我希望它有帮助。
我正在创建设置 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"。现在我们找到它的当前状态,如果它已经被选中,我们取消选中它,反之亦然。我希望它有帮助。