Recyclerview not call any Adapter method :onCreateViewHolder,onBindViewHolder,
Asked Answered
L

9

60

my RecyclerView do not call onCreateViewHolder, onBindViewHolder, therefore, does not appear nothing in recyclerview. I put logs for debugging, and no log is shown. What can be?

My adapter:

public class CommentListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>{
private static final int EMPTY_VIEW = 10 ;
private ArrayList<comment> mItems;
Boolean firstTime = true;
private Typeface mTf = null;
Context mContext;
public CommentListAdapter(Context context,ArrayList<comment> items){
    Log.e("Adapter", "constructor Called");
    this.mItems = items;
    mContext = context;
}
public class EmptyViewHolder extends RecyclerView.ViewHolder {
    public EmptyViewHolder(View itemView) {
        super(itemView);
    }
}
public class ViewHolder extends RecyclerView.ViewHolder{
    TextView mAuthorName;
    TextView mMessage;
    NetworkImageView mThumbnail;
    public ViewHolder(View itemView) {
        super(itemView);
        mAuthorName = (TextView)itemView.findViewById(R.id.author_name);
        mMessage = (TextView)itemView.findViewById(R.id.message);
        mThumbnail = (NetworkImageView)itemView.findViewById(R.id.author_avatar);
    }

}

public void add(comment item, int position) {
    mItems.add(position, item);
    notifyItemInserted(position);
}

public void remove(comment item) {
    int position = mItems.indexOf(item);
    mItems.remove(position);
    notifyItemRemoved(position);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType){
    Log.e("Adapter", "onCreateViewHolder Called");
    View v;
    if(firstTime){
        mTf = BBcTypeFace.getTypeFace(parent.getContext().getApplicationContext(),"font/bbc.ttf");
        firstTime = false;
    }
    if( viewType == EMPTY_VIEW){
        v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.comment_empty_row,parent,false);
        EmptyViewHolder evh = new EmptyViewHolder(v);
        return evh;
    }else {
        v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.comment_row, parent, false);
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
    Log.e("Adapter", "onBindViewHolder Called");
    if(viewHolder instanceof ViewHolder) {
        ViewHolder holder = (ViewHolder)viewHolder;
        comment c = mItems.get(position);
        Log.e("Adapter", "Comment is\n: " + c.toString());
        final ViewHolder finalHolder = holder;
        ImageRequest request = new ImageRequest(c.author_img_link, new Response.Listener<Bitmap>() {
            @Override
            public void onResponse(Bitmap bitmap) {
                if (bitmap != null) {
                    finalHolder.mThumbnail.setImageBitmap(bitmap);
                }
            }
        }, 0, 0, null,
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError volleyError) {
                        VolleyLog.e("ImageLoader", volleyError.getMessage());
                        VolleyLog.e("ImageLoader", volleyError.getStackTrace());
                    }
                });
        GetVideoInfo.getInstance(mContext.getApplicationContext()).addToRequestQueue(request);
        holder.mAuthorName.setText(c.author_name);
        holder.mMessage.setText(c.Message);
        holder.mMessage.setTypeface(mTf);
        holder.mAuthorName.setTypeface(mTf);
    }
}
@Override
public int getItemCount() {
    Log.e("Adapter", "getItemCount() Called");
    return (mItems.size() > 0 ? mItems.size() : 1);
}
@Override
public int getItemViewType(int position) {
    Log.e("Adapter", "getItemViewType() Called");
    if (mItems.size() == 0) {
        return EMPTY_VIEW;
    }
    return super.getItemViewType(position);
}}

I will use public void add(comment item, int position){...} to add item in RecyclerView.

in Fragment :

private RecyclerView mRecyclerView;
private CommentListAdapter mAdapter;
private LayoutManager mLayoutManager;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
....

    mLayoutManager = new LinearLayoutManager(getActivity());
    mAdapter = new CommentListAdapter(getActivity(),new ArrayList<comment>());
    mRecyclerView = (RecyclerView)rootView.findViewById(R.id.comment_list);
    mRecyclerView.setHasFixedSize(true);
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setAdapter(mAdapter);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());

    makeJsonObjectRequest(mItem.url);
    return rootView;
}

XML Files :

<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/scrollView"
    android:background="@android:color/white"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true"

    android:layout_alignParentBottom="true">

    ....
        <RelativeLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
.....

            <android.support.v7.widget.RecyclerView
                android:id="@+id/comment_list"
                android:layout_width="match_parent"
                android:layout_height="match_parent">

            </android.support.v7.widget.RecyclerView>
....
        </RelativeLayout>
    ....
</ScrollView>

comment_row xml file :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:orientation="horizontal"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="wrap_content"
android:gravity="right"
android:background="@android:color/darker_gray">

<LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
    android:gravity="right">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:id="@+id/author_name"
            android:layout_alignParentTop="true"
            android:layout_toLeftOf="@+id/author_avatar"
            android:layout_toStartOf="@+id/author_avatar"
            android:gravity="right" />

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/message"
            android:layout_below="@+id/author_name"
            android:layout_toLeftOf="@+id/author_avatar"
            android:layout_toStartOf="@+id/author_avatar"
            android:gravity="right" />
        </LinearLayout>

