Я делаю простое приложение со списком задач и использую базу данных для хранения всего. Я написал собственный CursorAdapter, расширяющий ResourceCursorAdapter, для обработки данных. Все отображается нормально, но как только вы начинаете выходить за рамки этого, все становится отрывочным. Во-первых, моя реализация:
import android.app.AlertDialog;
import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.ResourceCursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.Filterable;
import android.widget.LinearLayout;
import android.widget.TextView;
/**
* @author Dave Smith
*
*/
public class TaskCursorAdapter extends ResourceCursorAdapter {
/**
* @param context
* @param layout
* @param c
* @param from
* @param to
* @param flags
*/
private Context context;
private int layout, isCheckedFromDb, IdFromDb;
private Cursor cursor;
public TaskCursorAdapter(Context context, int layout, Cursor c,
int flags) {
super(context, layout, c, flags);
this.context = context;
this.layout = layout;
}
public TaskCursorAdapter(Context context, int layout){
super(context, layout, null, 0);
this.context = context;
this.layout = layout;
}
public TaskCursorAdapter(Context context, int layout, Cursor c){
super(context, layout, c, 0);
this.context = context;
this.layout = layout;
}
public TaskCursorAdapter(Context context, int layout, Cursor cursor, boolean autoRequery)
{
super(context, layout, cursor, autoRequery);
this.context = context;
this.layout = layout;
}
public View newView(Context context, Cursor cursor, ViewGroup parent){
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
return v;
}
public void bindView(View v, Context context, Cursor c){
CheckBox taskCheckBox = (CheckBox)v.findViewById(R.id.taskCheckBox);
TextView taskText = (TextView)v.findViewById(R.id.taskTitle);
TextView taskNote = (TextView)v.findViewById(R.id.taskNote);
final long assignedID = v.getID();
//v.setClickable(true);
//LinearLayout holder = (LinearLayout)v.findViewById(R.id.container);
//holder.setClickable(true);
//IdFromDb = c.getInt(c.getColumnIndex(NagTasksDatabaseHelper.ID));
taskText.setText(c.getString(c.getColumnIndex(NagTasksDatabaseHelper.TASK)));
taskNote.setText(c.getString(c.getColumnIndex(NagTasksDatabaseHelper.NOTE)));
//isCheckedFromDb = c.getInt(c.getColumnIndex(NagTasksDatabaseHelper.CHECKED));
taskCheckBox.setChecked(c.getInt(c.getColumnIndex(NagTasksDatabaseHelper.CHECKED))==1);
//cursor = c;
taskCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//Really Old method:
/*NagTasksDatabaseHelper helper = new NagTasksDatabaseHelper(null);
int idCol = cursor.getColumnIndex(NagTasksDatabaseHelper.ID);
int taskID = helper.getNewTaskId();
if (idCol!=-1)
{
taskID= cursor.getInt(idCol);
if (isChecked){
helper.checkOffTask(taskID);
} else {
helper.uncheckTask(taskID);
}
}
//TODO Solve how to use helper to change ISCHECKED in database
helper.close();
//Old method:
NagTasksDatabaseHelper helper = new NagTasksDatabaseHelper(null);
if (isChecked) {
helper.checkOffTask(IdFromDb);
} else {
helper.uncheckTask(IdFromDb);
}
helper.close();*/
//Current method:
if (assignedID!=View.NO_ID) {
NagTasksDatabaseHelper helper = new NagTasksDatabaseHelper(buttonView.getContext());
if (isChecked) {
helper.checkOffTask(assignedID);
} else {
helper.uncheckTask(assignedID);
}
helper.close();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(buttonView.getContext());
builder.setMessage("No ID found. Try something else.");
builder.setCancelable(true);
builder.create().show();
}
}
});
}
}
Выпуск 1
EDIT: Проблема решена, хотя я не знаю, как это сделать.
В текущем состоянии я получаю сообщение об ошибке в консоли Eclipse, когда нажимаю «Выполнить». Это вообще не влияет на то, насколько хорошо он работает, но в предыдущей реализации, где я использовал макет, который имел только CheckBox и просто изменил текст CheckBox, эта ошибка не появлялась:
[2012-06-18 16:10:15 - ddms] null
java.lang.NullPointerException
at com.android.ddmlib.JdwpPacket.writeAndConsume(JdwpPacket.java:213)
at com.android.ddmlib.Client.sendAndConsume(Client.java:575)
at com.android.ddmlib.HandleHello.sendHELO(HandleHello.java:142)
at com.android.ddmlib.HandleHello.sendHelloCommands(HandleHello.java:65)
at com.android.ddmlib.Client.getJdwpPacket(Client.java:672)
at com.android.ddmlib.MonitorThread.processClientActivity(MonitorThread.java:317)
at com.android.ddmlib.MonitorThread.run(MonitorThread.java:263)
[2012-06-18 16:10:15 - ddms] null
java.lang.NullPointerException
at com.android.ddmlib.JdwpPacket.writeAndConsume(JdwpPacket.java:213)
at com.android.ddmlib.Client.sendAndConsume(Client.java:575)
at com.android.ddmlib.HandleHello.sendHELO(HandleHello.java:142)
at com.android.ddmlib.HandleHello.sendHelloCommands(HandleHello.java:65)
at com.android.ddmlib.Client.getJdwpPacket(Client.java:672)
at com.android.ddmlib.MonitorThread.processClientActivity(MonitorThread.java:317)
at com.android.ddmlib.MonitorThread.run(MonitorThread.java:263)
Выпуск 2
ListFragment, который использует этот CursorAdapter, не выполняет свой метод OnListItemClick(). Точно так же я зарегистрировал ListView ListFragment для использования ContextMenu (с registerForContextMenu()), но долгое нажатие не вызывает контекстное меню.
Выпуск 3
Раскомментирование taskCheckBox.setOnCheckedChangeListener обычно приводит к плохим последствиям при установленном флажке. Как правило, он генерирует исключение нулевого указателя и аварийно завершает работу, потому что не знает, для чего _id вызывать checkOffTask() или uncheckTask(). (РЕДАКТИРОВАТЬ: изменения, внесенные в последнее редактирование... по-прежнему не делают то, что я хочу, но, по крайней мере, не падает. Также раздражает, что getItemId() запрашивает позицию и я не знаю, как получить это для данного элемента в ListView из курсора, иначе я бы использовал это.)
Может ли кто-нибудь помочь мне решить эти проблемы? Я до сих пор в основном не понимаю, как работают CursorAdapters, несмотря на -something-read">просить помощи по этому вопросу раньше.
EDIT: я должен отметить, что в моем приложении есть другой список, в котором используется очень слегка измененный ResourceCursorAdapter (см. связанный вопрос), и ни одна из этих проблем там не возникла. (Хотя у проблемы 3 нет причин для появления, так как это простой список строк.)
ResourceCursorAdapterвместоCursorAdapter? - person Macarse   schedule 19.06.2012SimpleCursorAdapter, но на самом деле я не воспользовался преимуществами, которые дало мне использованиеSimpleCursorAdapter. Итак, я спустился по звену в цепочке. - person MowDownJoe   schedule 19.06.2012CursorAdapterнапрямую. - person Macarse   schedule 20.06.2012ResourceCursorAdapterсправляется с инфляцией за меня, но если вы думаете, что у вас есть что-то, что решает мои проблемы, покажите мне. - person MowDownJoe   schedule 20.06.2012