RecyclerView没有调用onCreateViewHolder或onBindViewHolder方法

72

没有出现任何错误,所有数据似乎都是有效的。但不知道为什么,与视图相关的方法都没有被调用。我已经确保以下内容:

  • 只有getItemCount()适配器方法被调用,并返回正整数值(我知道这将是你们关注的领域)

    • 构造函数被调用,成员变量有效。

    • 父视图是垂直LinearLayout;没有滚动视图或任何其他具有自己的滚动属性的视图。

    • 包含片段视图已创建并显示在屏幕上。

这是片段中的声明,后面是适配器。非常感谢帮助,因为这让我完全困惑了。

SubMenuAdapter adapter = new SubMenuAdapter(getActivity(), mContentItems);
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(adapter);
public class SubMenuAdapter extends RecyclerView.Adapter<SubMenuAdapter.ViewHolder> {
private static final String TAG = String.format("==> %S", SubMenuAdapter.class.getSimpleName());

private final List<ContentItem> mContentItems;
private Context mContext;

public SubMenuAdapter(Context context, List<ContentItem> contenItems) {
    Log.d(TAG, "Constructor called");
    mContentItems = contenItems;
    mContext = context;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Log.d(TAG, "onCreateViewHolder called");
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_resource_efficiency, parent, false);
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    Log.d(TAG, "onBindViewHolder called");

    ContentItem item = mContentItems.get(position);
    holder.textName.setText(item.getName());
    FontSetter.setMyriadProRegular(mContext, holder.textName);
    Picasso.with(mContext).load("file://" + item.getPreviewImageDefault()).into(holder.imageIcon);
}

@Override
public int getItemCount() {
    Log.d(mContext, String.format("getItemCount: %d", mContentItems.size()));
    return mContentItems.size();
}

// ViewHolder
public static class ViewHolder extends RecyclerView.ViewHolder {

    TextView textName;
    ImageView imageIcon;

    public ViewHolder(View view) {
        super(view);
        textName = (TextView) view.findViewById(R.id.tv_resource_efficiency_option);
        imageIcon = (ImageView) view.findViewById(R.id.iv_resource_efficiency_icon);
    }
}

2
我尝试了'match_parent'、'wrap_content'和400dp的大小,都设置了蓝色背景值,但仍然没有显示。我还明确将可见性设置为visible——仍然没有显示。虽然我并不指望它会出现,因为方法没有被调用来创建和绑定视图。 - Conti
1
我有同样的问题,适配器中的数据已更改,调用了notifyDataSetChanged,执行了setAdapter,片段仍然存在并绘制,但onCreateViewHolder或onBindView没有被调用。所有视图都可见。 - Raskilas
1
我有同样的问题,我的适配器方法getItemCount()返回大于0,但仍然没有正面的结果。我认为ScrollView和RecycleView一起工作存在问题。 - Stoycho Andreev
1
这也发生在我身上。奇怪的是,我在同一项目中有另一个完美运行的RecyclerView。 - Martin Epsz
2
@IgorGanapolsky 我得搜索一下我的BitBucket找到它,我在7个月前提交了这个问题,并在花费数小时后放弃了。但请检查我的第三个要点,“父视图是一个垂直的LinearLayout;没有滚动视图,也没有任何其他具有自己滚动属性的视图。”层次结构中根本没有滚动视图。 - Conti
显示剩余9条评论
24个回答

110

这也许对某人有所帮助

第一次使用

recyclerView.setAdapter(adapter);

然后:

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

那么它看起来会像这样:

recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

顺序已经颠倒

更新:

现在我只是使用:

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

在xml中的RecyclerView


3
你有没有任何关于为什么必须这样的解释链接? - igoris
嗨@igoris,不幸的是我没有,我只是通过试错找到了这个解决方案。 - Aerim
10
LayoutManager 是我犯过无数次的最令人烦恼的错误,而且我总是会忘记它。我打算把“设置布局管理器!”挂在墙上并装裱起来 :) - daneejela
我认为,如果在设置适配器之前设置“LayoutManager”,它将已经测量了一些内容,并且不认为需要再次进行测量。这只是理论,没有证明。 - Aerim
1
太棒了!但这是你的答案和删除@VenakteshShukla的答案的组合。 - who-aditya-nawandar

50

我已经追寻答案一个多小时了。

在设置适配器之前,不要忘记调用这个一行代码。

recyclerView.setLayoutManager(new LinearLayoutManager(this));

看起来RecyclerView没有默认的布局管理器选项,因此我们必须通过编程方式添加它。

如果你发现这个对你有帮助,那就太好了。


是的,我忘记了这一点,并且尝试了整整一天,最终您的答案帮助我进行了交叉检查。 - krishnamurthy
知道那种感觉,只需要一行代码就解决了。很高兴它有所帮助。 - ralphgabb

19

请确保您的recycle view不是嵌套在nestedscrollview中的子元素

例如,以下代码将无法正常工作。

