Slava
Slava

Reputation: 439

Why RecyclerView onBindViewHolder called just once?

Have a strange bug in my code. I use Recycler View (used in the past without any problem). I created test ArrayList for showing it in Recycler but I get the only first row in RecyclerView and after it, the app stops (not crashes) like ArrayList was finished.

My Main Code:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view =  inflater.inflate(R.layout.fragment_all_tab, container, false);

    Activity activity = getActivity();

    //TODO: For testing ONLY
    ArrayList<Order> orders = new ArrayList<>();
    for(int i = 0; i < 10; i++) {
        orders.add(new Order(i, i, i));
    }

    // Initialising Orders Recycler View.
    OrderAdapter orderAdapter = new OrderAdapter(activity, orders);
    RecyclerView recyclerViewOrders = (RecyclerView) view.findViewById(R.id.recylerViewAllDiners);
    recyclerViewOrders.setLayoutManager(new LinearLayoutManager(activity));
    recyclerViewOrders.setAdapter(orderAdapter);

    return view;
}

Adapter:

package com.slavafleer.tipcalculator;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;

/**
 * Order Adapter for Order Recycler View
 */
public class OrderAdapter extends RecyclerView.Adapter<OrderHolder> {

    private Context context;
    private ArrayList<Order> orders;

    public OrderAdapter(Context context, ArrayList<Order> orders) {

        this.context = context;
        this.orders = orders;
    }

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

        LayoutInflater layoutInflater = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        View view = layoutInflater.inflate(R.layout.item_order, parent, false);

        return new OrderHolder(view);
    }

    // TODO: why it has been done just once ?
    @Override
    public void onBindViewHolder(OrderHolder holder, int position) {

        Order order = orders.get(position);

        holder.bindOrder(order);
    }

    @Override
    public int getItemCount() {
        return orders.size();
    }
}

Holder:

package com.slavafleer.tipcalculator;

import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;

/**
 * Order Holder for Order Recycler View
 */
public class OrderHolder extends RecyclerView.ViewHolder {

    private TextView textViewOrderId;
    private TextView textViewDinerId;
    private TextView textViewPrice;

    public OrderHolder(View itemView) {
        super(itemView);

        textViewOrderId = (TextView) itemView.findViewById(R.id.textViewOrderId);
        textViewDinerId = (TextView) itemView.findViewById(R.id.textViewDinerId);
        textViewPrice = (TextView) itemView.findViewById(R.id.textViewPrice);
    }

    // Bind Data Object to the Views.
    public void bindOrder(Order order) {

        textViewOrderId.setText(order.getOrderId() + "");
        textViewDinerId.setText(order.getDinerId() + "");
        textViewPrice.setText(order.getPrice() + "");
    }


}

Upvotes: 12

Views: 8279

Answers (5)

Andrew
Andrew

Reputation: 37969

Check it out if the outermost element of the item layout height IS NOT set to "match_parent" value, but is set to "wrap_content" or some Ndp value. Example:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout mlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"  // Just like this!
    >
    <TextView
        android:id="@+id/item_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    />
</LinearLayout>

Upvotes: 7

Snow Albert
Snow Albert

Reputation: 577

I have also encountered the same problem because the wrong height parameter is set.

It should be wrap_content, but I set the layout-height = match_parent.

So the first list item will occupy all the space in the list view, so it only displays a list item.

Upvotes: 6

sssvrock
sssvrock

Reputation: 569

My Previous commit Recyclerview support version : 24.2.1

Later I updated build.gradle by adding following:

> configurations.all {
   >     resolutionStrategy.eachDependency { DependencyResolveDetails details ->
   >         def requested = details.requested
   >         if (requested.group == 'com.android.support') {
   >             if (!requested.name.startsWith("multidex")) {
   >                 details.useVersion '25.3.0'
   >             }
   >         }
   >     } }

So after this all support versions have been upgraded to 25.3.0 except for "multidex". This means recyclerview version also upgraded.

Here is the issue, after this running a build My recyclerview onbindviewholder method is not called.

Any how I found this cause after commenting above code and running, able to use my recyclerview

Hope this may useful for someone.

Regards Vinod

Upvotes: 0

Slava
Slava

Reputation: 439

At first, Febi Mathew, thank you for trying to help me with this.

I found how to fix it.

My original line in Gradle was

compile 'com.android.support:recyclerview-v7:23.2.0'

after I did sample just for Recycler and it was the same, I tried an older version

compile 'com.android.support:recyclerview-v7:23.1.1'

And it worked perfectly. So I suppose it is not my bug =). If you know how to report for this bug, you welcome to do it.

Update: What was wrong is I didn't set layout-height for my item as wrap content. And from reason that I don't understand on old version it did not matter but on a new one it just takes all my screen and I didn't think to try to slide it down.

Upvotes: 12

Febi M Felix
Febi M Felix

Reputation: 2839

Can you try this?

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater layoutInflater = (LayoutInflater)
            context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    View view = layoutInflater.inflate(R.layout.item_order, parent, false);

    return new OrderHolder(view);
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    Order order = orders.get(position);

    OrderHolder orderHolder = (OrderHolder)holder;
    orderHolder.bindOrder(order);
}

Upvotes: 0

Related Questions