<com.android.volley.toolbox.NetworkImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/author_avatar"
    android:layout_alignParentTop="true"
    android:layout_alignParentRight="true"
    android:layout_alignParentEnd="true"
    android:minHeight="150dp"
    android:minWidth="150dp" /></LinearLayout>

I will add item to RecyclerView with this code :

JsonObjectRequest jsonObjReqComment = new
             JsonObjectRequest(Request.Method.GET,urlJsonObj+"#comment", null,
                     new Response.Listener<JSONObject>() {
                         @Override
                         public void onResponse(JSONObject response) {
                             try {
                                 JSONArray res = response.getJSONArray("response");
                                 //Log.e("Comment","Count:"+response.toString());
                                 //Log.e("Comment","Count:"+res.length());
                                 for (int i = 0; i < res.length(); i++) {
                                     JSONObject thread = res.getJSONObject(i);
                                     JSONObject author_json = thread.getJSONObject("author");
                                     int dislikes = thread.getInt("dislikes");
                                     int likes = thread.getInt("likes");
                                     String Message = thread.getString("message");
                                     //get Author info
                                     String author_img_link = author_json.getJSONObject("avatar").getString("permalink");
                                     String author_name = author_json.getString("name");
                                     comment c = new comment(dislikes,likes,Message,author_img_link,author_name);
                                     //Log.e("Comment",c.toString());
                                     //commentsList.add(c);
                                     mAdapter.add(c,0);
                                 }

                             } catch (JSONException e) {
                                 Log.e("OnResponse","Error JSON");
                                 e.printStackTrace();
                             } catch (Exception e){
                                 Log.e("OnResponse","Error Exception");
                                 e.printStackTrace();
                             }


                         }
                     }
                     , new Response.ErrorListener() {
                 @Override
                 public void onErrorResponse(VolleyError error) {
                     VolleyLog.d("vOLLEY", "Error: " + error.getMessage());
                     // hide the progress dialog

                 }
             }
             ){
                 @Override
                 public Map<String, String> getHeaders(){
                     Map<String, String> headers = new HashMap<String, String>();
                     headers.put("User-agent", "Comment");
                     return headers;
                 }
             };
Lumper answered 23/1, 2015 at 17:36 Comment(20)
A row matching parent on both width and height? Are you sure you want that?Twin
You are not even getting getItemCount ? That is quite weird. Besides that, your empty view implementation is wrong. When you add an item for the first time, you should first call notifyItemRemoved(0) so that RV knows item 0 is removed. Also, your getItemViewType implementation is quite risky as RV may call it while EMPTY view is a part of the UI but new items are just added so this is quite risky. I would suggest to have a boolean in your adapter that sets shouldEmpty view and when it is set to false, you should call notifyItemRemoved(0). Make sure it happens before adding items .Brio
@PedroOliveira I changed to android:layout_width="match_parent" android:layout_height="wrap_content" , dosen't change any thingLumper
@Brio RecyclerView just call getItemCount(), but RecyclerView don't call other Override methods, I try this code without EmptyViewHolder with Initial data, but I have this problem too, excuse me, if my english is poorLumper
So not even a call to onCreate or onBind for EMPTY View? also, did you debug if add is being called?Brio
I think when getItemCount() returns 0, it wont call other methods. Can you show us the part where you're actually adding items to the adapter ?Utas
@Brio yes I call add method too, and I see this problemLumper
@ShivamVerma getItemCount() return >= 1, I will update my question.Lumper
@ShivamVerma I add some code at end of my question.Lumper
I think, the problem is with this line : mAdapter.add(c,0); You're always adding the item at the 0th position which tells android that the item at position at 0 has changed and it tries to just redraw the 0th item position. Can you try adding something like mAdapter.add(c,i);Utas
@ShivamVerma, nope, calling add(c, 0) only means it will add the new item to position 0 and push other items down (so empty view moves to position 1).Brio
Ah yes, sorry, just read the documentation.Utas
@SanatiSharif, if you can upload a sample project, i'm happy to take a look at it.Brio
@Brio Is there a possibility of Wrong Thread Exception ? Given that mAdapter.add(c,0); is possibly being called from a background thread and the notifyItemInserted() method needs to run on the UI thread ?Utas
@ShivamVerma nope, Volley onResponse run on main (UI) ThreadLumper
@Brio its huge project, I can't upload it,Lumper
Ok, one last thing. Check the height of your RV. Try setting a fixed height. Maybe the combination of ScrollView, RL and RV causes it to have 0 height (which would explain not getting any views because there is no room). I don't understand why you have that setup anyways. Besides that, I cannot see what else is going wrong. If there was a bug in RV like this, it would be pretty obvious and surface itself way before.Brio
@Brio excuse me I'm new in android programing, what is RL and RV ? Thanks,Lumper
RL = relative layout RV = recyclerviewBrio
Always specify layout manager. I keep forgetting about that!Eburnation
H
36

