How can I add ListView in Fragment using TabLayout?

Viewed 406

I am really new at Kotlin. I tried to make slidable pages using TabLayout. I have 3 different Fragments and I need to add ListView or RecyclerView on that fragments but in this point I can't figure out where is I have to add adapter of ListView. I add adapter class on fragment's Kotlin file but I can't connect that and fragment.(I think) I got an error which is ListView cannot be null so I can say about my adapter didn't working correctly. How can I solve it?

Here I add my codes:

My SecondFragment.kt code:

class SecondFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val listView = view!!.findViewById<ListView>(R.id.main_listview)


    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val listView = view!!.findViewById<ListView>(R.id.main_listview)
        return inflater.inflate(R.layout.fragment_second, container, false)


    }



    private class MyCustomAdapter(context: Context): BaseAdapter(){

        private val mContext : Context

        private val names = arrayListOf<String>("Test Name", "Steve Jobs", "Tim Cook", "Kobe King")

        init {
            mContext = context
        }

        // BURADA KAC TANE ROW OLDUGUNUN SOYLER..
        override fun getCount(): Int {
            return names.size
        }

        override fun getItem(position: Int): Any {

            return "Test String"
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
            //val textView = TextView(mContext)
            //textView.text = "Here my first row for list view.."
            //return textView

            val layoutInflater = LayoutInflater.from(mContext)
            val rowMain = layoutInflater.inflate(R.layout.row_for_list, parent, false)


            val nameTextView = rowMain.findViewById<TextView>(R.id.name_textView)
            nameTextView.text = names.get(position)

            val positionTextView = rowMain.findViewById<TextView>(R.id.position_textview)
            positionTextView.text = "Row Number: $position"

            return rowMain

        }


    }
}

Here my ViewPagerAdapter.kt file code:

class ViewPagerAdapter(supportFragmentManager: FragmentManager) : FragmentPagerAdapter(supportFragmentManager, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {

    private val mFragmentList = ArrayList<Fragment>()
    private val mFragmentTitleList = ArrayList<String>()


    override fun getCount(): Int {
        return mFragmentList.size
    }

    override fun getItem(position: Int): Fragment {
        return mFragmentList[position]
    }

    override fun getPageTitle(position: Int): CharSequence? {
        return mFragmentTitleList[position]
    }

    fun addFragment(fragment: Fragment, title: String){
        mFragmentList.add(fragment)
        mFragmentTitleList.add(title)
    }




}

And here my MainActivity.kt file code:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setUpTabs()

    }
    private fun setUpTabs() {

        val adapter = ViewPagerAdapter(supportFragmentManager)
        adapter.addFragment(HomeFragment(), "Home")
        adapter.addFragment(SecondFragment(), "Second")
        adapter.addFragment(ThirdFragment(), "Third")

        viewPager.adapter = adapter
        tabs.setupWithViewPager(viewPager)

        tabs.getTabAt(0)!!.setIcon(R.drawable.ic_baseline_account_box_24)
        tabs.getTabAt(1)!!.setIcon(R.drawable.ic_baseline_add_ic_call_24)
        tabs.getTabAt(2)!!.setIcon(R.drawable.ic_baseline_adb_24)

    }

}
2 Answers

Try this :

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view=inflater.inflate(R.layout.fragment_second, container, false)
        val listView = view!!.findViewById<ListView>(R.id.main_listview)

       val myListAdapter = MyCustomAdapter(container!!.context)
    listView.adapter = myListAdapter
    

        return view


    }

You have to set to instantiate the adapter and set it to the listView, I also explained some things in the comments.

class SecondFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        //don't do this in onCreate, do it in onViewCreated or onCreateView
        //val listView = view!!.findViewById<ListView>(R.id.main_listview)


    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val root = inflater.inflate(R.layout.fragment_second, container, false)

        //you can set adapter here if you want, but i did it in onViewCreated

        //return it
        return root
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        //get reference to ListView
        val listView = root.findViewById<ListView>(R.id.main_listview)

        //set adapter
        listView.adapter = MyCustomAdapter(requireContext())
    }


    private class MyCustomAdapter(private val mContext: Context): BaseAdapter(){

        //do initiation here as it needs to be done only once
        private val layoutInflater: LayoutInflater = LayoutInflater.from(mContext)

        private val names = arrayListOf<String>("Test Name", "Steve Jobs", "Tim Cook", "Kobe King")


        // BURADA KAC TANE ROW OLDUGUNUN SOYLER..
        override fun getCount(): Int {
            return names.size
        }

        override fun getItem(position: Int): Any {

            return "Test String"
        }

        override fun getItemId(position: Int): Long {
            return position.toLong()
        }

        override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
            //val textView = TextView(mContext)
            //textView.text = "Here my first row for list view.."
            //return textView

            val rowMain = layoutInflater.inflate(R.layout.row_for_list, parent, false)


            val nameTextView = rowMain.findViewById<TextView>(R.id.name_textView)
            nameTextView.text = names.get(position)

            val positionTextView = rowMain.findViewById<TextView>(R.id.position_textview)
            positionTextView.text = "Row Number: $position"

            return rowMain

        }


    }
}
Related