android - 会在ListView中选择错误的item位置吗?
问题描述
我正在尝试按照这个示例实现一个搜索功能,通过关键字在 SQLite 数据库中搜索。这是我的代码:
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
<activity android:name=".AddCarActivity">
</activity>
<activity android:name=".ViewActivity">
</activity>
</application>
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var cars: ListView
lateinit var car_adapter: CarAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
cars = findViewById(R.id.cars)
val add: FloatingActionButton = findViewById(R.id.add)
add.setOnClickListener {
startActivityForResult(Intent(this, AddCarActivity::class.java), 1000)
}
cars.onItemClickListener = AdapterView.OnItemClickListener { _, _, i, _ ->
val cursor = CarDatabase(this).getCarList()
cursor.moveToPosition(i)
val intent = Intent(this, ViewActivity::class.java)
intent.putExtra("car", cursor.getString(1))
startActivity(intent)
}
getCars()
}
fun getCars() {
car_adapter = CarAdapter(this, CarDatabase(this).getCarList())
cars.adapter = car_adapter
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu, menu)
val manager: SearchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
val search = menu!!.findItem(R.id.search).actionView as SearchView
search.setSearchableInfo(manager.getSearchableInfo(componentName))
val context: Context = this
search.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
if (query!!.isNotEmpty()) {
val cursor: Cursor = CarDatabase(context).getCarListByKeyword(query)!!
Toast.makeText(context, "${cursor.count} record(s) found!", Toast.LENGTH_LONG).show()
car_adapter.swapCursor(cursor)
}
return false
}
override fun onQueryTextChange(newText: String?): Boolean {
if (newText!!.isNotEmpty()) {
val cursor: Cursor = CarDatabase(context).getCarListByKeyword(newText)!!
car_adapter.swapCursor(cursor)
} else
getCars()
return false
}
})
return true
}
}
AddCarActivity.kt
class AddCarActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_add_car)
val add: ImageButton = findViewById(R.id.add_car)
add.setOnClickListener {
val car: EditText = findViewById(R.id.car_et)
if (CarDatabase(this).addCar(car.text.toString())) {
Toast.makeText(this, "Car added!", Toast.LENGTH_SHORT).show()
setResult(1000)
finish()
} else
Toast.makeText(this, "Please try again!", Toast.LENGTH_SHORT).show()
}
}
}
视图活动.kt
class ViewActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view)
val car: TextView = findViewById(R.id.car_v)
car.text = intent.getStringExtra("car")
}
}
汽车适配器.kt
class CarAdapter(context: Context, cursor: Cursor?) :
CursorAdapter(context, cursor, 0) {
private var mInflater: LayoutInflater? = null
override fun newView(context: Context, cursor: Cursor, parent: ViewGroup): View {
val view = mInflater!!.inflate(R.layout.cars_list, parent, false)
val holder = ViewHolder()
holder.car = view.findViewById(R.id.car)
view.tag = holder
return view
}
override fun bindView(view: View, context: Context, cursor: Cursor) {
val holder = view.tag as ViewHolder
holder.car!!.text = cursor.getString(cursor.getColumnIndex(CarDatabase.CAR))
}
internal class ViewHolder {
var car: TextView? = null
}
init {
mInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
}
}
汽车数据库.kt
class CarDatabase(context: Context) : SQLiteOpenHelper(context, NAME, null, VERSION) {
companion object {
const val NAME = "Cars.db"
const val VERSION = 1
const val TABLE = "Cars"
const val ID = "_id"
const val CAR = "Car"
}
private var db: SQLiteDatabase = this.writableDatabase
override fun onCreate(db: SQLiteDatabase) {
db.execSQL("CREATE TABLE $TABLE ($ID INTEGER PRIMARY KEY AUTOINCREMENT, $CAR TEXT);")
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DROP TABLE IF EXISTS $TABLE")
onCreate(db)
}
fun getCarList(): Cursor {
val cursor = db.rawQuery("SELECT * FROM $TABLE", null)
if (!cursor.moveToFirst())
cursor.close()
return cursor
}
fun addCar(car: String): Boolean {
val values = ContentValues()
values.put(CAR, car)
return db.insert(TABLE, null, values) > 0
}
fun getCarListByKeyword(search: String): Cursor? {
val cursor = db.rawQuery("SELECT rowid as $ID, $CAR FROM $TABLE WHERE $CAR LIKE '%$search%'", null)
if (cursor == null) {
return null
} else if (!cursor.moveToFirst()) {
cursor.close()
return null
}
return cursor
}
}
这是我在这样的测试设备上执行应用程序后创建的示例 列表。此示例应用程序执行以下操作:通过单击一个项目打开 View 活动并像这样显示所选项目。例如,通过选择奥迪,您将看到奥迪。
问题出在搜索功能上。例如,如果我搜索Mercedes Benz然后点击它,在 ViewActivity 中出现Audi like this。或者Toyota -> Mercedes Benz或Audi Q5 -> Lexus等。搜索后似乎在ListView中会选择错误的位置。我怎么解决这个问题?如果我无法解释清楚,请告诉我。
解决方案
似乎即使您将数据库光标交换为适配器中的搜索视图,您也不会使用它来实际从数据库中获取项目:(在您的 onItemClickListener 中)
val cursor = CarDatabase(this).getCarList()
cursor.moveToPosition(i)
您应该从适配器而不是 CarDatabase(this).getCarList() 获取当前光标,然后使用它,即
val cursor = car_adapter.cursor
cursor.moveToPosition(i)
希望能帮助到你。干杯。
推荐阅读
- c++ - &NAME->FIELD 是什么意思,当 NAME - 结构上的指针,用 typedef 创建时?
- google-bigquery - 是否可以在 Big Query 的计划查询中调用程序?
- python - 如何遍历多个不同的 text/conf 文件寻找相似之处并向输出文件添加额外信息?
- c++ - C++:如何将 std::string 的内容写入 UTF-8 编码文件?
- java - 在 JavaFX 中隐藏拖放半透明预览
- python-3.x - 我的 matplotlib 绘图工作太慢,有没有办法提高效率?
- windows - 有没有办法在 Windows 命令行中一次性使用命令/操作?例如。输入许可证密钥
- excel - VBA焦点传递
- python - Locust 将请求和响应正文导出到 csv 文件
- javascript - 为什么我来自 BehivourSubject 的消息会重复每条新收到的消息?