Android 如何将SQLite数据与可重用的RecyclerView适配器一起使用
我希望使用在Android 如何将SQLite数据与可重用的RecyclerView适配器一起使用,android,database,sqlite,kotlin,sqliteopenhelper,Android,Database,Sqlite,Kotlin,Sqliteopenhelper,我希望使用在片段中声明的一些数据,以便将其显示为RecyclerView项。问题在于myList,我知道存在类型不匹配。但是,我在片段的onCreateView方法中创建了数据库表行,因为我希望对将来的数据集使用相同的DatabaseHandler。是否有一种可能的方法来使用片段中的这些行,同时确保数据可以通过项目类属性fullName和/或缩写进行过滤?我想避免为我将要创建的每个数据集创建一个新的数据库处理程序 类型不匹配|必需:可变列表|找到:DatabaseHandler 项目类别 dat
片段中声明的一些数据,以便将其显示为RecyclerView
项。问题在于myList
,我知道存在类型不匹配。但是,我在片段的onCreateView
方法中创建了数据库表行,因为我希望对将来的数据集使用相同的DatabaseHandler
。是否有一种可能的方法来使用片段中的这些行,同时确保数据可以通过项目类属性fullName
和/或缩写
进行过滤?我想避免为我将要创建的每个数据集创建一个新的数据库处理程序
类型不匹配|必需:可变列表|找到:DatabaseHandler
项目类别
data class Companies (val id: Int, val fullName: String, val abbreviation: String)
class MyFragment : androidx.fragment.app.Fragment() {
private var mAdapter: MyListAdapter? = null
private lateinit var mRecyclerView: androidx.recyclerview.widget.RecyclerView
private var mTwoPane: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.layout_recyclerview, container, false)
mTwoPane = (activity as androidx.fragment.app.FragmentActivity).findViewById<View>(R.id.detail_container) != null
mRecyclerView = view.findViewById<RecyclerView>(R.id.recyclerView_list)
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this.activity)
mRecyclerView.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(Objects.requireNonNull<Context>(context), LinearLayout.VERTICAL))
val companyA = Companies(1, "GlaxoSmithKline plc", "GSK")
val companyB = Companies(2, "Hiscox Ltd", "HSX")
val companyC = Companies(3, "InterContinental Hotels Group plc", "IHG")
val companyD = Companies(4, "Marks & Spencer Group plc", "MKS")
val companyE = Companies(5, "FTSE 150", "")
val companyF = Companies(6, "FTSE 250", "")
val myList = DatabaseHandler(this.context!!)
myList.insertData(companyA)
myList.insertData(companyB)
myList.insertData(companyC)
myList.insertData(companyD)
myList.insertData(companyE)
myList.insertData(companyF)
mRecyclerView.adapter = mAdapter
mAdapter = MyListAdapter(activity!!, myList, mTwoPane)
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val mInflater = Objects.requireNonNull<androidx.fragment.app.FragmentActivity>(activity).menuInflater
mInflater.inflate(R.menu.menu_search, menu)
val searchitem = menu.findItem(R.id.action_search)
val searchView = searchitem.actionView as SearchView
searchView.maxWidth = Integer.MAX_VALUE
searchView.queryHint = Objects.requireNonNull<Context>(context).getText(R.string.searchhint_stopname)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
mAdapter!!.filter.filter(newText)
return false
}
})
super.onCreateOptionsMenu(menu, inflater)
}
}
class DatabaseHandler(context: Context) : SQLiteOpenHelper(context, DatabaseHandler.DB_NAME, null, DatabaseHandler.DB_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
val createTable = "CREATE TABLE $TABLE_NAME ($COL_ID INTEGER PRIMARY KEY, $COL_NAME TEXT, $COL_ABBREVIATION TEXT);"
db.execSQL(createTable)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
val dropTable = "DROP TABLE IF EXISTS $TABLE_NAME"
db.execSQL(dropTable)
onCreate(db)
}
fun insertData(companies: Companies): Boolean {
val db = this.readableDatabase
val values = ContentValues()
values.put(COL_ID, companies.id)
values.put(COL_NAME, companies.fullName)
values.put(COL_ABBREVIATION, companies.abbreviation)
val _success = db.insert(TABLE_NAME, null, values)
db.close()
Log.v("Insertion complete", "Record Inserted Successfully")
return (Integer.parseInt("$_success") != -1)
}
fun getCompany(_id: Int): Companies {
val companies = Companies(_id, "", "")
val db = writableDatabase
val selectQuery = "SELECT * FROM $TABLE_NAME WHCOL_$COL_ID = $_id"
val cursor = db.rawQuery(selectQuery, null)
if (cursor != null) {
cursor.moveToFirst()
while (cursor.moveToNext()) {
val id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(COL_ID)))
val fullName = cursor.getString(cursor.getColumnIndex(COL_NAME))
val abbreviation = cursor.getString(cursor.getColumnIndex(COL_ABBREVIATION))
}
}
cursor.close()
return companies
}
companion object {
private const val DB_VERSION = 1
private const val DB_NAME = "MyCompanies"
private const val TABLE_NAME = "Companies"
private const val COL_ID = "Id"
private const val COL_NAME = "Name"
private const val COL_ABBREVIATION = "Abbreviation"
}
}
class MyListAdapter(private val mCtx: Context,
private val myList: MutableList<Companies>,
private val mTwoPane: Boolean) : androidx.recyclerview.widget.RecyclerView.Adapter<MyListAdapter.CompanyViewHolder>(), Filterable {
private var myListFull = myList.toMutableList()
private val companyFilter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
val filteredList = ArrayList<Companies>()
when {
constraint == null || constraint.isEmpty() -> filteredList.addAll(myListFull)
else -> {
val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in myListFull) {
when {
item.companyName!!.toLowerCase().contains(filterPattern) ->
filteredList.add(item)
}
}
}
}
val results = Filter.FilterResults()
results.values = filteredList
return results
}
override fun publishResults(constraint: CharSequence?, results: Filter.FilterResults?) {
myList.clear()
myList.addAll(results!!.values as List<Companies>)
notifyDataSetChanged()
}
}
inner class CompanyViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
.ViewHolder(itemView) {
var tvTitle: TextView = itemView.findViewById(R.id.tv_RVItem)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CompanyViewHolder {
val inflater = LayoutInflater.from(mCtx)
val v = inflater.inflate(R.layout.recyclerview_item_textview, parent, false)
return CompanyViewHolder(v)
}
override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) {
val product = myList[holder.adapterPosition]
holder.tvTitle.text = product.companyfuName
}
override fun getItemCount(): Int {
return myList.size
}
override fun getFilter(): Filter {
return companyFilter
}
}
片段类
data class Companies (val id: Int, val fullName: String, val abbreviation: String)
class MyFragment : androidx.fragment.app.Fragment() {
private var mAdapter: MyListAdapter? = null
private lateinit var mRecyclerView: androidx.recyclerview.widget.RecyclerView
private var mTwoPane: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.layout_recyclerview, container, false)
mTwoPane = (activity as androidx.fragment.app.FragmentActivity).findViewById<View>(R.id.detail_container) != null
mRecyclerView = view.findViewById<RecyclerView>(R.id.recyclerView_list)
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this.activity)
mRecyclerView.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(Objects.requireNonNull<Context>(context), LinearLayout.VERTICAL))
val companyA = Companies(1, "GlaxoSmithKline plc", "GSK")
val companyB = Companies(2, "Hiscox Ltd", "HSX")
val companyC = Companies(3, "InterContinental Hotels Group plc", "IHG")
val companyD = Companies(4, "Marks & Spencer Group plc", "MKS")
val companyE = Companies(5, "FTSE 150", "")
val companyF = Companies(6, "FTSE 250", "")
val myList = DatabaseHandler(this.context!!)
myList.insertData(companyA)
myList.insertData(companyB)
myList.insertData(companyC)
myList.insertData(companyD)
myList.insertData(companyE)
myList.insertData(companyF)
mRecyclerView.adapter = mAdapter
mAdapter = MyListAdapter(activity!!, myList, mTwoPane)
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val mInflater = Objects.requireNonNull<androidx.fragment.app.FragmentActivity>(activity).menuInflater
mInflater.inflate(R.menu.menu_search, menu)
val searchitem = menu.findItem(R.id.action_search)
val searchView = searchitem.actionView as SearchView
searchView.maxWidth = Integer.MAX_VALUE
searchView.queryHint = Objects.requireNonNull<Context>(context).getText(R.string.searchhint_stopname)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
mAdapter!!.filter.filter(newText)
return false
}
})
super.onCreateOptionsMenu(menu, inflater)
}
}
class DatabaseHandler(context: Context) : SQLiteOpenHelper(context, DatabaseHandler.DB_NAME, null, DatabaseHandler.DB_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
val createTable = "CREATE TABLE $TABLE_NAME ($COL_ID INTEGER PRIMARY KEY, $COL_NAME TEXT, $COL_ABBREVIATION TEXT);"
db.execSQL(createTable)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
val dropTable = "DROP TABLE IF EXISTS $TABLE_NAME"
db.execSQL(dropTable)
onCreate(db)
}
fun insertData(companies: Companies): Boolean {
val db = this.readableDatabase
val values = ContentValues()
values.put(COL_ID, companies.id)
values.put(COL_NAME, companies.fullName)
values.put(COL_ABBREVIATION, companies.abbreviation)
val _success = db.insert(TABLE_NAME, null, values)
db.close()
Log.v("Insertion complete", "Record Inserted Successfully")
return (Integer.parseInt("$_success") != -1)
}
fun getCompany(_id: Int): Companies {
val companies = Companies(_id, "", "")
val db = writableDatabase
val selectQuery = "SELECT * FROM $TABLE_NAME WHCOL_$COL_ID = $_id"
val cursor = db.rawQuery(selectQuery, null)
if (cursor != null) {
cursor.moveToFirst()
while (cursor.moveToNext()) {
val id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(COL_ID)))
val fullName = cursor.getString(cursor.getColumnIndex(COL_NAME))
val abbreviation = cursor.getString(cursor.getColumnIndex(COL_ABBREVIATION))
}
}
cursor.close()
return companies
}
companion object {
private const val DB_VERSION = 1
private const val DB_NAME = "MyCompanies"
private const val TABLE_NAME = "Companies"
private const val COL_ID = "Id"
private const val COL_NAME = "Name"
private const val COL_ABBREVIATION = "Abbreviation"
}
}
class MyListAdapter(private val mCtx: Context,
private val myList: MutableList<Companies>,
private val mTwoPane: Boolean) : androidx.recyclerview.widget.RecyclerView.Adapter<MyListAdapter.CompanyViewHolder>(), Filterable {
private var myListFull = myList.toMutableList()
private val companyFilter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
val filteredList = ArrayList<Companies>()
when {
constraint == null || constraint.isEmpty() -> filteredList.addAll(myListFull)
else -> {
val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in myListFull) {
when {
item.companyName!!.toLowerCase().contains(filterPattern) ->
filteredList.add(item)
}
}
}
}
val results = Filter.FilterResults()
results.values = filteredList
return results
}
override fun publishResults(constraint: CharSequence?, results: Filter.FilterResults?) {
myList.clear()
myList.addAll(results!!.values as List<Companies>)
notifyDataSetChanged()
}
}
inner class CompanyViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
.ViewHolder(itemView) {
var tvTitle: TextView = itemView.findViewById(R.id.tv_RVItem)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CompanyViewHolder {
val inflater = LayoutInflater.from(mCtx)
val v = inflater.inflate(R.layout.recyclerview_item_textview, parent, false)
return CompanyViewHolder(v)
}
override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) {
val product = myList[holder.adapterPosition]
holder.tvTitle.text = product.companyfuName
}
override fun getItemCount(): Int {
return myList.size
}
override fun getFilter(): Filter {
return companyFilter
}
}
MyListAdapter类
data class Companies (val id: Int, val fullName: String, val abbreviation: String)
class MyFragment : androidx.fragment.app.Fragment() {
private var mAdapter: MyListAdapter? = null
private lateinit var mRecyclerView: androidx.recyclerview.widget.RecyclerView
private var mTwoPane: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setHasOptionsMenu(true)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.layout_recyclerview, container, false)
mTwoPane = (activity as androidx.fragment.app.FragmentActivity).findViewById<View>(R.id.detail_container) != null
mRecyclerView = view.findViewById<RecyclerView>(R.id.recyclerView_list)
mRecyclerView.setHasFixedSize(true)
mRecyclerView.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this.activity)
mRecyclerView.addItemDecoration(androidx.recyclerview.widget.DividerItemDecoration(Objects.requireNonNull<Context>(context), LinearLayout.VERTICAL))
val companyA = Companies(1, "GlaxoSmithKline plc", "GSK")
val companyB = Companies(2, "Hiscox Ltd", "HSX")
val companyC = Companies(3, "InterContinental Hotels Group plc", "IHG")
val companyD = Companies(4, "Marks & Spencer Group plc", "MKS")
val companyE = Companies(5, "FTSE 150", "")
val companyF = Companies(6, "FTSE 250", "")
val myList = DatabaseHandler(this.context!!)
myList.insertData(companyA)
myList.insertData(companyB)
myList.insertData(companyC)
myList.insertData(companyD)
myList.insertData(companyE)
myList.insertData(companyF)
mRecyclerView.adapter = mAdapter
mAdapter = MyListAdapter(activity!!, myList, mTwoPane)
return view
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val mInflater = Objects.requireNonNull<androidx.fragment.app.FragmentActivity>(activity).menuInflater
mInflater.inflate(R.menu.menu_search, menu)
val searchitem = menu.findItem(R.id.action_search)
val searchView = searchitem.actionView as SearchView
searchView.maxWidth = Integer.MAX_VALUE
searchView.queryHint = Objects.requireNonNull<Context>(context).getText(R.string.searchhint_stopname)
searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String): Boolean {
return false
}
override fun onQueryTextChange(newText: String): Boolean {
mAdapter!!.filter.filter(newText)
return false
}
})
super.onCreateOptionsMenu(menu, inflater)
}
}
class DatabaseHandler(context: Context) : SQLiteOpenHelper(context, DatabaseHandler.DB_NAME, null, DatabaseHandler.DB_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
val createTable = "CREATE TABLE $TABLE_NAME ($COL_ID INTEGER PRIMARY KEY, $COL_NAME TEXT, $COL_ABBREVIATION TEXT);"
db.execSQL(createTable)
}
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
val dropTable = "DROP TABLE IF EXISTS $TABLE_NAME"
db.execSQL(dropTable)
onCreate(db)
}
fun insertData(companies: Companies): Boolean {
val db = this.readableDatabase
val values = ContentValues()
values.put(COL_ID, companies.id)
values.put(COL_NAME, companies.fullName)
values.put(COL_ABBREVIATION, companies.abbreviation)
val _success = db.insert(TABLE_NAME, null, values)
db.close()
Log.v("Insertion complete", "Record Inserted Successfully")
return (Integer.parseInt("$_success") != -1)
}
fun getCompany(_id: Int): Companies {
val companies = Companies(_id, "", "")
val db = writableDatabase
val selectQuery = "SELECT * FROM $TABLE_NAME WHCOL_$COL_ID = $_id"
val cursor = db.rawQuery(selectQuery, null)
if (cursor != null) {
cursor.moveToFirst()
while (cursor.moveToNext()) {
val id = Integer.parseInt(cursor.getString(cursor.getColumnIndex(COL_ID)))
val fullName = cursor.getString(cursor.getColumnIndex(COL_NAME))
val abbreviation = cursor.getString(cursor.getColumnIndex(COL_ABBREVIATION))
}
}
cursor.close()
return companies
}
companion object {
private const val DB_VERSION = 1
private const val DB_NAME = "MyCompanies"
private const val TABLE_NAME = "Companies"
private const val COL_ID = "Id"
private const val COL_NAME = "Name"
private const val COL_ABBREVIATION = "Abbreviation"
}
}
class MyListAdapter(private val mCtx: Context,
private val myList: MutableList<Companies>,
private val mTwoPane: Boolean) : androidx.recyclerview.widget.RecyclerView.Adapter<MyListAdapter.CompanyViewHolder>(), Filterable {
private var myListFull = myList.toMutableList()
private val companyFilter = object : Filter() {
override fun performFiltering(constraint: CharSequence?): Filter.FilterResults {
val filteredList = ArrayList<Companies>()
when {
constraint == null || constraint.isEmpty() -> filteredList.addAll(myListFull)
else -> {
val filterPattern = constraint.toString().toLowerCase().trim { it <= ' ' }
for (item in myListFull) {
when {
item.companyName!!.toLowerCase().contains(filterPattern) ->
filteredList.add(item)
}
}
}
}
val results = Filter.FilterResults()
results.values = filteredList
return results
}
override fun publishResults(constraint: CharSequence?, results: Filter.FilterResults?) {
myList.clear()
myList.addAll(results!!.values as List<Companies>)
notifyDataSetChanged()
}
}
inner class CompanyViewHolder(itemView: View) : androidx.recyclerview.widget.RecyclerView
.ViewHolder(itemView) {
var tvTitle: TextView = itemView.findViewById(R.id.tv_RVItem)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CompanyViewHolder {
val inflater = LayoutInflater.from(mCtx)
val v = inflater.inflate(R.layout.recyclerview_item_textview, parent, false)
return CompanyViewHolder(v)
}
override fun onBindViewHolder(holder: CompanyViewHolder, position: Int) {
val product = myList[holder.adapterPosition]
holder.tvTitle.text = product.companyfuName
}
override fun getItemCount(): Int {
return myList.size
}
override fun getFilter(): Filter {
return companyFilter
}
}
class MyListAdapter(私有val mCtx:Context,
private val myList:MutableList,
private val mTwoPane:Boolean):androidx.recyclerview.widget.recyclerview.Adapter(),可筛选{
私有变量myListFull=myList.toMutableList()
private val companyFilter=object:Filter(){
重写性能筛选(约束:CharSequence?):Filter.FilterResults{
val filteredList=ArrayList()
什么时候{
constraint==null | | constraint.isEmpty()->filteredList.addAll(myListFull)
其他->{
val filterPattern=constraint.toString().toLowerCase().trim{it
filteredList.add(项目)
}
}
}
}
val results=Filter.FilterResults()
results.values=filteredList
返回结果
}
覆盖有趣的publishResults(约束:CharSequence?,结果:Filter.FilterResults?){
myList.clear()
myList.addAll(结果!!.value作为列表)
notifyDataSetChanged()
}
}
内部类CompanyViewHolder(itemView:View):androidx.recyclerview.widget.recyclerview
.ViewHolder(项目视图){
变量tvTitle:TextView=itemView.findViewById(R.id.tv\RVItem)
}
override fun onCreateViewHolder(父级:ViewGroup,viewType:Int):CompanyViewHolder{
val充气机=充气机从(mCtx)
val v=充气机。充气(R.layout.recyclerview\u item\u textview,父项,false)
返回公司翼肩(v)
}
覆盖BindViewHolder(holder:CompanyViewHolder,position:Int){
val product=myList[支架.适配器位置]
holder.tvTitle.text=product.companyfuName
}
重写getItemCount():Int{
返回myList.size
}
重写getFilter():筛选器{
返回公司过滤器
}
}
初始化DatabaseHandler
使getCompany
函数返回公司类型的列表或数组
将它交给适配器,以手动方式显示它李>
Java代码如下所示:
// My recycler view
RecyclerView rv = (RecyclerView) findViewById(R.id.RVCategory);
LinearLayoutManager llm = new LinearLayoutManager(this);
rv.setLayoutManager(llm);
// My data helper
MDBHelper mDBHelper = new DbHelper(this);
// I gave the returned list to the list in the `Activity`
List = mDBHelper.GetCompany();
// Then I gave it to the adapter
Adapter_Category adapter = new Adapter_Category(CategoryList, inflater);
rv.setAdapter(adapter);
请更具体地回答。你很快就把它打出来了,不容易理解。初始化DatabaseHandler
where?你的意思是-在适配器中使用private val myList:DatabaseHandler
?在活动中初始化DatabaseHandler,以便访问getCompany函数并获取返回的列表我没有使用活动,我使用的是片段。您的意思是类似于val myList:DatabaseHandler
?我在片段中的onCreate之前添加了它;LinearLayoutManager llm=新的LinearLayoutManager(本);rv.setLayoutManager(llm);//我的数据helber MDBHelper MDBHelper=new DbHelper(this);//将返回的列表保存到activity list=mDBHelper.GetCompany();//然后我把它交给adabter adabter_Category adapter=new adabter_Category(类别列表,充气器);rv.设置适配器(适配器);