想在 android studio kotlin 中为列表视图上的 setOnItemClickListener 创建新线程,以通过从数据库中获取数据来打开新的 activity
want to create new thread in android studio kotlin for setOnItemClickListener on listview to open new activity by taking data from database
想在 android studio kotlin 中为列表视图上的 setOnItemClickListener 创建新线程,以通过从数据库中获取数据来打开新的 activity。
我在主线程上执行此操作,这使我的应用程序冻结,有时它需要超过 2、3 次点击列表项才能打开我点击的项目的相应 activity。
package com.example.countriescapitals_continentwise
import android.content.Intent
import android.os.AsyncTask
import android.os.Bundle
import android.text.PrecomputedText
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import android.widget.ProgressBar
import android.widget.SearchView
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import javax.xml.transform.Result
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [AsiaFrag.newInstance] factory method to
* create an instance of this fragment.
*/
class AsiaFrag : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private var asyncTask:AsyncTask<PrecomputedText.Params,ProgressBar,Result>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val asiaLayout= inflater.inflate(R.layout.fragment_asia, container, false)
val mAsiaLv:ListView=asiaLayout.findViewById(R.id.asialv_id)
val msearchvw:androidx.appcompat.widget.SearchView=asiaLayout.findViewById(R.id.asiasearchid)
msearchvw.queryHint="Search Among Countries"
msearchvw.isIconified=false
val dbHelper=AssetOpenHelper(requireActivity())
val dataBase=dbHelper.readableDatabase
var myCursor=dataBase.rawQuery("SELECT * FROM ASIA",null)
val mCursorAdapter=CustomCursorAdapter(requireContext(),myCursor)
mAsiaLv.adapter=mCursorAdapter
//on item click listner go to other activity
mAsiaLv.setOnItemClickListener { parent, view, position, id->
var mcountryName=myCursor?.getString(1)
var mcapitalName=myCursor?.getString(2)
var mcurrencyName=myCursor?.getString(3)
var mlanguageName=myCursor?.getString(4)
var mareaName=myCursor?.getString(6)
var mpopulation=myCursor?.getString(5)
var mimageName=myCursor?.getString(7)
val intentToDetails= Intent(requireContext(),CountryDetails::class.java)
intentToDetails.putExtra("icountryName",mcountryName)
intentToDetails.putExtra("icapitalName",mcapitalName)
intentToDetails.putExtra("icurrencyName",mcurrencyName)
intentToDetails.putExtra("ilanguageName",mlanguageName)
intentToDetails.putExtra("iareaName",mareaName)
intentToDetails.putExtra("ipopulation",mpopulation)
intentToDetails.putExtra("iimageName",mimageName)
startActivity(intentToDetails)
}
// code for search view to search among listview items
msearchvw.setOnQueryTextListener(object : SearchView.OnQueryTextListener,
androidx.appcompat.widget.SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(p0: String?): Boolean {
return false
}
override fun onQueryTextChange(p0: String?): Boolean {
myCursor=dataBase.rawQuery("SELECT * FROM ASIA WHERE COUNTRY LIKE '%${p0}%' OR CAPITAL LIKE '${p0}'",null )
mCursorAdapter.changeCursor(myCursor)
return false
}
}
)
return asiaLayout
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment AsiaFrag.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
AsiaFrag().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
//////////////// 这是我的 xml 文件
<
?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".AsiaFrag">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="@+id/asiasearchid"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/asialv_id"/>
</LinearLayout>
</FrameLayout>
/////////////// sqlite数据库开启助手
package com.example.countriescapitals_continentwise
import android.app.Activity
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log
import androidx.fragment.app.FragmentActivity
import java.io.File
import java.io.FileOutputStream
/// creating constants
const val dbName = "COUNTRY_DETAILS.db"
const val dbVersionNumber = 1
class AssetOpenHelper(private val context: Context):SQLiteOpenHelper(context,dbName,null, dbVersionNumber) {
private var dataBase:SQLiteDatabase?=null
init {
// Check if the database already copied to the device.
val dbExist = checkDatabase()
if (dbExist) {
// if already copied then don't do anything.
Log.e("-----", "Database exist")
} else {
// else copy the database to the device.
Log.e("-----", "Database doesn't exist")
createDatabase()
}
}
private fun createDatabase() {
copyDatabase()
}
private fun checkDatabase(): Boolean {
val dbFile = File(context.getDatabasePath(dbName).path)
return dbFile.exists()
}
private fun copyDatabase() {
val inputStream = context.assets.open("databases/$dbName")
val outputFile = File(context.getDatabasePath(dbName).path)
val outputStream = FileOutputStream(outputFile)
val bytesCopied = inputStream.copyTo(outputStream)
Log.e("bytesCopied", "$bytesCopied")
inputStream.close()
outputStream.flush()
outputStream.close()
}
// Open the database with read and write access mode.
private fun openDatabase() {
dataBase = SQLiteDatabase.openDatabase(context.getDatabasePath(dbName).path, null, SQLiteDatabase.OPEN_READWRITE)
}
// Close the database.
override fun close() {
dataBase?.close()
super.close()
}
override fun onCreate(p0: SQLiteDatabase?) {
}
override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
}
}
切勿在主线程中进行数据库操作。
始终为数据库操作创建一个单独的函数。
使用加载程序来防止用户多次点击。
viewModelScope.launch(){
dbOperations()
}
private suspend fun dbOperations() {
//Do your db task here. its background thread
withContext(Dispatchers. Main) {
//call next activity here. it is main thread.
}
}
想在 android studio kotlin 中为列表视图上的 setOnItemClickListener 创建新线程,以通过从数据库中获取数据来打开新的 activity。 我在主线程上执行此操作,这使我的应用程序冻结,有时它需要超过 2、3 次点击列表项才能打开我点击的项目的相应 activity。
package com.example.countriescapitals_continentwise
import android.content.Intent
import android.os.AsyncTask
import android.os.Bundle
import android.text.PrecomputedText
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ListView
import android.widget.ProgressBar
import android.widget.SearchView
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import javax.xml.transform.Result
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [AsiaFrag.newInstance] factory method to
* create an instance of this fragment.
*/
class AsiaFrag : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private var asyncTask:AsyncTask<PrecomputedText.Params,ProgressBar,Result>?=null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
val asiaLayout= inflater.inflate(R.layout.fragment_asia, container, false)
val mAsiaLv:ListView=asiaLayout.findViewById(R.id.asialv_id)
val msearchvw:androidx.appcompat.widget.SearchView=asiaLayout.findViewById(R.id.asiasearchid)
msearchvw.queryHint="Search Among Countries"
msearchvw.isIconified=false
val dbHelper=AssetOpenHelper(requireActivity())
val dataBase=dbHelper.readableDatabase
var myCursor=dataBase.rawQuery("SELECT * FROM ASIA",null)
val mCursorAdapter=CustomCursorAdapter(requireContext(),myCursor)
mAsiaLv.adapter=mCursorAdapter
//on item click listner go to other activity
mAsiaLv.setOnItemClickListener { parent, view, position, id->
var mcountryName=myCursor?.getString(1)
var mcapitalName=myCursor?.getString(2)
var mcurrencyName=myCursor?.getString(3)
var mlanguageName=myCursor?.getString(4)
var mareaName=myCursor?.getString(6)
var mpopulation=myCursor?.getString(5)
var mimageName=myCursor?.getString(7)
val intentToDetails= Intent(requireContext(),CountryDetails::class.java)
intentToDetails.putExtra("icountryName",mcountryName)
intentToDetails.putExtra("icapitalName",mcapitalName)
intentToDetails.putExtra("icurrencyName",mcurrencyName)
intentToDetails.putExtra("ilanguageName",mlanguageName)
intentToDetails.putExtra("iareaName",mareaName)
intentToDetails.putExtra("ipopulation",mpopulation)
intentToDetails.putExtra("iimageName",mimageName)
startActivity(intentToDetails)
}
// code for search view to search among listview items
msearchvw.setOnQueryTextListener(object : SearchView.OnQueryTextListener,
androidx.appcompat.widget.SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(p0: String?): Boolean {
return false
}
override fun onQueryTextChange(p0: String?): Boolean {
myCursor=dataBase.rawQuery("SELECT * FROM ASIA WHERE COUNTRY LIKE '%${p0}%' OR CAPITAL LIKE '${p0}'",null )
mCursorAdapter.changeCursor(myCursor)
return false
}
}
)
return asiaLayout
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment AsiaFrag.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
AsiaFrag().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
//////////////// 这是我的 xml 文件
<
?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".AsiaFrag">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<androidx.appcompat.widget.SearchView
android:id="@+id/asiasearchid"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/asialv_id"/>
</LinearLayout>
</FrameLayout>
/////////////// sqlite数据库开启助手
package com.example.countriescapitals_continentwise
import android.app.Activity
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import android.util.Log
import androidx.fragment.app.FragmentActivity
import java.io.File
import java.io.FileOutputStream
/// creating constants
const val dbName = "COUNTRY_DETAILS.db"
const val dbVersionNumber = 1
class AssetOpenHelper(private val context: Context):SQLiteOpenHelper(context,dbName,null, dbVersionNumber) {
private var dataBase:SQLiteDatabase?=null
init {
// Check if the database already copied to the device.
val dbExist = checkDatabase()
if (dbExist) {
// if already copied then don't do anything.
Log.e("-----", "Database exist")
} else {
// else copy the database to the device.
Log.e("-----", "Database doesn't exist")
createDatabase()
}
}
private fun createDatabase() {
copyDatabase()
}
private fun checkDatabase(): Boolean {
val dbFile = File(context.getDatabasePath(dbName).path)
return dbFile.exists()
}
private fun copyDatabase() {
val inputStream = context.assets.open("databases/$dbName")
val outputFile = File(context.getDatabasePath(dbName).path)
val outputStream = FileOutputStream(outputFile)
val bytesCopied = inputStream.copyTo(outputStream)
Log.e("bytesCopied", "$bytesCopied")
inputStream.close()
outputStream.flush()
outputStream.close()
}
// Open the database with read and write access mode.
private fun openDatabase() {
dataBase = SQLiteDatabase.openDatabase(context.getDatabasePath(dbName).path, null, SQLiteDatabase.OPEN_READWRITE)
}
// Close the database.
override fun close() {
dataBase?.close()
super.close()
}
override fun onCreate(p0: SQLiteDatabase?) {
}
override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
}
}
切勿在主线程中进行数据库操作。
始终为数据库操作创建一个单独的函数。 使用加载程序来防止用户多次点击。
viewModelScope.launch(){
dbOperations()
}
private suspend fun dbOperations() {
//Do your db task here. its background thread
withContext(Dispatchers. Main) {
//call next activity here. it is main thread.
}
}