从适配器刷新列表视图
Refresh listview from adapter
我有 2 个列表 CheckBox
。当用户勾选 list_1
中的 CheckBox
时,列表项将转移到 list_2
。它工作正常,除了我无法从适配器刷新列表。尝试使用 notifyDataSetChanged()
但没有任何反应。
在我的 MainActivity
:
CustomListAdapter adapter = new CustomListAdapter(this, db.getAllTasks(MySQLiteHelper.TABLE_HOME, false), MySQLiteHelper.TABLE_HOME,false);
mylistView.setAdapter(adapter); // Set the adapter for list_1
CustomListAdapter adapterDone = new CustomListAdapter(this, db.getAllTasks(MySQLiteHelper.TABLE_HOME, true), MySQLiteHelper.TABLE_HOME,true);
listViewDone.setAdapter(adapterDone); // Set the adapter for list_2
和 getAllTasks
函数:
public List<Task> getAllTasks(String tableName, boolean done) {
List<Task> tasks = new LinkedList<Task>();
String op = done ? "1" : "0";
String query = "SELECT * FROM " + tableName + " WHERE done=" + op;
Log.d(TAG, "query: " + query);
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Task task = null;
if (cursor.moveToFirst()) {
do {
task = new Task();
task.setTaskText(cursor.getString(0));
task.setDate(cursor.getString(1));
task.setTime(cursor.getString(2));
task.setDone(cursor.getInt(3) == 1);
tasks.add(task);
} while (cursor.moveToNext());
}
return tasks;
}
这是我的 Adapter
:
public class CustomListAdapter extends ArrayAdapter<Task> {
private static final String TAG = "DTAG";
private final Activity context;
private final List<Task> myTasks;
private final MySQLiteHelper db;
private final String tableName;
private final boolean done;
public CustomListAdapter(Activity context, List<Task> myTasks, String tableName, boolean done) {
super(context, R.layout.list_row, myTasks);
this.context = context;
this.myTasks = myTasks;
this.tableName = tableName;
this.done = done;
db = new MySQLiteHelper(context);
}
public View getView(final int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_row, null, true);
final TextView txtTitle = (TextView) rowView.findViewById(R.id.listMainTextView);
TextView txtSubTitle = (TextView) rowView.findViewById(R.id.listSubTextView);
CheckBox ch = (CheckBox) rowView.findViewById(R.id.checkBox);
ch.setChecked(done);
ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Log.d(TAG, "position: " + position + " Name: " + myTasks.get(position).getTaskText() + " Checked");
db.updateTask(myTasks.get(position).getTaskText(), tableName, true);
} else {
Log.d(TAG, "position: " + position + " Name: " + myTasks.get(position).getTaskText() + " UnChecked");
db.updateTask(myTasks.get(position).getTaskText(), tableName, false);
}
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
}, 1000);
}
});
txtTitle.setText(myTasks.get(position).getTaskText());
txtSubTitle.setText(myTasks.get(position).getTime() + " " + myTasks.get(position).getDate());
return rowView;
};
}
您必须在更新数据库后再次调用 get task 以获取新的任务列表,然后调用 notifydatasetchange。
在这种情况下,我个人使用 cursoradapter,更改后,重新查询我的光标并调用 changecursor。
希望对你有帮助。
像这样在 MainActivity
中创建两个单独的 Task
列表。
List<Task> tasksPendingList = new LinkedList<Task>();
List<Task> tasksDoneList = new LinkedList<Task>();
现在通过在初始化 Adapter
之前调用 getAllTasks
方法来获取任务。
tasksPendingList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, false);
tasksDoneList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, true);
现在像这样初始化适配器
CustomListAdapter adapter = new CustomListAdapter(this, tasksPendingList, MySQLiteHelper.TABLE_HOME, false);
mylistView.setAdapter(adapter); // Set the adapter for list_1
CustomListAdapter adapterDone = new CustomListAdapter(this, tasksDoneList, MySQLiteHelper.TABLE_HOME, true);
listViewDone.setAdapter(adapterDone); // Set the adapter for list_2
现在,在 Adapter
的 getView
方法中,您需要再次重新填充列表才能使 notifyDatasetChanged
正常工作。
ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
db.updateTask(myTasks.get(position).getTaskText(), tableName, true);
} else {
db.updateTask(myTasks.get(position).getTaskText(), tableName, false);
}
// Just call refreshBothList here
refreshBothList();
}
});
您可以考虑在 MainActivity
中的 getView
方法之外采用列表的刷新机制。
public void refreshBothList() {
// Repopulate the lists.
tasksPendingList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, false);
tasksDoneList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, true);
adapter.notifyDataSetChanged();
adapterDone.notifyDataSetChanged();
}
您可以考虑将 CustomListAdapter
作为内部 class 放入 MainActivity
。
我有 2 个列表 CheckBox
。当用户勾选 list_1
中的 CheckBox
时,列表项将转移到 list_2
。它工作正常,除了我无法从适配器刷新列表。尝试使用 notifyDataSetChanged()
但没有任何反应。
在我的 MainActivity
:
CustomListAdapter adapter = new CustomListAdapter(this, db.getAllTasks(MySQLiteHelper.TABLE_HOME, false), MySQLiteHelper.TABLE_HOME,false);
mylistView.setAdapter(adapter); // Set the adapter for list_1
CustomListAdapter adapterDone = new CustomListAdapter(this, db.getAllTasks(MySQLiteHelper.TABLE_HOME, true), MySQLiteHelper.TABLE_HOME,true);
listViewDone.setAdapter(adapterDone); // Set the adapter for list_2
和 getAllTasks
函数:
public List<Task> getAllTasks(String tableName, boolean done) {
List<Task> tasks = new LinkedList<Task>();
String op = done ? "1" : "0";
String query = "SELECT * FROM " + tableName + " WHERE done=" + op;
Log.d(TAG, "query: " + query);
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Task task = null;
if (cursor.moveToFirst()) {
do {
task = new Task();
task.setTaskText(cursor.getString(0));
task.setDate(cursor.getString(1));
task.setTime(cursor.getString(2));
task.setDone(cursor.getInt(3) == 1);
tasks.add(task);
} while (cursor.moveToNext());
}
return tasks;
}
这是我的 Adapter
:
public class CustomListAdapter extends ArrayAdapter<Task> {
private static final String TAG = "DTAG";
private final Activity context;
private final List<Task> myTasks;
private final MySQLiteHelper db;
private final String tableName;
private final boolean done;
public CustomListAdapter(Activity context, List<Task> myTasks, String tableName, boolean done) {
super(context, R.layout.list_row, myTasks);
this.context = context;
this.myTasks = myTasks;
this.tableName = tableName;
this.done = done;
db = new MySQLiteHelper(context);
}
public View getView(final int position, View view, ViewGroup parent) {
LayoutInflater inflater = context.getLayoutInflater();
View rowView = inflater.inflate(R.layout.list_row, null, true);
final TextView txtTitle = (TextView) rowView.findViewById(R.id.listMainTextView);
TextView txtSubTitle = (TextView) rowView.findViewById(R.id.listSubTextView);
CheckBox ch = (CheckBox) rowView.findViewById(R.id.checkBox);
ch.setChecked(done);
ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Log.d(TAG, "position: " + position + " Name: " + myTasks.get(position).getTaskText() + " Checked");
db.updateTask(myTasks.get(position).getTaskText(), tableName, true);
} else {
Log.d(TAG, "position: " + position + " Name: " + myTasks.get(position).getTaskText() + " UnChecked");
db.updateTask(myTasks.get(position).getTaskText(), tableName, false);
}
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
notifyDataSetChanged();
}
}, 1000);
}
});
txtTitle.setText(myTasks.get(position).getTaskText());
txtSubTitle.setText(myTasks.get(position).getTime() + " " + myTasks.get(position).getDate());
return rowView;
};
}
您必须在更新数据库后再次调用 get task 以获取新的任务列表,然后调用 notifydatasetchange。
在这种情况下,我个人使用 cursoradapter,更改后,重新查询我的光标并调用 changecursor。
希望对你有帮助。
像这样在 MainActivity
中创建两个单独的 Task
列表。
List<Task> tasksPendingList = new LinkedList<Task>();
List<Task> tasksDoneList = new LinkedList<Task>();
现在通过在初始化 Adapter
之前调用 getAllTasks
方法来获取任务。
tasksPendingList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, false);
tasksDoneList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, true);
现在像这样初始化适配器
CustomListAdapter adapter = new CustomListAdapter(this, tasksPendingList, MySQLiteHelper.TABLE_HOME, false);
mylistView.setAdapter(adapter); // Set the adapter for list_1
CustomListAdapter adapterDone = new CustomListAdapter(this, tasksDoneList, MySQLiteHelper.TABLE_HOME, true);
listViewDone.setAdapter(adapterDone); // Set the adapter for list_2
现在,在 Adapter
的 getView
方法中,您需要再次重新填充列表才能使 notifyDatasetChanged
正常工作。
ch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
db.updateTask(myTasks.get(position).getTaskText(), tableName, true);
} else {
db.updateTask(myTasks.get(position).getTaskText(), tableName, false);
}
// Just call refreshBothList here
refreshBothList();
}
});
您可以考虑在 MainActivity
中的 getView
方法之外采用列表的刷新机制。
public void refreshBothList() {
// Repopulate the lists.
tasksPendingList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, false);
tasksDoneList = db.getAllTasks(MySQLiteHelper.TABLE_HOME, true);
adapter.notifyDataSetChanged();
adapterDone.notifyDataSetChanged();
}
您可以考虑将 CustomListAdapter
作为内部 class 放入 MainActivity
。