BWappsAndmore
BWappsAndmore

Reputation: 531

recyclerView (still) not showing items on Fragment

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>

Upvotes: 0

Views: 1878

Answers (3)

BWappsAndmore
BWappsAndmore

Reputation: 531

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>

Upvotes: 0

Jhonatan Sabadi
Jhonatan Sabadi

Reputation: 858

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
    }

Upvotes: 2

Mohammed Aquib Azad
Mohammed Aquib Azad

Reputation: 634

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.

Upvotes: 0

Related Questions