0

I know that there are plenty of similiar posts about similar issues as mine, I even followed this and this and other posts as well (I won't list every single post here though) and tried different things out, but I still can't make my recyclerview show anything on my Fragment.

I write an app mostly for learning purposes - something similar to this, just to get sense about how things work together. If you like to see the project, (at least what I've done so far), you can do this here.

I just want to show items on recyclerview. Currently, nothing from the recyclerview is shown in the Fragment a white background only :(.

I don't even get any errors sort of "No adapter attached; skipping layout" or "No LayoutManager attached; skipping layout". And I am sure this could be a really small issue, so could you please explain me what am I missing or doing wrong.

Thank you so much for your efforts.

Here is what I do:

The Adapter code:

class ActivitiesAdapter internal constructor(
    context: Context
) : RecyclerView.Adapter<ActivitiesAdapter.ActivitiesViewHolder>() {
    private val inflater: LayoutInflater = LayoutInflater.from(context)
    private var activities = emptyList<DoItAgainEntity>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ActivitiesViewHolder {
        val itemView = inflater.inflate(R.layout.recyclerview_item, parent, false)
        return ActivitiesViewHolder(itemView)
    }

    override fun onBindViewHolder(holder: ActivitiesViewHolder, position: Int) {
        val current = activities[position]
        holder.activityItemView.text = current.engagement
    }

    internal fun setActivities(activities: List<DoItAgainEntity>) {
        this.activities = activities
        notifyDataSetChanged()
    }

    override fun getItemCount() = activities.size

    inner class ActivitiesViewHolder(itemview: View) : RecyclerView.ViewHolder(itemview) {
        val activityItemView: TextView = itemview.findViewById(R.id.textView)
    }
}

The Fragment code:

class ShowDBEntriesFragment : Fragment() {

    private lateinit var viewModel: ShowDBEntriesViewModel
    private lateinit var layout: View
    private lateinit var recyclerView: RecyclerView
    private lateinit var adapter: ActivitiesAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        layout = inflater.inflate(R.layout.show_dbentries_fragment, container, false)
        adapter = ActivitiesAdapter(context!!)
        recyclerView = layout.findViewById(R.id.recyclerview)
        recyclerView.addItemDecoration(
            DividerItemDecoration(
                context!!,
                LinearLayoutManager.VERTICAL
            )
        )
        recyclerView.layoutManager =
            LinearLayoutManager(context!!, LinearLayoutManager.VERTICAL, false)
        recyclerView.adapter = adapter
        return layout
    }

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

        viewModel = ViewModelProviders.of(this).get(ShowDBEntriesViewModel::class.java)

        fab.setOnClickListener {
            val fragmentManager = (activity as MainActivity).supportFragmentManager
            val fragmentTransaction = fragmentManager.beginTransaction()
            val fragment = InsertNewEngagementFragment()
            fragmentTransaction.replace(R.id.fragment_newEngagement, fragment)
            fragmentTransaction.commit()
        }
    }

}

The xml code from recyclerview_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        style="@style/activity_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_orange_light" />

</LinearLayout>
BWappsAndmore
  • 491
  • 3
  • 17
  • You didn't set any data to your adapter – Md. Asaduzzaman Jan 22 '20 at 17:10
  • Have you insert any data in your database? – Md. Asaduzzaman Jan 22 '20 at 17:18
  • @Md. Asaduzzaman Thank you for your help. I've populated data in my database. `suspend fun populateDatabase(doItAgainDao: DoItAgainDao) { doItAgainDao.deleteAll() var engagement = DoItAgainEntity(1, "play guitar", 100) doItAgainDao.insert(engagement) engagement = DoItAgainEntity(2, "make breakfast", 2) doItAgainDao.insert(engagement) engagement = DoItAgainEntity(2, "go out with friends", 20) doItAgainDao.insert(engagement) }` – BWappsAndmore Jan 22 '20 at 19:48

3 Answers3

2

You are not calling setActivities().

Your code will look like this:

override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        layout = inflater.inflate(R.layout.show_dbentries_fragment, container, false)
        adapter = ActivitiesAdapter(context!!)
        recyclerView = layout.findViewById(R.id.recyclerview)
        recyclerView.addItemDecoration(
            DividerItemDecoration(
                context!!,
                LinearLayoutManager.VERTICAL
            )
        )
        recyclerView.layoutManager =
            LinearLayoutManager(context!!, LinearLayoutManager.VERTICAL, false)
        recyclerView.adapter = adapter
        // Create activities variable
        adapter.setActivities(activities)
        return layout
    }
