Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android编程:通过复选框从listview中查找数据库密钥id。待办事项清单/杂货清单_Android_Sqlite_Listview_Checkbox_Onclick - Fatal编程技术网

Android编程:通过复选框从listview中查找数据库密钥id。待办事项清单/杂货清单

Android编程:通过复选框从listview中查找数据库密钥id。待办事项清单/杂货清单,android,sqlite,listview,checkbox,onclick,Android,Sqlite,Listview,Checkbox,Onclick,我是一个使用Android/Java编程的初学者,我在不太难完成的事情上遇到了麻烦。我使用的代码是我试图从谷歌记事本v1中改编的。我意识到这个版本远未完成,但它是最精简的开始 我试图做的是修改列表,使其包含注释,但使其功能类似于待办事项列表,可以向列表中添加项目。在每个项目旁边,都需要有一个复选框。我正在将复选框状态写入数据库,而我遇到的问题是从数据库中收集每个复选框的相关id。如果我手动指定列表中需要的项目,它可以工作,但是我无法获得OnClick(setChk)来提取数据库所需的id。我在下

我是一个使用Android/Java编程的初学者,我在不太难完成的事情上遇到了麻烦。我使用的代码是我试图从谷歌记事本v1中改编的。我意识到这个版本远未完成,但它是最精简的开始

我试图做的是修改列表,使其包含注释,但使其功能类似于待办事项列表,可以向列表中添加项目。在每个项目旁边,都需要有一个复选框。我正在将复选框状态写入数据库,而我遇到的问题是从数据库中收集每个复选框的相关id。如果我手动指定列表中需要的项目,它可以工作,但是我无法获得OnClick(setChk)来提取数据库所需的id。我在下面发布了4个重要的代码文件

我在尝试实现这一点时遇到了很多问题,在编程的这一点上,我只是在创造一些东西来获得编程技能。如果有人有我所描述的功能正常的待办事项列表,我将非常感谢看到一个工作的示例代码。我非常感谢任何帮助

Finished.java



notes_row.xml


新的完成。爪哇

private void fillData() {
    Cursor c = mDbHelper.fetchAllNotes();
    startManagingCursor(c);

    String[] from = new String[] { NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_CHECK };
    int[] to = new int[] { R.id.text1, R.id.CheckBox1 };

    // Now create an array adapter and set it to display using our row
    final SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);



    notes.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
            int nCheckedIndex = cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_CHECK);
            if (columnIndex == nCheckedIndex) {
                CheckBox cb = (CheckBox) view;

                boolean bChecked = (cursor.getInt(nCheckedIndex) != 0);
                cb.setChecked(bChecked);

                //call if after setChecked so the listener isn't called there already
                cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        int position = getListView().getPositionForView(buttonView);
                        Cursor c = notes.getCursor();
                        if (c.moveToPosition(position)) {

                            int rowid = c.getInt(c.getColumnIndex(NotesDbAdapter.KEY_ROWID));

                            if (isChecked) {
                                mDbHelper.updateChk(rowid, "1");


                            } else {
                                mDbHelper.updateChk(rowid, "0");

                            }


                        } 
                    }

            });
                return true;
            }
            return false;
        }
    });


    setListAdapter(notes);

  }
Logcat

03-11 10:38:53.486:E/AndroidRuntime(5611):致命异常:main 03-11 10:38:53.486:E/AndroidRuntime(5611):java.lang.NullPointerException 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.AdapterView.getPositionForView(AdapterView.java:581) 03-11 10:38:53.486:E/AndroidRuntime(5611):在com.finished.finished$1.onCheckedChanged(finished.java:167) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.CompoundButton.setChecked(CompoundButton.java:124) 03-11 10:38:53.486:E/AndroidRuntime(5611):在com.finished.finished$1.setViewValue(finished.java:162) 03-11 10:38:53.486:E/AndroidRuntime(5611):位于android.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:126) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.CursorAdapter.getView(CursorAdapter.java:186) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.AbsListView.obtainView(AbsListView.java:1409) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.ListView.makeAndAddView(ListView.java:1745) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.ListView.fillUp(ListView.java:700) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.ListView.correctTooHigh(ListView.java:1367) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.ListView.fillGap(ListView.java:642) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.AbsListView.trackMotionScroll(AbsListView.java:3399) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.AbsListView.onTouchEvent(AbsListView.java:2233) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.widget.ListView.onTouchEvent(ListView.java:3446) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.view.dispatchTouchEvent(view.java:3885)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1691) 03-11 10:38:53.486:E/AndroidRuntime(5611):在com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1125) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.app.Activity.dispatchTouchEvent(Activity.java:2096)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1675) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2194) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.view.ViewRoot.handleMessage(ViewRoot.java:1878) 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.os.Handler.dispatchMessage(Handler.java:99)上 03-11 10:38:53.486:E/AndroidRuntime(5611):在android.os.Looper.loop(Looper.java:123) 03-11 10:38:53.486:E/AndroidRuntime(5611):位于android.app.ActivityThread.main(ActivityThread.java:3683) 03-11 10:38:53.486:E/AndroidRuntime(5611):位于java.lang.reflect.Method.Invokenactive(本机方法) 03-11 10:38:53.486:E/AndroidRuntime(5611):在java.lang.reflect.Method.invoke(Method.java:507) 03-11 10:38:53.486:E/AndroidRuntime(5611):在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 03-11 10:38:53.486:E/AndroidRuntime(5611):位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
03-11 10:38:53.486:E/AndroidRuntime(5611):在dalvik.system.NativeStart.main(本机方法)

