Android - 复选框在列表视图中每 10 次重复一次
Posted
技术标签:
【中文标题】Android - 复选框在列表视图中每 10 次重复一次【英文标题】:Android - Checkbox repeating every 10th in a listview 【发布时间】:2015-12-22 01:25:43 【问题描述】:您好,我一直在尝试使用自定义适配器创建一个列表视图,以在其中放置两个文本视图和一个复选框。列表视图工作正常,但复选框开始每 10 个重复一次,因此如果您选中第一个复选框,则第 10 个复选框也会选中,依此类推。我对此进行了研究,但找不到一个可以很好解释的具体答案,我可以理解我必须做些什么来修复它。那么如何修复复选框以使其不重复?
act_view_items_view.xml
<RelativeLayout
android:layout_
android:layout_
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_
android:layout_
android:text="New Text"
android:id="@+id/workout_items_textView"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="20dp"
android:gravity="center_vertical"
android:layout_toStartOf="@+id/workout_items_textView2"
android:layout_toLeftOf="@+id/workout_items_textView2"
android:textIsSelectable="false"
android: />
<TextView
android:layout_
android:layout_
android:text="New Text"
android:id="@+id/workout_items_textView2"
android:textSize="20dp"
android:gravity="center_vertical"
android:layout_toLeftOf="@+id/workout_items_CheckBox"
android:layout_alignParentTop="true"
android:/>
<CheckBox
android:layout_
android:layout_
android:id="@+id/workout_items_CheckBox"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:
android:layout_alignBottom="@+id/workout_items_textView2"
android:focusable="false"/>
</RelativeLayout>
view_items.java
public class view_items extends ListActivity
private ListAdapter listAdapter;
private ListAdapter listAdapter2;
private TaskDBHelper helper;
private TextView taskTextView;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.act_view_items);
updateUI2();
@Override
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.menu, menu);
return true;
@Override
public boolean onOptionsItemSelected(MenuItem item)
switch (item.getItemId())
case R.id.action_add_task:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Add a Workout");
builder.setMessage("Enter the name of the workout");
final EditText inputField = new EditText(this);
builder.setView(inputField);
builder.setPositiveButton("Next", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialogInterface, int i)
AlertDialog.Builder builder2 = new AlertDialog.Builder(view_items.this);
builder2.setTitle("Add a Workout");
builder2.setMessage("Enter the reps for the workout");
final EditText inputField2 = new EditText(view_items.this);
builder2.setView(inputField2);
builder2.setPositiveButton("Next", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialogInterface, int i)
String task = inputField.getText().toString();
String reps = inputField2.getText().toString();
String workoutID = TaskContract.UNSTABLE_WORKOUT_ID;
helper = new TaskDBHelper(view_items.this);
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.clear();
values.put(TaskContract.Columns.TASK, task);
values.put(TaskContract.Columns.REPS, reps);
values.put(TaskContract.Columns.WORKOUT_ID, workoutID);
db.insertWithOnConflict(TaskContract.TABLE, null, values, SQLiteDatabase.CONFLICT_IGNORE);
updateUI2();
);
builder2.setNegativeButton("Cancel", null);
builder2.create().show();
);
builder.setNegativeButton("Cancel",null);
builder.create().show();
return true;
default:
return false;
public void updateUI2()
// TodoDatabaseHandler is a SQLiteOpenHelper class connecting to SQLite
TaskDBHelper handler = new TaskDBHelper(this);
// Get access to the underlying writeable database
SQLiteDatabase db = handler.getWritableDatabase();
// Query for items from the database and get a cursor back
String sql2 = String.format("SELECT * FROM workout_items WHERE %s = '%s'",
TaskContract.Columns.WORKOUT_ID,
TaskContract.UNSTABLE_WORKOUT_ID);
Cursor todoCursor = db.rawQuery(sql2, null);
// Find ListView to populate
setContentView(R.layout.act_view_items);
ListView lvItems = (ListView) findViewById(android.R.id.list);
// Setup cursor adapter using cursor from last step
view_items_CursorAdapter todoAdapter = new view_items_CursorAdapter(this, todoCursor, 0);
// Attach cursor adapter to the ListView
lvItems.setAdapter(todoAdapter);
public void onDoneButtonClick(View view)
View v = (View) view.getParent();
TextView taskTextView = (TextView) v.findViewById(R.id.taskTextView);
String task = taskTextView.getText().toString();
String sql = String.format("DELETE FROM %s WHERE %s = '%s'",
TaskContract.TABLE,
TaskContract.Columns.TASK,
task);
helper = new TaskDBHelper(view_items.this);
SQLiteDatabase sqlDB = helper.getWritableDatabase();
sqlDB.execSQL(sql);
updateUI2();
view_items_CursorAdapter.java
public class view_items_CursorAdapter extends CursorAdapter
public view_items_CursorAdapter(Context context, Cursor cursor, int flags)
super(context, cursor, 0);
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
return LayoutInflater.from(context).inflate(R.layout.act_view_items_view, parent, false);
@Override
public void bindView(View view, Context context, Cursor cursor)
TextView tvBody = (TextView) view.findViewById(R.id.workout_items_textView);
TextView tvPriority = (TextView) view.findViewById(R.id.workout_items_textView2);
String body = cursor.getString(cursor.getColumnIndexOrThrow("task"));
int priority = cursor.getInt(cursor.getColumnIndexOrThrow("reps"));
tvBody.setText(body);
tvPriority.setText(String.valueOf(priority));
【问题讨论】:
我猜这是因为你的适配器回收了视图,这意味着它重用了一个已经渲染的视图。为了达到最佳效果,您还需要在bindView
方法上设置复选框的选中状态,就像使用 TextView
s 一样
我是否可以将复选框的状态保存到 sql 数据库中,然后像使用 textviews 一样在 bindview 方法上设置它们的状态,否则效率不高吗?
如果选中状态是您认为应该始终可用的状态,那么我不明白为什么不这样做。但您可能希望在应用关闭时将其清除,否则已选中状态将跨会话保持。
【参考方案1】:
试试这个。希望这能解决您的问题。
public class view_items_CursorAdapter extends CursorAdapter
boolean[] checkbox;
public view_items_CursorAdapter(Context context, Cursor cursor, int flags)
super(context, cursor, 0);
checkbox = new boolean[cursor.getCount()];
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent)
return LayoutInflater.from(context).inflate(R.layout.act_view_items_view, parent, false);
@Override
public void bindView(View view, Context context, Cursor cursor)
final int position = cursor.getPosition();
TextView tvBody = (TextView) view.findViewById(R.id.workout_items_textView);
TextView tvPriority = (TextView) view.findViewById(R.id.workout_items_textView2);
CheckBox tvCheck = (CheckBox) view.findViewById(R.id.checkbox1);
String body = cursor.getString(cursor.getColumnIndexOrThrow("task"));
int priority = cursor.getInt(cursor.getColumnIndexOrThrow("reps"));
tvBody.setText(body);
tvPriority.setText(String.valueOf(priority));
tvCheck.setChecked(checkbox[position]);
tvCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
checkbox[position] = isChecked;
);
【讨论】:
它不会重复,但它会在您滚动列表视图后将复选框重置为未选中。 好的,所以我稍微修改了代码,现在它似乎可以正常工作了。感谢这个很好的例子,它让我更好地理解了整个方法。以上是关于Android - 复选框在列表视图中每 10 次重复一次的主要内容,如果未能解决你的问题,请参考以下文章
在android编程中选中复选框时,使用警报框显示从给定的自定义列表视图中删除行的代码
在 Android Studio 中每 10 秒显示一次位置