RecyclerView onCreateViewHolder and onBindViewHolder not getting called

Viewed 129

I am trying to create a dynamic list view by getting data from SQLite Database. I created breakpoints and found out that onCreateViewHolder and onBindViewHolder of adapter files are not getting called. Anyway while trying to print the count within getItemCount(), I am getting the correct count. Could anyone please help me fix it?

List View.java

package com.hacker.wanderlust;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;

import com.hacker.wanderlust.adapter.TravelListAdapter;
import com.hacker.wanderlust.bean.Travel;
import com.hacker.wanderlust.dao.TravelDAO;
import com.hacker.wanderlust.logic.Conversion;

import java.text.ParseException;
import java.util.ArrayList;

public class TravelViewList extends AppCompatActivity {

    TravelDAO travelDAO = new TravelDAO(this);
    Conversion conversion = new Conversion();

    ArrayList<Travel> travels=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_travel_view_list);

        try {

            RecyclerView travelList = (RecyclerView) findViewById(R.id.travelListView);

            travelList.setLayoutManager(new LinearLayoutManager(this));
            travelList.setHasFixedSize(true);

            Cursor cursor = travelDAO.getTravelData();

            Log.d("message","Cursor got data");

            if(cursor!=null && cursor.getCount()>0) {

                if(cursor.moveToFirst()) {

                    do {

                        Travel travel = new Travel();

                        travel.setName(cursor.getString(0));
                        travel.setLocation(cursor.getString(1));
                        travel.setDateOfTravel(conversion.toSQLDate(cursor.getString(2)));

                        Log.d("message",travel.getName());

                        travels.add(travel);

                    } while(cursor.moveToNext());

                }

            }

            travelList.setAdapter(new TravelListAdapter(conversion.travelArrayListToArray(travels)));

        } catch (ParseException e) {
            e.printStackTrace();
        }

    }
}

Adapter File

package com.hacker.wanderlust.adapter;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.hacker.wanderlust.R;
import com.hacker.wanderlust.bean.Travel;

public class TravelListAdapter extends RecyclerView.Adapter<TravelListAdapter.TravelViewHolder> {

    private Travel[] data;

    public TravelListAdapter(Travel[] data) {
        this.data = data;
    }

    @NonNull
    @Override
    public TravelViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

        Log.d("message","onCreate");

        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.travel_view, parent, false);
        return new TravelViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull TravelViewHolder holder, int position) {

        Travel travel=data[position];
        holder.tripName.setText(travel.getName());
        holder.tripDetails.setText(travel.getLocation());

    }

    @Override
    public int getItemCount() {
        Log.d("message","count: "+data.length);
        return data.length;
    }

    public class TravelViewHolder extends RecyclerView.ViewHolder {

        TextView tripName, tripDetails;

        public TravelViewHolder(@NonNull View itemView) {
            super(itemView);
            tripName = itemView.findViewById(R.id.tripName);
            tripDetails = itemView.findViewById(R.id.tripDetails);
        }
    }

}

travel_view.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="10dp"
    android:paddingTop="10dp">

    <TextView
        android:id="@+id/tripName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:textSize="34sp"></TextView>

    <TextView
        android:id="@+id/tripDetails"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:textSize="16sp"></TextView>

</LinearLayout>

activity_travel_view_list.xml

<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:id="@+id/travelListView"
    android:visibility="visible">

</androidx.recyclerview.widget.RecyclerView>

Dropbox link to entire project code: https://www.dropbox.com/s/5qs7ixiylrxzv41/Wanderlust.zip?dl=0

3 Answers

I tested the code(changed the part of getting data from DB) on my side, it works fine. My code:

public class TestRecyclerview02 extends AppCompatActivity {
    ArrayList<Travel> travels=new ArrayList<>();
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_recycleview02);

        try {
            RecyclerView travelList = (RecyclerView) findViewById(R.id.travelListView);

            travelList.setLayoutManager(new LinearLayoutManager(this));
            travelList.setHasFixedSize(true);

            // debug mock, not using the cursor.
            travels.add(new Travel("AAAA", "123"));
            travels.add(new Travel("BBBB", "1234"));
            travels.add(new Travel("CCCC", "123456"));
            travels.add(new Travel("DDDD", "1234567"));
            travels.add(new Travel("EEEE", "1234567"));
            travels.add(new Travel("FFFF", "12345678"));

            travelList.setAdapter(new TravelListAdapter( travels.toArray(new Travel[0])));

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

About the Adapter, I didn't change it, just added one line log in the method of onBindViewHolder

 Log.d("message","onBindViewHolder");

Regards the travel_view.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" // ===> pay attention to this 
    android:orientation="vertical">

    <TextView
        android:id="@+id/tripName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="tripName" />

    <TextView
        android:id="@+id/tripDetails"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="tripDetails" />

</LinearLayout>

And the result is ok. recycler view problem

The issue is that you are trying to access DB from the main thread. Your adapter is fine.

The issue was that in the recycler view (activity_travel_view_list.xml) the height and width were set to 0dp. I changed it to android:layout_width="match_parent" & android:layout_height="match_parent" and it worked. Thank you all for your contributions.

Related