首先将
SimpleCursorAdapter
作为类的实例变量。然后将setChk更改为以下内容

public void setChk(View view) {
    int position = getListView().getPositionForView(view);
    Cursor c = notes.getCursor();
    if (c.moveToPosition(position)) {

        int rowid = c.getInt(c.getColumnIndex(NotesDbAdapter.KEY_ROWID)

        //your code
    } 
}
在您的情况下,
OnClickListener
不是最佳选择。单击复选框时,
OnCheckedChangeListener
更好。它还有一个优点,即您不必再次调用
fillData()
方法,如果数据库很大,这可能需要一些时间

编辑: 我修改了ViewBinder的代码,以便在CheckedChangeListener上使用

new SimpleCursorAdapter.ViewBinder() {
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        int nCheckedIndex = cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_CHECK);
        if (columnIndex == nCheckedIndex) {
            CheckBox cb = (CheckBox) view;

            boolean bChecked = (cursor.getInt(nCheckedIndex) != 0);
            cb.setChecked(bChecked);

            //call if after setChecked so the listener isn't called there already
            cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    int position = getListView().getPositionForView(buttonView);
                    Cursor c = notes.getCursor();
                    if (c.moveToPosition(position)) {

                        int rowid = c.getInt(c.getColumnIndex(NotesDbAdapter.KEY_ROWID)

                        if (isChecked) {
                            //TODO update db
                        } else {
                            //TODO update db                           
                        }
                    } 
                }
            return true;
        }

        return false;
    }
});

谢谢你,先生!这很有效,我现在已经把一切都准备好了,但是。。。就像你说的,听着
    import android.content.ContentValues;
    import android.content.Context;
    import android.database.Cursor;
    import android.database.SQLException;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;

public class NotesDbAdapter {

public static final String KEY_TITLE = "title";
public static final String KEY_BODY = "body";
public static final String KEY_ROWID = "_id";
public static final String KEY_CHECK = "check";

private static final String TAG = "NotesDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;

/**
 * Database creation sql statement
 */
private static final String DATABASE_CREATE =
    "create table notes (_id integer primary key autoincrement, "
    + "title text not null, body text not null);";

private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "notes";
private static final int DATABASE_VERSION = 3;


private final Context mCtx;

private static class DatabaseHelper extends SQLiteOpenHelper {

    DatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        db.execSQL(DATABASE_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                + newVersion + ", which will destroy all old data");
        db.execSQL("DROP TABLE IF EXISTS notes");
        onCreate(db);
    }
}

/**
 * Constructor - takes the context to allow the database to be
 * opened/created
 * 
 * @param ctx the Context within which to work
 */
public NotesDbAdapter(Context ctx) {
    this.mCtx = ctx;
}

/**
 * Open the notes database. If it cannot be opened, try to create a new
 * instance of the database. If it cannot be created, throw an exception to
 * signal the failure
 * 
 * @return this (self reference, allowing this to be chained in an
 *         initialization call)
 * @throws SQLException if the database could be neither opened or created
 */
public NotesDbAdapter open() throws SQLException {
    mDbHelper = new DatabaseHelper(mCtx);
    mDb = mDbHelper.getWritableDatabase();
    return this;
}

public void close() {
    mDbHelper.close();
}


