-1

I'm looking to use some data that has been declared in a Fragment so it can be displayed as RecyclerView items. The problem is with myList and I understand that there is a type mismatch. However, I created the database table rows in the onCreateView method of the Fragment because I want to use the same DatabaseHandler for future data sets. Is there a possible way to use those rows in the Fragment whilst ensuring that the data can be filtered by either of the item class properties fullName and/or abbreviation? I want to avoid the need of having to creae a new DatabaseHandler for each data set that I will create.

Type Mismatch | Required: MutableList | Found: DatabaseHandler

item class

data class Companies (val id: Int, val fullName: String, val abbreviation: String)

fragment class

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)
    }
}

DatabaseHandler class

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"
    }
}

MyListAdapter class

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
    }
}
wbk727
  • 8,017
  • 12
  • 61
  • 125

1 Answers1

0
  1. Initialize DatabaseHandler
  2. Make the getCompany function return a list or array of Company type
  3. Give it to the adapter to show it just the way you are doing manually.

A Java code will look like this:

 // 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);
wbk727
  • 8,017
  • 12
  • 61
  • 125
adil zakarya
  • 220
  • 1
  • 4
  • 14
  • Please be more specific with your answers. You've clearly typed this quickly and it's not easy to follow. Initialse `DatabaseHandler` where? – wbk727 Apr 03 '19 at 22:42
  • Do you mean - use `private val myList: DatabaseHandler` in the adapter? – wbk727 Apr 03 '19 at 22:43
  • Initialse DatabaseHandler in the activity so you can access to the **getCompany** function and get the returned list – adil zakarya Apr 03 '19 at 22:48
  • I'm not using an activity, I'm using a fragment. Do you mean something like `val myList: DatabaseHandler`? I added that just before `onCreate` in the fragment. – wbk727 Apr 03 '19 at 22:53
  • A java code will look like this // my recycle view RecyclerView rv = (RecyclerView) findViewById(R.id.RVCAtegory); LinearLayoutManager llm = new LinearLayoutManager(this); rv.setLayoutManager(llm); // My data helber MDBHelper mDBHelper = new DbHelper(this); // i geve the returned list to the list in the activity List = mDBHelper.GetCompany(); // then i gave it to the adabter Adabter_Category adapter = new Adabter_Category(CategoryList, inflater); rv.setAdapter(adapter); – adil zakarya Apr 03 '19 at 23:02
  • Please move this code to your answer. I'm struggling to read this and convert it to Kotlin. – wbk727 Apr 03 '19 at 23:11
  • @MacaronLover i did it . – adil zakarya Apr 03 '19 at 23:12
  • For `mDBHelper.GetCompany();` something needs to go in the parentheses (brackets) – wbk727 Apr 03 '19 at 23:17
  • if you are selecting every thing then no need for parameters, i'm using the same code on my app [right here](https://play.google.com/store/apps/details?id=com.Chodo.BTSLyrics) – adil zakarya Apr 03 '19 at 23:26
  • The error in my question still exists. Doesn't `private val myList: MutableList,` in the adapter need to change to something else? – wbk727 Apr 03 '19 at 23:31
  • Please see my update code. I don't know where I've gone wrong. – wbk727 Apr 04 '19 at 16:51
  • Please don't ignore my requests for help. I've asked you nicely. – wbk727 Apr 07 '19 at 15:39