As @yigit guess the combination of ScrollView, RelativeLayout causes this problem, Just make more room for RecyclerView.

Headman answered 23/1, 2015 at 22:3 Comment(3)
Thanks. Preview the xml to ensure that the recycle view is displayed.Sanitarian
Mine is not inside a ScrollView, yet still having this problem.Lifetime
I had my RecyclerView inside ConstraintLayout so it was not calling any adapter methods. Crazy :xAntonetteantoni
C
193

Other than @SanatiSharif's and @sohrab's answer, you have to follow below mandatory step.

Make sure you call setLayoutManager, something like below.

recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));

before setting adapter into recyclerView, otherwise it is not going to work. You can customize it if you need. this link will give you some idea of how LayoutManager works.

Capitalization answered 7/4, 2016 at 23:28 Comment(2)
the question is, why is this needed? This answer solves my problem but I don't know why.Diarrhea
You can also set this via XML: app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"Genus
H
36

As @yigit guess the combination of ScrollView, RelativeLayout causes this problem, Just make more room for RecyclerView.

Headman answered 23/1, 2015 at 22:3 Comment(3)
Thanks. Preview the xml to ensure that the recycle view is displayed.Sanitarian
Mine is not inside a ScrollView, yet still having this problem.Lifetime
I had my RecyclerView inside ConstraintLayout so it was not calling any adapter methods. Crazy :xAntonetteantoni
L
19

If RecyclerView gets put into a ScrollView, then during measure step its height is unspecified (because ScrollView allows any height) and gets equal to minimum height (as per implementation) which is apparently zero.

ref : android: RecyclerView inside a ScrollView

Solution : - put views in row of RecyclerViews - Calculate the size of the list items and set the height of the ListView programmatically http://vardhan-justlikethat.blogspot.com/2014/04/android-listview-inside-scrollview.html

Lumper answered 24/1, 2015 at 17:47 Comment(0)
T
7

Might have been a different case but for me I just forgot to set the Layout Manager as follows:

LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recycler.setLayoutManager(layoutManager);

Hope it helps :)

Turd answered 10/11, 2017 at 0:42 Comment(0)
A
6

Its late but hope it will help somone. try either of the following:

first solution: make sure you haven't use this line unnecessarily

recyclerView.setHasFixedSize(true);

second solution: make sure you set layout manager to recyclerView

recycler.setLayoutManager(new LinearLayoutManager(this));

third solution: you getItemCount returns 0, So RecyclerView never tries to instantiate a view. Make it return something greater than 0

Accordingly answered 4/5, 2017 at 6:14 Comment(0)
S
3

In my Case I was using Fragment-> ViewPager and Tablayout -> Inside viewpagers item I used RecyclerView.

So Instead of calling ViewPagerAdapter(getChildFragmentManager()) , I was calling ViewPagerAdapter(getSupportFragmentManager()) , that is why any of my recycler adapter item is not getting called.

So proper way to set the ViewPagerAdapter within a fragment is

ViewPagerAdapter(getChildFragmentManager())

Supersaturated answered 2/6, 2018 at 11:48 Comment(0)
A
1

In my case i had this structure

<ScrollView>
    <RelativeLayout>
        <android.support.v7.widget.RecyclerView/>

    </RelativeLayout>
</ScrollView>

i solved the problem remove Relative

<ScrollView>

        <android.support.v7.widget.RecyclerView/>

</ScrollView>
Antiar answered 31/7, 2017 at 4:41 Comment(0)
T
1

Is kind of silly, but another thing that can block the calls to the methods is to declare the visibility of the view as GONE.

android:visibility="gone"

recyclerView.setVisibility(View.GONE);

Any of these will block the call of the methods in RecyclerView.Adapter

I hope it can help someone.

Tapp answered 18/7, 2018 at 15:30 Comment(0)
S
1

I had a similar issue but none of the above answers helped me.

Finally, I found out I made a mistake when creating and binding the view for the Fragment in which my RecyclerView was living:

Problematic Code

FormPageFragment.onCreate

binding=FormPageBinding.inflate(layoutInflater)

but in onCreateView I did this:

FormPageFragment.onCreateView

return inflater.inflate(R.layout.form_page, container, false)

and later in onStart setting the adapter like this:

FormPageFragment.onStart

binding.formContent.adapter=FormEntriesAdapter(page, viewModel.enteredData)
        

Solution

But this was rubbish. It should have all be done in onCreateView and of course the binding.rootView needs to be returned as view, other wise the bindings views are not attached to the layout and setting any adapters on them has no effect.

working version of onCreateView

 binding=FormPageBinding.inflate(layoutInflater)
 return binding.root
        

So it was more a problem with fragment instanciation, creating and binding the correct views than with the RecyclerView itself.

Secrete answered 23/6, 2021 at 9:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.