Jhonatan Sabadi
  • 838
  • 7
  • 14
  • 1
    Thank you very much for your help. But this doesn't work - the `activities` variable is on this place unresolved. – BWappsAndmore Jan 22 '20 at 19:47
  • You need to create the variable (with some itens) and pass it to your adapter, your adapter is empty. – Jhonatan Sabadi Jan 22 '20 at 19:56
  • 1
    thank you for your comment. I was expecting that the adapter will show the prepolulated data. If you would like to take a look on the project on GitHub, you will see that I prepopulate the database with some dummy data. At the moment, the adapter doesn't show this data, but I will try your advice out too. – BWappsAndmore Jan 22 '20 at 21:01
  • You prepopulate just on DB, but you have to load it on recycler view, in your activity you got do something like that: `val data = doItAgainDao.getAll() ` then `adapter.setActivities(data)`. You need to get data from your DB, then set on your recycler view. – Jhonatan Sabadi Jan 23 '20 at 12:27
  • 1
    thanks for your response. This was more or less the reason why entries were not shown on the recyclerView. Finally I found a working solution for this problem that I will share it and also accept it. But really thank you so much for pointing out to the right direction. Cheers. – BWappsAndmore Jan 23 '20 at 13:20
0

In recyclerview_item.xml

Change android:layout_height="match_parent" to android:layout_height="wrap_content"

The item layout is probably taking entire layout space.

0

This is the answer of this issue. I don't OWN this code. This code was written from a genious with huge heart (and also a friend of mine) who understands how things work and writes beautiful code. It's a great honor of mine to learn from you, bro - thank you so much for your ultimate kindness and god-like Android knowledge you have! Keep it up like this.

And here it is - the right way of doing things:

The Adapter code:

class ActivitiesAdapter : RecyclerView.Adapter<ActivitiesViewHolder>() {

    private var activities = emptyList<DoItAgainEntity>()

    internal fun setActivities(activities: List<DoItAgainEntity>) {
        this.activities = activities
        notifyDataSetChanged()
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ActivitiesViewHolder =
        ActivitiesViewHolder(
            LayoutInflater.from(parent.context).inflate(
                R.layout.recyclerview_item,
                parent,
                false
            )
        )

    override fun onBindViewHolder(holder: ActivitiesViewHolder, position: Int) {
        holder.bind(activities[position])
    }

    override fun getItemCount() = activities.size
}

class ActivitiesViewHolder(
    override val containerView: View
) : RecyclerView.ViewHolder(containerView), LayoutContainer {

    fun bind(vo: DoItAgainEntity) {
        itemView.textView.text = vo.engagement
    }
}

The Fragment code:

class ShowDBEntriesFragment : Fragment() {

    private lateinit var viewModel: ShowDBEntriesViewModel
    private lateinit var activitiesAdapter: ActivitiesAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View = inflater.inflate(R.layout.show_dbentries_fragment, container, false)

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

        viewModel = ViewModelProviders.of(this).get(ShowDBEntriesViewModel::class.java)

        activitiesAdapter = ActivitiesAdapter()
        recyclerview.apply {
            addItemDecoration(
                DividerItemDecoration(
                    context!!,
                    LinearLayoutManager.VERTICAL
                )
            )
            layoutManager = LinearLayoutManager(context!!, LinearLayoutManager.VERTICAL, false)
            adapter = activitiesAdapter
        }

        // for testing purposes. could be deleted easily
        activitiesAdapter.setActivities(
            listOf(
                DoItAgainEntity(1, "play guitar", 100),
                DoItAgainEntity(2, "make breakfast", 2),
                DoItAgainEntity(2, "go out with friends", 20)
            )
        )

        fab.setOnClickListener {
            val fragmentManager = (activity as MainActivity).supportFragmentManager
            val fragmentTransaction = fragmentManager.beginTransaction()
            val fragment = InsertNewEngagementFragment()
            fragmentTransaction.replace(R.id.fragment_newEngagement, fragment)
            fragmentTransaction.commit()
        }
    }

}

The xml code from recyclerview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        style="@style/activity_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/holo_orange_light" />

</LinearLayout>
BWappsAndmore
  • 491
  • 3
  • 17