Будет ли выбрана неправильная позиция элемента в ListView? - PullRequest
0 голосов
/ 04 ноября 2018

Я пытаюсь реализовать функцию поиска для поиска в базе данных 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()
        }
    }
}

ViewActivity.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")
    }
}

CarAdapter.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?
    }
}

CarDatabase.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
    }
}

Вот мой список примеров, который я создал после выполнения приложения на тестовом устройстве вот так . В этом примере приложения выполняется следующее: При нажатии на элемент открывается действие «Просмотр» и появляется выбранный элемент , например . Например, выбрав Audi, вы увидите Audi.

Проблема в функции поиска. Например, если я ищу Mercedes Benz и затем нажимаю на него, в ViewActivity появляется Audi , например, . Или Toyota -> Mercedes Benz или Audi Q5 -> Lexus и т. Д. Кажется, после поиска будут выбраны неправильные позиции в ListView . Как я могу решить эту проблему? Пожалуйста, дайте мне знать, если я не могу объяснить что-то по понятным причинам.

1 Ответ

0 голосов
/ 05 ноября 2018

Кажется, что даже если вы меняете курсор БД для представления поиска в своем адаптере, вы не используете его для фактического получения элемента из вашей базы данных: (в вашем onItemClickListener)

val cursor = CarDatabase(this).getCarList()
cursor.moveToPosition(i)

Вы должны получить текущий курсор из адаптера вместо CarDatabase (this) .getCarList () и затем использовать его, т.е.

val cursor = car_adapter.cursor
cursor.moveToPosition(i)

Надеюсь, это поможет. Приветствия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...