<android.support.v4.widget.NestedScrollView
    android:id="@+id/responder_scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/darkGray"
    android:clipToPadding="false"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.v7.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            app:cardElevation="@dimen/spacing_medium"
            app:cardUseCompatPadding="true">

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <TextView
                    android:id="@+id/responder_testimonial"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentTop="true"
                    android:text="Testimonial"
                    android:textSize="@dimen/general_font_size" />

                <TextView
                    android:id="@+id/responder_counter_testimonial"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_toRightOf="@+id/responder_testimonial"
                    android:text="170"
                    android:textSize="@dimen/general_font_size_small" />

                <Button
                    android:id="@+id/responder_btn_testimonial"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentTop="true"
                    android:text="Go" />

               <view
                    android:id="@+id/responder_list_testimonial"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_below="@+id/responder_testimonial"
                    class="android.support.v7.widget.RecyclerView"/>
            </RelativeLayout>
        </android.support.v7.widget.CardView>

    </FrameLayout>
</android.support.v4.widget.NestedScrollView>

然后我使用,

<android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="true">

<view
    android:id="@+id/responder_list_testimonial"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/responder_testimonial"
    class="android.support.v7.widget.RecyclerView"/>

:这是一个空的段落标签。

2
实际上,这个问题是由于我在ScrollView中嵌套了RecyclerView引起的。为了解决这个问题,我在RecyclerView上设置了一个自定义的LayoutManager。 - IgorGanapolsky
嗨,是的,你说得对,我也使用自定义LayoutManager。 - raditya gumay
我花了很长时间在这上面。尽管我的回收视图不是滚动视图或嵌套滚动视图的直接子项,但我还是遇到了这个问题。这是一个已知的错误还是设计如此? - startoftext
我不确定。但是如果你想使用NestedScrollView,你也应该在其中使用一个View。 - raditya gumay
相反地,将ScrollView替换为NestedScrollView后,代码开始工作(ScrollView > LinearLayout > RecyclerView)。无论如何,有了您的帮助。 - Vassily
是的,你可以做到。 - raditya gumay

11

我不知道这对任何人是否有用,但我几乎遇到了完全相同的问题。

我的问题不在于片段/类或回收器适配器。问题出在父级XML布局中,actionbar采用了match_parent,而fragment被替换的FrameLayout没有任何可用的位置来显示。这就是为什么方法没有被调用的原因。

我猜想那些面临相同问题的人可能会遇到类似的情况。请仔细检查每个XML文件中的每个宽度和高度,因为问题似乎根本不在适配器中。


你救了我!!我正在做完全相同的事情。 - nikhil
很高兴我的回答有所帮助。 - Abdul-Rahman Ahmad

11

我的一点建议。刚刚花了三个多小时调试这个问题。

注意不要随意使用以下代码:

recyclerView.setHasFixedSize(true);

仅在确定视图具有恒定大小时才设置固定大小。否则,可能根本不会调用onCreateViewHolder和onBindView方法。


1
非常感谢,这对我很有帮助。同时,我在这里提到了相同的答案:[https://dev59.com/3V4c5IYBdhLWcg3wiKyU#42054411] - venky
1
我已经到处寻找了。而问题正是如此! - Gabriel

8

我曾经遇到过同样的问题,即onCreateViewHolderonBindView方法没有被调用,只有getItemCount被调用。所以这基本上是由于RecyclerView的高度和宽度设置为wrap_content0dp引起的。将其更改为某个值可以解决问题。


4

这个问题已经很老了,但在我的情况下,我使用了 ConstraintLayout 并且高度设置错误,所以我的视图会有 0dp ,然后适配器会保存它的工作,因为视图是 0dp。

确保高度和宽度正确,并且 RecyclerView 具有正数大小。


3

在我的情况下,将Activity更改为ViewModel并使用Binding后,我忘记从onCreate方法中删除setContentView。通过删除它,我的问题得到了解决。


谢谢你!解决了我的问题。 - Nadim Ansari

2
如果您将列表的高度设置为wrap_content,同时将项目列表的高度也设置为wrap_content,则不会显示任何内容,并且不会调用recyclerView的任何功能。

2
实现 FirebaseListAdapter 时,需要注意以下几点以正确设置:
  1. 检查 xml 中的 recyclerview 属性是否正确。例如,不要使用 wrap_content 作为高度和宽度。
  2. 请检查 layoutManager 是否已设置,并确保 setHasFixedSize() 已处理。
  3. 使 POJO 类变量与 firebase 子属性匹配。
  4. 设置 FirebaseRecyclerOptions。
  5. 存在 FirebaseRecyclerAdapter 的 onCreateViewHolder() 和 onBindViewHolder。
  6. 处理生命周期事件。
注意 - 使用 wrap_content 作为 recyclerview 的高度是任何人都可能犯的最简单的错误之一。因此,请首先检查。

使用Firestore:第一点对我有效。wrap_content,我怎么能忘记呢:-),感谢添加的注释。谢谢帮助。 - Sankalp
总是乐意帮助 :) - Prashant Paliwal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接