/**
 * Create a new note using the title and body provided. If the note is
 * successfully created return the new rowId for that note, otherwise return
 * a -1 to indicate failure.
 * 
 * @param title the title of the note
 * @param body the body of the note
 * @return rowId or -1 if failed
 */
public long createNote(String title, String body, String check) {
    ContentValues initialValues = new ContentValues();
    initialValues.put(KEY_TITLE, title);
    initialValues.put(KEY_BODY, body);
    initialValues.put(KEY_BODY, check);

    return mDb.insert(DATABASE_TABLE, null, initialValues);
}

/**
 * Delete the note with the given rowId
 * 
 * @param rowId id of note to delete
 * @return true if deleted, false otherwise
 */
public boolean deleteNote(long rowId) {

    return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}

/**
 * Return a Cursor over the list of all notes in the database
 * 
 * @return Cursor over all notes
 */
public Cursor fetchAllNotes() {

    return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_TITLE,
            KEY_BODY, KEY_CHECK}, null, null, null, null, null, null);
}

/**
 * Return a Cursor positioned at the note that matches the given rowId
 * 
 * @param rowId id of note to retrieve
 * @return Cursor positioned to matching note, if found
 * @throws SQLException if note could not be found/retrieved
 */
public Cursor fetchNote(long rowId) throws SQLException {

    Cursor mCursor =

        mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
                KEY_TITLE, KEY_BODY, KEY_CHECK}, KEY_ROWID + "=" + rowId, null,
                null, null, null, null);
    if (mCursor != null) {
        mCursor.moveToFirst();
    }
    return mCursor;

}

/**
 * Update the note using the details provided. The note to be updated is
 * specified using the rowId, and it is altered to use the title and body
 * values passed in
 * 
 * @param rowId id of note to update
 * @param title value to set note title to
 * @param body value to set note body to
 * @param check 
 * @return true if the note was successfully updated, false otherwise
 */
public boolean updateNote(long rowId, String title, String body, String check) {
    ContentValues args = new ContentValues();
    args.put(KEY_TITLE, title);
    args.put(KEY_BODY, body);
    args.put(KEY_CHECK, check);

    return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}
private void fillData() {
    Cursor c = mDbHelper.fetchAllNotes();
    startManagingCursor(c);

    String[] from = new String[] { NotesDbAdapter.KEY_TITLE, NotesDbAdapter.KEY_CHECK };
    int[] to = new int[] { R.id.text1, R.id.CheckBox1 };

    // Now create an array adapter and set it to display using our row
    final SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.notes_row, c, from, to);



    notes.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
        public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
            int nCheckedIndex = cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_CHECK);
            if (columnIndex == nCheckedIndex) {
                CheckBox cb = (CheckBox) view;

                boolean bChecked = (cursor.getInt(nCheckedIndex) != 0);
                cb.setChecked(bChecked);

                //call if after setChecked so the listener isn't called there already
                cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                        int position = getListView().getPositionForView(buttonView);
                        Cursor c = notes.getCursor();
                        if (c.moveToPosition(position)) {

                            int rowid = c.getInt(c.getColumnIndex(NotesDbAdapter.KEY_ROWID));

                            if (isChecked) {
                                mDbHelper.updateChk(rowid, "1");


                            } else {
                                mDbHelper.updateChk(rowid, "0");

                            }


                        } 
                    }

            });
                return true;
            }
            return false;
        }
    });


    setListAdapter(notes);

  }
public void setChk(View view) {
    int position = getListView().getPositionForView(view);
    Cursor c = notes.getCursor();
    if (c.moveToPosition(position)) {

        int rowid = c.getInt(c.getColumnIndex(NotesDbAdapter.KEY_ROWID)

        //your code
    } 
}
new SimpleCursorAdapter.ViewBinder() {
    public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
        int nCheckedIndex = cursor.getColumnIndexOrThrow(NotesDbAdapter.KEY_CHECK);
        if (columnIndex == nCheckedIndex) {
            CheckBox cb = (CheckBox) view;

            boolean bChecked = (cursor.getInt(nCheckedIndex) != 0);
            cb.setChecked(bChecked);

            //call if after setChecked so the listener isn't called there already
            cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    int position = getListView().getPositionForView(buttonView);
                    Cursor c = notes.getCursor();
                    if (c.moveToPosition(position)) {

                        int rowid = c.getInt(c.getColumnIndex(NotesDbAdapter.KEY_ROWID)

                        if (isChecked) {
                            //TODO update db
                        } else {
                            //TODO update db                           
                        }
                    } 
                }
            return true;
        }

        return false;
    }
});