androidandroid-studiokotlinfragmentexpandablelistview

Creating an Expandable List View in a Fragment using Kotlin


I cannot get past a problem that comes up because it's in a fragment and not in the MainActivity. I have rewritten this code several ways and cannot get it to work. "this" in the listViewAdapter in the FAQFragment is showing an error that doesn't show up if I just write it in MainActivity. I'm trying to make a FAQ fragment, and ideally have a grandchild with the answer to the question(child) from the topic(parent). I haven't figured out how to do that yet either. Please help or direct me to a better method of doing this.

FAQFragment:

package com.app

import android.os.Bundle
import android.view.*
import android.content.Context
import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.fragment_f_a_q.*

class FAQFragment : Fragment() {

    private lateinit var listViewAdapter: FAQAdapter
    private lateinit var questionList : List<String>
    private lateinit var answerList : HashMap<String, List<String>>


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        showList()

        listViewAdapter = FAQAdapter(this,questionList, answerList)
        FAQList.setAdapter(listViewAdapter)


        return inflater.inflate(R.layout.fragment_f_a_q, container, false)
    }

    private fun showList() {
        questionList = ArrayList()
        answerList = HashMap()

        (questionList as ArrayList<String>).add("Question 1")
        (questionList as ArrayList<String>).add("Question 2")
        (questionList as ArrayList<String>).add("Question 3")
        (questionList as ArrayList<String>).add("Question 4")
        (questionList as ArrayList<String>).add("Question 5")

        val answer1: MutableList<String> = ArrayList()
        answer1.add("Answer 1")
        answer1.add("Answer 2")
        answer1.add("Answer 3")

        val answer2: MutableList<String> = ArrayList()
        answer2.add("Answer 1")
        answer2.add("Answer 2")
        answer2.add("Answer 3")

        val answer3: MutableList<String> = ArrayList()
        answer3.add("Answer 1")
        answer3.add("Answer 2")
        answer3.add("Answer 3")

        val answer4: MutableList<String> = ArrayList()
        answer4.add("Answer 1")
        answer4.add("Answer 2")
        answer4.add("Answer 3")

        val answer5: MutableList<String> = ArrayList()
        answer5.add("Answer 1")
        answer5.add("Answer 2")
        answer5.add("Answer 3")

        answerList[questionList[0]] = answer1
        answerList[questionList[1]] = answer2
        answerList[questionList[2]] = answer3
        answerList[questionList[3]] = answer4
        answerList[questionList[4]] = answer5

    }


}

FAQAdapter:

package com.app

import android.content.Context
import android.view.*
import android.widget.*

class FAQAdapter internal constructor(private val context: Context, private val questionList: List<String>, private val answerList: HashMap<String, List<String>>): BaseExpandableListAdapter() {

    override fun getGroupCount(): Int {
        return questionList.size
    }

    override fun getChildrenCount(groupPosition: Int): Int {
        return this.answerList[this.questionList[groupPosition]]!!.size
    }

    override fun getGroup(groupPosition: Int): Any {
        return questionList[groupPosition]
    }

    override fun getChild(groupPosition: Int, childPosition: Int): Any {
        return this.answerList[this.questionList[groupPosition]]!![childPosition]
    }

    override fun getGroupId(groupPosition: Int): Long {
        return groupPosition.toLong()
    }

    override fun getChildId(groupPosition: Int, childPosition: Int): Long {
        return childPosition.toLong()
    }

    override fun hasStableIds(): Boolean {
        return false
    }

    override fun getGroupView(
        groupPosition: Int,
        isExpanded: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {

        var convertView = convertView
        val questionTitle = getGroup(groupPosition) as String
        if(convertView == null){
            val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = inflater.inflate(R.layout.faq_questions, null)
        }

        val questionTv = convertView!!.findViewById<TextView>(R.id.question_list_tv)
        questionTv.setText(questionTitle)

        return convertView

    }

    override fun getChildView(
        groupPosition: Int,
        childPosition: Int,
        isLastChild: Boolean,
        convertView: View?,
        parent: ViewGroup?
    ): View {

        var convertView = convertView
        val answerTitle = getChild(groupPosition, childPosition) as String
        if(convertView == null){
            val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
            convertView = inflater.inflate(R.layout.faq_answers, null)
        }

        val answerTv = convertView!!.findViewById<TextView>(R.id.question_list_tv)
        answerTv.setText(answerTitle)

        return convertView
    }

    override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
        return true
    }
}

Solution

  • Use requireContext() instead of this.