在我的 ListView 中选择项目后,滚动 Kotlin 时随机选择其他项目
After items selection in my ListView other items get randomly selected while scrolling Kotlin
我是新手。滚动我的 ListView 后,"same position" 中的项目作为我在自动选择之前选择的项目。 (相同的位置我指的是屏幕中的位置而不是数据库中的位置。)我以前遇到过这个问题,因为我是通过 OnItemClickListener 中 ListView 的索引来选择项目的。但是我又遇到了这个问题,尽管我认为我的做法是正确的。
当我单击 ListView 中的项目时,我获得了它的唯一 ID,并基于此将此项目(数据库中此行的)的 SELECTED 值更改为 0 或 1(取决于它是否被单击或不是)。之后,我将背景颜色切换为灰色(或返回白色)。这是在区分 SELECTED 属性.
的 CursorAdapter 中处理的
这是我的代码。
OnCreate 在 MainActivity.kt
val dbHelper = DBHelper(this)
val db = dbHelper.writableDatabase
val myCursor = db.rawQuery("SELECT * FROM ${ContractClass.FeedReaderContract.TABLE_NAME}", null)
val myAdapter = CursorAdapter(this, myCursor)
myListView.adapter = myAdapter
myListView.setOnItemClickListener { _, view, _, _ ->
val text = view.txtName.text
val select = "${ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD} MATCH ?"
val selectCursor = db.query(
ContractClass.FeedReaderContract.TABLE_NAME, // The table to query
null, // The array of columns to return (pass null to get all)
select, // The columns for the WHERE clause
arrayOf("$text"), // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
)
with(selectCursor) {
while (moveToNext()) {
val itemSel = getInt(getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED))
if (itemSel == 1){
val values = ContentValues().apply {
put(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED, 0)
}
val count = db.update(
ContractClass.FeedReaderContract.TABLE_NAME, values, select, arrayOf("$text"))
}else{
val values = ContentValues().apply {
put(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED, 1)
}
val count = db.update(
ContractClass.FeedReaderContract.TABLE_NAME, values, select, arrayOf("$text"))
}
}
}
}
CursorAdapter.kt
class CursorAdapter(context: Context, cursor: Cursor) : CursorAdapter(context, cursor, 0) {
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
if (cursor.getInt(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)) == 0){
return LayoutInflater.from(context).inflate(R.layout.row_list_row, parent, false)
}else{
return LayoutInflater.from(context).inflate(R.layout.user_list_row_selected, parent, false)
}
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
override fun bindView(view: View, context: Context, cursor: Cursor) {
// Find fields to populate in inflated template
val tvBody = view.findViewById<View>(R.id.txtName) as TextView
val tvPriority = view.findViewById<View>(R.id.txtComment) as TextView
val tvPriority2 = view.findViewById<View>(R.id.txtThird) as TextView
val tvPriority3 = view.findViewById<View>(R.id.txtThi) as TextView
// Extract properties from cursor
val body = cursor.getString(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD))
val priority = cursor.getString(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_DEFN))
val priority2 = cursor.getInt(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract._id))
val priority3 = cursor.getInt(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED))
// Populate fields with extracted properties
tvBody.text = body
tvPriority.text = priority.toString()
tvPriority2.text = priority2.toString()
tvPriority3.text = priority3.toString()
}
}
数据库Table创建
private val SQL_CREATE_ENTRIES =
"CREATE VIRTUAL TABLE ${ContractClass.FeedReaderContract.TABLE_NAME} USING fts4(" +
"${ContractClass.FeedReaderContract._id}," +
"${ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD} TEXT," +
"${ContractClass.FeedReaderContract.COLUMN_NAME_DEFN} TEXT," +
"${ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED} INTEGER)"
我在这里找到了类似的 post:List view with simple cursor adapter items checked are un-checked during scroll
但我认为,他们建议我已经做过的事情。
感谢您的帮助。
如果您想使用多种不同的视图类型,您需要覆盖 getItemViewType(position)
。如果你不这样做,那么适配器就无法知道它作为 convertView
传递的 View
实例是否是正确的类型,你最终会得到严重回收的视图。
这对于 CursorAdapter
来说似乎不是微不足道的(我没有任何经验)。我认为正确的做法应该是这样的:
override fun getItemViewType(position: Int): Int {
cursor.moveToPosition(position)
val columnIndex = cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)
return when (cursor.getInt(columnIndex)) {
0 -> 0
else -> 1
}
}
我还认为您应该更改 newView()
以利用这些类型。保留现有的 应该 工作,但它会是重复的代码。
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
val layoutId = when (val type = getItemViewType(cursor.position)) {
0 -> R.layout.row_list_row
1 -> R.layout.user_list_row_selected
else -> throw IllegalStateException("unexpected viewType: $type")
}
return LayoutInflater.from(context).inflate(layoutId, parent, false)
}
在更改 to/updated 基础数据后,您似乎没有更改 ListView 的 Cursor。
尝试在对基础数据进行更改后,通过
更新 ListView 的 Cursor
- 重新查询数据然后
- 使用适配器的
swapCursor(myCursor)
(或 notiftDatasetChanged()
方法)
这是您的应用程序的等价物,但在 Java 而不是 Kotlin 中(没有任何运气转换,因为我几乎从不使用 Kotlin)。
我相信这可以满足您的要求。也就是说,
如果您 select 未被 select 编辑的行,那么所有包含 enword 的行都会被 select 编辑并变灰,并且 select ed 列值设置为 1。
如果您 select 一个 selected(灰色)行,那么那些包含 enword 的行将被 de-selected 并变为白色selected 列值被改回 0
请注意,我没有创建 FTS table,而是模仿了 FTS 并使用 LIKE 而不是 MATCH。
如果 selected 背景为灰色,则切换为白色。例如最初是:-
如果单击猫(第 2 行),则所有其他猫行也会根据 :-
切换并变灰
等等。
代码
MainActivity(我在转换时遇到问题的文件)
public class MainActivity extends AppCompatActivity {
DBHelper dbhelper;
ListView myListView;
MyCursorAdapter myAdapter;
Cursor mCursor;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myListView = this.findViewById(R.id.myListView);
dbhelper = new DBHelper(this);
addSomeTestingData();
manageListView();
}
private void manageListView() {
mCursor = dbhelper.getAllRows();
if (myAdapter == null) {
myAdapter = new MyCursorAdapter(this,mCursor);
myListView.setAdapter(myAdapter);
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dbhelper.updateSelected(mCursor.getString(mCursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD)));
manageListView();
}
});
} else {
myAdapter.swapCursor(mCursor);
}
}
private void addSomeTestingData() {
if (DatabaseUtils.queryNumEntries(dbhelper.getWritableDatabase(),ContractClass.FeedReaderContract.TABLENAME) > 1) return;
for (int i=0; i < 10; i++) {
dbhelper.addRow("Apple", "Thing that falls from trees");
dbhelper.addRow("Cat", "Something that is furry and sits on mats");
dbhelper.addRow("Bear", "Something that is furry that eats honey but doesn't ssit on a mat");
dbhelper.addRow("Dog", "Something is furry and friendly");
dbhelper.addRow("Echida", "An upside down hedgehog");
dbhelper.addRow("Ferret", "Something that is furry and found up trouser legs");
dbhelper.addRow("Giraffe", "Something that has 5 legs one pointing up");
dbhelper.addRow("Hippo", "An animal that loves mud and water but not humans");
dbhelper.addRow("Ibis", "A white feathered flying thing");
dbhelper.addRow("Jaguar", "A car or a large black cat");
dbhelper.addRow("Kangaroo", "A marsupial that boxes, skips and has a puch for shopping trips");
dbhelper.addRow("Lizard", "A rock dweller");
dbhelper.addRow("Mammoth", "A big hairy elephant now extinct");
dbhelper.addRow("Nuthatch", "A small bird that does not customise nuts so they have hatches.");
dbhelper.addRow("Ostrich", "A l argefast running bird that does not fly");
dbhelper.addRow("Panther", "A skinny pink cat that walks on only two of it's four lehs");
dbhelper.addRow("Queen", "A female rule of a country");
dbhelper.addRow("Rhinocerous", "A Hippo like animal that has a name that is hard to spell");
dbhelper.addRow("Tiger", "A live verion of Winnie the Pooh's friend Tigger");
dbhelper.addRow("Stork", "A skinny ostrich that flies and delivers children through Dream World.");
}
}
}
显然 addSomeTestingData 方法就是为了这个。
请注意,几乎没有任何其他代码。数据库访问已全部移至 DBHelper class.
关键是manageListView方法
- 首先填充适配器使用的游标。
- 适配器尚未实例化,因此实例化为 null,然后绑定到 ListView。
- 添加了 OnItemClickListener 注意它会在数据库更新后调用 manageListView 方法。
- 如果适配器已被实例化,则调用 swapCursor 方法,告诉适配器底层游标已更改。
DBHelper.java
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(@Nullable Context context) {
super(context, ContractClass.DBNAME,null,ContractClass.DBVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(ContractClass.FeedReaderContract.CRTSQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public Cursor getAllRows() {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(ContractClass.FeedReaderContract.TABLENAME,null,null,null,null,null,null);
}
public void updateSelected(String selected) {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("UPDATE "
+ ContractClass.FeedReaderContract.TABLENAME
+ " SET " + ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED
+ "= CASE " + ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED +
" WHEN 1 THEN 0 ELSE 1 END " +
" WHERE " + ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD + " LIKE ?",
new String[]{selected}
);
}
public long addRow(String enWord, String definition) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD,enWord);
cv.put(ContractClass.FeedReaderContract.COLUMN_NAME_DEFN,definition);
return db.insert(ContractClass.FeedReaderContract.TABLENAME,null,cv);
}
}
- 选择所有行已移至此处作为 getAllRows 方法
- addRow只是允许添加一些测试数据。
- updateSelected 方法不是将行提取到 Cursor 中,而是使用 CASE WHEN ELSE END 子句切换值来驱动更新,应该更有效。
- 请注意,不是 MATCH,因为 MATCH 是 FTS 特定的(我相信)LIKE 已被用作基础 table 不是 FTS table。 您将使用 MATCH
MyCursorAdapter.java
public class MyCursorAdapter extends CursorAdapter {
public MyCursorAdapter(Context context, Cursor c) {
super(context, c, false);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.row_list_row,parent,false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
if (cursor.getInt(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)) < 1) {
view.setBackgroundColor(0xFFF9F9F9);
} else {
view.setBackgroundColor(0xFFD9D9D9);
}
TextView tvBody = view.findViewById(R.id.txtName);
TextView tvPriority = view.findViewById(R.id.txtComment);
TextView tvPriority2 = view.findViewById(R.id.txtThird);
TextView tvPriority3 = view.findViewById(R.id.txtThi);
tvBody.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD)));
tvPriority.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_DEFN)));
tvPriority2.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract._id)));
tvPriority3.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)));
}
}
- 主要区别在于视图的背景是在 bindView 方法中更改的,而不是在 newView 方法中更改布局。
我是新手。滚动我的 ListView 后,"same position" 中的项目作为我在自动选择之前选择的项目。 (相同的位置我指的是屏幕中的位置而不是数据库中的位置。)我以前遇到过这个问题,因为我是通过 OnItemClickListener 中 ListView 的索引来选择项目的。但是我又遇到了这个问题,尽管我认为我的做法是正确的。
当我单击 ListView 中的项目时,我获得了它的唯一 ID,并基于此将此项目(数据库中此行的)的 SELECTED 值更改为 0 或 1(取决于它是否被单击或不是)。之后,我将背景颜色切换为灰色(或返回白色)。这是在区分 SELECTED 属性.
的 CursorAdapter 中处理的这是我的代码。
OnCreate 在 MainActivity.kt
val dbHelper = DBHelper(this)
val db = dbHelper.writableDatabase
val myCursor = db.rawQuery("SELECT * FROM ${ContractClass.FeedReaderContract.TABLE_NAME}", null)
val myAdapter = CursorAdapter(this, myCursor)
myListView.adapter = myAdapter
myListView.setOnItemClickListener { _, view, _, _ ->
val text = view.txtName.text
val select = "${ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD} MATCH ?"
val selectCursor = db.query(
ContractClass.FeedReaderContract.TABLE_NAME, // The table to query
null, // The array of columns to return (pass null to get all)
select, // The columns for the WHERE clause
arrayOf("$text"), // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
null // The sort order
)
with(selectCursor) {
while (moveToNext()) {
val itemSel = getInt(getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED))
if (itemSel == 1){
val values = ContentValues().apply {
put(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED, 0)
}
val count = db.update(
ContractClass.FeedReaderContract.TABLE_NAME, values, select, arrayOf("$text"))
}else{
val values = ContentValues().apply {
put(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED, 1)
}
val count = db.update(
ContractClass.FeedReaderContract.TABLE_NAME, values, select, arrayOf("$text"))
}
}
}
}
CursorAdapter.kt
class CursorAdapter(context: Context, cursor: Cursor) : CursorAdapter(context, cursor, 0) {
// The newView method is used to inflate a new view and return it,
// you don't bind any data to the view at this point.
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
if (cursor.getInt(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)) == 0){
return LayoutInflater.from(context).inflate(R.layout.row_list_row, parent, false)
}else{
return LayoutInflater.from(context).inflate(R.layout.user_list_row_selected, parent, false)
}
}
// The bindView method is used to bind all data to a given view
// such as setting the text on a TextView.
override fun bindView(view: View, context: Context, cursor: Cursor) {
// Find fields to populate in inflated template
val tvBody = view.findViewById<View>(R.id.txtName) as TextView
val tvPriority = view.findViewById<View>(R.id.txtComment) as TextView
val tvPriority2 = view.findViewById<View>(R.id.txtThird) as TextView
val tvPriority3 = view.findViewById<View>(R.id.txtThi) as TextView
// Extract properties from cursor
val body = cursor.getString(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD))
val priority = cursor.getString(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_DEFN))
val priority2 = cursor.getInt(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract._id))
val priority3 = cursor.getInt(cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED))
// Populate fields with extracted properties
tvBody.text = body
tvPriority.text = priority.toString()
tvPriority2.text = priority2.toString()
tvPriority3.text = priority3.toString()
}
}
数据库Table创建
private val SQL_CREATE_ENTRIES =
"CREATE VIRTUAL TABLE ${ContractClass.FeedReaderContract.TABLE_NAME} USING fts4(" +
"${ContractClass.FeedReaderContract._id}," +
"${ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD} TEXT," +
"${ContractClass.FeedReaderContract.COLUMN_NAME_DEFN} TEXT," +
"${ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED} INTEGER)"
我在这里找到了类似的 post:List view with simple cursor adapter items checked are un-checked during scroll 但我认为,他们建议我已经做过的事情。
感谢您的帮助。
如果您想使用多种不同的视图类型,您需要覆盖 getItemViewType(position)
。如果你不这样做,那么适配器就无法知道它作为 convertView
传递的 View
实例是否是正确的类型,你最终会得到严重回收的视图。
这对于 CursorAdapter
来说似乎不是微不足道的(我没有任何经验)。我认为正确的做法应该是这样的:
override fun getItemViewType(position: Int): Int {
cursor.moveToPosition(position)
val columnIndex = cursor.getColumnIndexOrThrow(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)
return when (cursor.getInt(columnIndex)) {
0 -> 0
else -> 1
}
}
我还认为您应该更改 newView()
以利用这些类型。保留现有的 应该 工作,但它会是重复的代码。
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
val layoutId = when (val type = getItemViewType(cursor.position)) {
0 -> R.layout.row_list_row
1 -> R.layout.user_list_row_selected
else -> throw IllegalStateException("unexpected viewType: $type")
}
return LayoutInflater.from(context).inflate(layoutId, parent, false)
}
在更改 to/updated 基础数据后,您似乎没有更改 ListView 的 Cursor。
尝试在对基础数据进行更改后,通过
更新 ListView 的 Cursor- 重新查询数据然后
- 使用适配器的
swapCursor(myCursor)
(或notiftDatasetChanged()
方法)
这是您的应用程序的等价物,但在 Java 而不是 Kotlin 中(没有任何运气转换,因为我几乎从不使用 Kotlin)。
我相信这可以满足您的要求。也就是说,
如果您 select 未被 select 编辑的行,那么所有包含 enword 的行都会被 select 编辑并变灰,并且 select ed 列值设置为 1。
如果您 select 一个 selected(灰色)行,那么那些包含 enword 的行将被 de-selected 并变为白色selected 列值被改回 0
请注意,我没有创建 FTS table,而是模仿了 FTS 并使用 LIKE 而不是 MATCH。
如果 selected 背景为灰色,则切换为白色。例如最初是:-
如果单击猫(第 2 行),则所有其他猫行也会根据 :-
切换并变灰等等。
代码
MainActivity(我在转换时遇到问题的文件)
public class MainActivity extends AppCompatActivity {
DBHelper dbhelper;
ListView myListView;
MyCursorAdapter myAdapter;
Cursor mCursor;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myListView = this.findViewById(R.id.myListView);
dbhelper = new DBHelper(this);
addSomeTestingData();
manageListView();
}
private void manageListView() {
mCursor = dbhelper.getAllRows();
if (myAdapter == null) {
myAdapter = new MyCursorAdapter(this,mCursor);
myListView.setAdapter(myAdapter);
myListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dbhelper.updateSelected(mCursor.getString(mCursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD)));
manageListView();
}
});
} else {
myAdapter.swapCursor(mCursor);
}
}
private void addSomeTestingData() {
if (DatabaseUtils.queryNumEntries(dbhelper.getWritableDatabase(),ContractClass.FeedReaderContract.TABLENAME) > 1) return;
for (int i=0; i < 10; i++) {
dbhelper.addRow("Apple", "Thing that falls from trees");
dbhelper.addRow("Cat", "Something that is furry and sits on mats");
dbhelper.addRow("Bear", "Something that is furry that eats honey but doesn't ssit on a mat");
dbhelper.addRow("Dog", "Something is furry and friendly");
dbhelper.addRow("Echida", "An upside down hedgehog");
dbhelper.addRow("Ferret", "Something that is furry and found up trouser legs");
dbhelper.addRow("Giraffe", "Something that has 5 legs one pointing up");
dbhelper.addRow("Hippo", "An animal that loves mud and water but not humans");
dbhelper.addRow("Ibis", "A white feathered flying thing");
dbhelper.addRow("Jaguar", "A car or a large black cat");
dbhelper.addRow("Kangaroo", "A marsupial that boxes, skips and has a puch for shopping trips");
dbhelper.addRow("Lizard", "A rock dweller");
dbhelper.addRow("Mammoth", "A big hairy elephant now extinct");
dbhelper.addRow("Nuthatch", "A small bird that does not customise nuts so they have hatches.");
dbhelper.addRow("Ostrich", "A l argefast running bird that does not fly");
dbhelper.addRow("Panther", "A skinny pink cat that walks on only two of it's four lehs");
dbhelper.addRow("Queen", "A female rule of a country");
dbhelper.addRow("Rhinocerous", "A Hippo like animal that has a name that is hard to spell");
dbhelper.addRow("Tiger", "A live verion of Winnie the Pooh's friend Tigger");
dbhelper.addRow("Stork", "A skinny ostrich that flies and delivers children through Dream World.");
}
}
}
显然 addSomeTestingData 方法就是为了这个。
请注意,几乎没有任何其他代码。数据库访问已全部移至 DBHelper class.
关键是manageListView方法
- 首先填充适配器使用的游标。
- 适配器尚未实例化,因此实例化为 null,然后绑定到 ListView。
- 添加了 OnItemClickListener 注意它会在数据库更新后调用 manageListView 方法。
- 如果适配器已被实例化,则调用 swapCursor 方法,告诉适配器底层游标已更改。
DBHelper.java
public class DBHelper extends SQLiteOpenHelper {
public DBHelper(@Nullable Context context) {
super(context, ContractClass.DBNAME,null,ContractClass.DBVERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(ContractClass.FeedReaderContract.CRTSQL);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public Cursor getAllRows() {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(ContractClass.FeedReaderContract.TABLENAME,null,null,null,null,null,null);
}
public void updateSelected(String selected) {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("UPDATE "
+ ContractClass.FeedReaderContract.TABLENAME
+ " SET " + ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED
+ "= CASE " + ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED +
" WHEN 1 THEN 0 ELSE 1 END " +
" WHERE " + ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD + " LIKE ?",
new String[]{selected}
);
}
public long addRow(String enWord, String definition) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD,enWord);
cv.put(ContractClass.FeedReaderContract.COLUMN_NAME_DEFN,definition);
return db.insert(ContractClass.FeedReaderContract.TABLENAME,null,cv);
}
}
- 选择所有行已移至此处作为 getAllRows 方法
- addRow只是允许添加一些测试数据。
- updateSelected 方法不是将行提取到 Cursor 中,而是使用 CASE WHEN ELSE END 子句切换值来驱动更新,应该更有效。
- 请注意,不是 MATCH,因为 MATCH 是 FTS 特定的(我相信)LIKE 已被用作基础 table 不是 FTS table。 您将使用 MATCH
MyCursorAdapter.java
public class MyCursorAdapter extends CursorAdapter {
public MyCursorAdapter(Context context, Cursor c) {
super(context, c, false);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.row_list_row,parent,false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
if (cursor.getInt(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)) < 1) {
view.setBackgroundColor(0xFFF9F9F9);
} else {
view.setBackgroundColor(0xFFD9D9D9);
}
TextView tvBody = view.findViewById(R.id.txtName);
TextView tvPriority = view.findViewById(R.id.txtComment);
TextView tvPriority2 = view.findViewById(R.id.txtThird);
TextView tvPriority3 = view.findViewById(R.id.txtThi);
tvBody.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_ENWORD)));
tvPriority.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_DEFN)));
tvPriority2.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract._id)));
tvPriority3.setText(cursor.getString(cursor.getColumnIndex(ContractClass.FeedReaderContract.COLUMN_NAME_SELECTED)));
}
}
- 主要区别在于视图的背景是在 bindView 方法中更改的,而不是在 newView 方法中更改布局。