changeCursor()不刷新ListView

时间:2017-12-06 20:46:54

标签: android cursor android-sqlite android-cursoradapter sqliteopenhelper

我有一个简单的应用程序来管理学生列表。

在MainActivity中,我们可以将学生添加到列表中。点击添加的ListView项,会打开一个新活动,我们可以在其中编辑学生成绩。

我在自己的列表中使用自定义 CursorAdapter ,并使用自定义 SQLiteOpenHelper 数据库来处理数据库。

开启MainActivity:onResume()我检查数据库是否已更改,如果是,请致电changeCursor()

调试时,似乎设置了DB更改标志,但是对changeCursor()的调用不会使用新数据刷新ListView

示例

  1. 添加Adi,10
  2. 点击列表项 - >新活动 - > grade编辑为20 - >点击按钮
  3. 期待看到Adi,20,仍然看到Adi,10
  4. 这是我的相关代码:

    主要活动:

    public class MainActivity extends AppCompatActivity { 
        private SqlDbHelper mDB;
        private SQLAdapter mAdapter;
    
        @Override
        protected void onResume() {
            super.onResume();
            if(mDB.isDbChanged()) {
                mAdapter.changeCursor(mDB.getAllRows());
            }
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            /* Init fields & needed views */
            mDB = new SqlDbHelper(getApplicationContext());
            mAdapter = new SQLAdapter(getApplicationContext(), mDB.getAllRows(), false);
            final ListView lvStudents = findViewById(R.id.lv_students);
            final EditText etName = findViewById(R.id.et_name);
            final EditText etGrade = findViewById(R.id.et_grade);
    
            /* Listen to ADD BUTTON clicks */
            findViewById(R.id.button_add).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    insertNewRecord(etName.getText().toString(), etGrade.getText().toString());
                    etName.setText("");
                    etGrade.setText("");
                }
            });
    
            /* Set adapter to LV, Listen to list item clicks */
            lvStudents.setAdapter(mAdapter);
            lvStudents.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                    Intent listItemIntent = new Intent(getApplicationContext(), ListItemActivity.class);
    
                    /* Put needed info in the Intent extra */
                    listItemIntent.putExtra(SqlDbHelper.KEY_ID, l);
                    listItemIntent.putExtra(SqlDbHelper.KEY_NAME,
                            ((TextView)view.findViewById(R.id.tv_name)).getText().toString());
                    listItemIntent.putExtra(SqlDbHelper.KEY_GRADE,
                            Integer.parseInt( ((TextView)view
                                    .findViewById(R.id.tv_grade))
                                    .getText().toString() ));
                    startActivity(listItemIntent);
                }
            });
        }
    
        private void insertNewRecord(final String name, final String grade) {
            /* Add the new student to the DB */
            mDB.addStudent(name, gradeInt);
            mAdapter.changeCursor(mDB.getAllRows());
        }
    }
    

    SQLAdapter:

    final class SQLAdapter extends CursorAdapter {
        private LayoutInflater mInflater;
    
        public SQLAdapter(Context context, Cursor c, boolean autoRequery) {
            super(context, c, autoRequery);
            mInflater = LayoutInflater.from(context);
        }
    
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
            return mInflater.inflate(R.layout.lv_line, viewGroup, false);
        }
    
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            final String name = cursor.getString(cursor.getColumnIndex(SqlDbHelper.KEY_NAME));
            final int grade = cursor.getInt(cursor.getColumnIndex(SqlDbHelper.KEY_GRADE));
    
            view.findViewById(R.id.ll_line).setBackgroundColor(Color.RED);
            ((TextView)view.findViewById(R.id.tv_name)).setText(name);
            ((TextView)view.findViewById(R.id.tv_grade)).setText(String.valueOf(grade));
        }
    
    }
    

    SqlDbHelper:

    final class SqlDbHelper extends SQLiteOpenHelper {
        // some static string variables //
    
        /* Flag indicating DB was changed (by editStudent) -
          * For indication to MainActivity to refresh its list onResume */
        private static boolean mDbChanged;
    
        public SqlDbHelper(Context context) {
            super(context, DB_NAME, null, VERSION);
            mDbChanged = false;
        }
    
        @Override
        public void onCreate(SQLiteDatabase sqLiteDatabase) {
            /* Create sql command to create new table */
            StringBuilder sql = new StringBuilder();
            sql.append("CREATE TABLE " + TABLE_NAME + " (")
                    .append(KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,")
                    .append(KEY_NAME + " TEXT,")
                    .append(KEY_GRADE + " INT")
                    .append(")");
    
            Log.d(TAG, "Query to form table: " + sql.toString());
            sqLiteDatabase.execSQL(sql.toString());
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {}
    
        public void addStudent(final String name, final int grade) {
            ContentValues cv = new ContentValues();
            cv.put(KEY_NAME, name);
            cv.put(KEY_GRADE, grade);
            getWritableDatabase().insert(TABLE_NAME, null, cv);
        }
    
        public void editStudent(final long id, final int grade) throws IllegalArgumentException {
            StringBuilder updateQuery = new StringBuilder();
            updateQuery.append("UPDATE " + TABLE_NAME)
                    .append(" SET " + KEY_GRADE)
                    .append(" = " + grade)
                    .append(" WHERE " + KEY_ID)
                    .append(" = " + id);
    
            Log.d(TAG, "Query to edit: " + updateQuery.toString());
            getWritableDatabase().execSQL(updateQuery.toString());
    
            /* Indicate the change */
            mDbChanged = true;
        }
    
        /**
         * Aid method to get all rows in the DB
         * @return Cursor pointing to the start of all rows
         */
        public Cursor getAllRows() {
            /* Turn change flag off, if method was called in order
            * to refresh the main listview onResume */
            if(mDbChanged) {
                mDbChanged = false;
            }
    
            return getReadableDatabase().
                    rawQuery("SELECT * FROM " + TABLE_NAME, null);
        }
    
        public boolean isDbChanged() {
            return mDbChanged;
        }
    }
    

    ListItemActivity:

    public class ListItemActivity extends AppCompatActivity {
        private Intent mIntent;
        private Button mButtonEdit;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_list_item);
    
            /* Get needed params for the view */
            mIntent = getIntent();
            mButtonEdit = findViewById(R.id.button_item_edit);
            EditText etGrade = findViewById(R.id.et_item_grade);
    
            /* Set the Student's Name & Grade */
            final int grade = mIntent.getIntExtra(KEY_GRADE, -1);
    
            ((TextView)findViewById(R.id.tv_item_name)).
                    setText(mIntent.getStringExtra(KEY_NAME));
            etGrade.setText(String.valueOf(grade));
    
            /* Set on click listener for the edit button */
            mButtonEdit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    SqlDbHelper db = new SqlDbHelper(getApplicationContext());
                    db.editStudent(mIntent.getLongExtra(KEY_ID, -1), grade);
                }
            });
        }
    }
    

1 个答案:

答案 0 :(得分:0)

问题发生在ListItemActivity方法的mButton onClick()中。

我没有使用在EditText框中输入的新成绩更新数据库,而是使用了一个旧的grade变量,该变量保存了onCreate()中获得的成绩的旧值。

花了一些时间来弄明白,这是因为这个活动的屏幕等级确实改变了新的等级,尽管db更新了旧的等级。

<强>解决方案:

LastItemActivity::onClick,更改

db.editStudent(mIntent.getLongExtra(KEY_ID, -1), grade);

<强>

db.editStudent(mIntent.getLongExtra(KEY_ID, -1), Integer.parseInt(etGrade.getText().toString()))