【问题标题】:Populating Listview from Database Only Works Once从数据库中填充 Listview 只能工作一次
【发布时间】:2015-08-17 14:45:22
【问题描述】:

我正在尝试将包含用户条目的列表视图更新为两个文本输入。单击保存按钮后,应显示用户的条目。根据我的代码,第一次填写两个文本输入并点击保存时,列表视图会更新,但第二次点击保存时,列表视图不会更新。这是我的代码:

Home.java

public class Home extends AppCompatActivity implements AdapterView.OnItemSelectedListener {

EditText inputOne;
EditText inputTwo;
MyDBHandler dbHandler; 
Button saveButton; 
MyCursorAdapter cursorAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    inputOne = (EditText) findViewById(R.id.inputOne);
    inputTwo = (EditText) findViewById(R.id.inputTwo);
    dbHandler = new MyDBHandler(this, null, null, 1);
    saveButton = (Button) findViewById(R.id.saveButton);

    MyDBHandler myDBHandler = new MyDBHandler(this);
    Cursor c = myDBHandler.getCursor();
    cursorAdapter = new MyCursorAdapter(this,c,1);
    ListView notes = (ListView) findViewById(R.id.notes);
    notes.setAdapter(cursorAdapter);


public void saveClicked(View view) {
    Test test = new Test( inputOne.getText().toString(), inputTwo.getText().toString() );
    dbHandler.addTest(test);
    inputOne.setText("");
    inputTwo.setText("");

    cursorAdapter.notifyDataSetChanged();

}

MyDBHandler.java

public class MyDBHandler extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "Database.db";
public static final String TABLE_TEST = "test";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_ONE = "one";
public static final String COLUMN_TWO = "two";

public MyDBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
    super(context, DATABASE_NAME, factory, DATABASE_VERSION);
}

public void onCreate(SQLiteDatabase db) {
    String query = "CREATE TABLE " + TABLE_TEST + "(" +
            COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
            COLUMN_ONE + " TEXT," +
            COLUMN_TWO + " TEXT" + ");";
    db.execSQL(query);
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS " + TABLE_TEST);
    onCreate(db);
}

public void addTest(Test test){
    ContentValues values = new ContentValues();
    values.put(COLUMN_ONE, test.get_one());
    values.put(COLUMN_TWO, test.get_two());
    SQLiteDatabase db = getWritableDatabase();
    db.insert(TABLE_TEST, null, values);
    db.close();
}

public Cursor getCursor(){
    SQLiteDatabase db = getWritableDatabase();
    String query = "SELECT * FROM " + TABLE_ACTIVITIES + " WHERE 1";

    Cursor c = db.rawQuery(query, null);

    return c;

}

}

MyCursorAdapter.java

public class MyCursorAdapter extends CursorAdapter {

public MyCursorAdapter(Context context, Cursor c, int flags) {
    super(context, c, 1);
}

@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
    return LayoutInflater.from(context).inflate(R.layout.custom_row, parent, false);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    TextView one = (TextView) view.findViewById(R.id.one);
    TextView two = (TextView) view.findViewById(R.id.two);

    String one_string = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.COLUMN_ONE));
    one.setText(one_string);

    String two_string  = cursor.getString(cursor.getColumnIndexOrThrow(MyDBHandler.COLUMN_TWO));
    two.setText(two_string);

}

}

Test.java

public class Test {

private int _id;
private String _one;
private String _two;

public Test(){

}

public Test(int id){
    this._id = id;
}

public Test(String one, String two){
    this._one = one;
    this._two = two;
}

public int get_id() {
    return _id;
}

public void set_id(int _id) {
    this._id = _id;
}

public String get_one() {
    return _one;
}

public void set_one(String _one) {
    this._one = _one;
}

public String get_two() {
    return _two;
}

public void set_two(String _two) {
    this._two = _two;
}

【问题讨论】:

  • 为什么要重新创建适配器并调用 refreshDrawableState()?如果基础数据发生更改,您只需要调用 notifyDatasetChanged()。
  • 如果我不重新创建它,我会收到一条错误消息,指出它无法解析符号 cursorAdapter。
  • 那是因为作用域——你将它创建为一个局部变量。尝试将其声明为类的实例字段。 (在任何方法之外,就在类内部),然后在您拥有数据时对其进行初始化。
  • 我收到一条错误消息,说我的应用由于某种原因停止了。我将更新我的代码并显示 logcat。
  • 保持 instantiation 正常工作,只需将适配器声明为类字段,然后在更新数据库时引用它。不要立即初始化所有内容。

标签: android listview android-listview


【解决方案1】:

刷新由 Cursor 支持的 ListView 的正确方法是调用 cursorAdapter.notifyDatasetChanged(),而无需重新创建和重置适配器。

因此,在您的 saveClicked 方法中,您只需更新数据库并让适配器知道发生了变化。

为此,您需要将对适配器的引用保留为实例字段,而不是将其声明为局部变量。

【讨论】:

    【解决方案2】:

    原来我的 ListView 正在填充,但我犯了将 ListView 放入 ScrollView 的错误 - 所以我无法看到添加的条目。一旦我使用了这个解决方案,它就起作用了:Android - ListView's height just fits 1 ListView item

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      • 2017-11-13
      • 2012-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多