Search code examples
androidandroid-studiolistviewkotlinadapter

Why list of WeekDay objects isn't displayed on Android device? Kotlin ListView


I'm writing my first Android planning application. I have a navigation drawer and a WeekListFragment. In fragment I create an array of WeekDay objects and try to display them via a WeekAdapter. But when I run Android emulator nothing is displayed though fragment opens. Can you explain me what I should do?

Here is code of this fragment:

package itshpit.com.myapplication

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.TextView
import androidx.fragment.app.Fragment
import itshpit.com.myapplication.classes.WeekDay

class WeekListFragment() : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view: View? = inflater.inflate(R.layout.fragment_week, container, false)
        (activity as MainActivity).supportActionBar!!.title = "Week"

        val week: Array<String> = resources.getStringArray(R.array.week)
        val weekList: ArrayList<WeekDay> = ArrayList()
        weekList.add(WeekDay(text = "some Text", image = R.drawable.mon, id = 1))
        weekList.add(WeekDay(text = "some Text", image = R.drawable.mon, id = 2))
        weekList.add(WeekDay(text = "some Text", image = R.drawable.mon, id = 3))
        weekList.add(WeekDay(text = "some Text", image = R.drawable.mon, id = 4))
        weekList.add(WeekDay(text = "some Text", image = R.drawable.mon, id = 5))
        weekList.add(WeekDay(text = "some Text", image = R.drawable.mon, id = 6))
        weekList.add(WeekDay(text = "some Text", image = R.drawable.mon, id = 7))
        val adapter = WeekAdapter((activity as MainActivity), weekList)

        return view
    }

    class WeekAdapter(context: Context, val weekList: List<WeekDay>) : ArrayAdapter<WeekDay>(context, 0, weekList) {

        private class ViewHolder(row: View?) {
            var txtName: TextView
            var ivImage: ImageView

            init {
                this.txtName = row?.findViewById(R.id.txtWeekDay) as TextView
                this.ivImage = row.findViewById(R.id.imgWeekDay) as ImageView
            }
        }
        override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {

            val view: View?
            val viewHolder: ViewHolder
            if (convertView == null) {
                val layout = LayoutInflater.from(context)
                view = layout.inflate(R.layout.week_item, parent, false)
                viewHolder = ViewHolder(view)
                view.tag = viewHolder
            } else {
                view = convertView
                viewHolder = view.tag as ViewHolder
            }
            val weekDay: WeekDay = getItem(position) as WeekDay
            viewHolder.txtName.text = weekDay.text
            viewHolder.ivImage.setImageResource(weekDay.image)


            return view as View
        }

        override fun getItemId(position: Int): Long {
            return weekList[position].id
        }

        override fun getItem(position: Int): WeekDay? {
            return weekList.get(position)
        }

        override fun getCount(): Int {
            return 7
        }
    }
}

WeekDay class code is below:

data class WeekDay(var id: Long = -1,
                   var date: Date? = null,
                   var text: String,
                   var image: Int
                   ) {}

"fragment_week.xml" file:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".WeekListFragment">

    <ListView
        android:id="@+id/weekList"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </ListView>

</RelativeLayout>

Solution

  • You never assigned your adapter to the ListView.

    First you need a reference to your ListView. Put this right before your return line:

    val weekList: ListView = findViewById(R.id.weekList)
    

    Note, this step is unnecessary if using the Kotlin Android extensions (which new Android projects do by default). The Kotlin Android extensions automatically generate the properties for your view IDs.

    Then call delete your existing val adapter = ... line and do this:

    weekList.adapter = WeekAdapter(context, weekList)
    

    Notice I changed (activity as MainActivity) to context. This is because your adapter only asks for a context in its constructor.