回收视图未调用 onCreateViewHolder 或 onBindView

没有得到任何错误和所有的数据似乎有效。由于某种原因,没有调用视图相关的方法。我已经确认了以下几点:

  • GetItemCount ()是唯一被调用的适配器方法,它返回一个正整数值(我知道这将是你们要查看的区域)

    • 构造函数,则成员变量有效。

    • 父视图是一个垂直的 LinearLayout; 没有 scrollview,也看不到任何其他具有自己的滚动属性的视图。

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

下面是片段中的声明,后面跟着适配器。任何帮助都会受到感激,因为这完全是莫名其妙的。

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);
}
}
63840 次浏览

确保回收视图不是来自 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"/>

我不知道这对谁有帮助,但我几乎有同样的问题。 我的问题既不在片段/类中,也不在回收器适配器中。问题出在父 XML 布局中,其中的操作栏采用 match_parent,而 FrameLayout-片段被替换的地方-没有任何可用的地方显示。这就是为什么没有调用这些方法。

我想,对于那些面临同样问题的人来说,类似的情况可能也是如此。仔细检查每个 XML 文件中的每个宽度和高度可能位于同一棵树中,因为问题似乎根本不在适配器中。

这也可能对某人有帮助

首次使用

recyclerView.setAdapter(adapter);

然后:

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

它看起来是这样的:

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

顺序颠倒了

更新:

现在我只用:

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

在 xml 中的 RecyclerView

我遇到过同样的问题,不管是 onCreateViewHolder 还是 onBindViewHolder 都没有被调用。将 onCreateViewHolder 方法改为使用在构造函数中保存引用的 Context,而不是使用 Parent.getContext ()应该可以解决这个问题:

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

这是我的两便士,刚花了三个多小时调试。

确保你没有不小心使用下面的行。

SetHasFixedSize (true) ;

只有在确定视图的大小为常数时,才设置固定大小。 如果不是,onCreateViewHolder 和 onBindView 方法可能根本不会被调用。

在我的例子中,我将我的回收视图的 ID 设置为“回收视图”。似乎已经在某个地方定义了这个 ID,因为当我将其更改为不同的 ID 时,适配器中的方法被正确调用。

链接到答案

我还面临同样的问题,即 onCreateViewHolderonBindView方法没有被调用,只有 getItemCount被调用。所以基本上问题是 RecyclerView的身高和体重被设置为 wrap_content或者 0dp。把它改成某种值后,问题就解决了。

我知道这个话题很老了,但是如果你像我一样犯了同样的学习错误,你可能会发现这个很有帮助。

当我在一些网站上学习关于回收视图和复制一些代码和适应我的上下文,我已经创建了不同的变量(例如用户和数据) ,这意味着做同样的事情,除了一些方法是调用数据和一些是调用用户。当你试图理解别人的代码和 java 功能时,这是一个很容易犯的错误(这种情况经常发生在我身上)。

很高兴知道您可以在 Java 代码中的任何地方在控制台中使用 println,这样就可以非常容易地进行调试。

祝你好运!

我最近遇到了这个问题,显然有很多可能的原因。尝试这些选项中的一个或组合,看看哪一个适合你:)

1. 布局经理
确保将布局管理器设置为回收者视图,如下所示

// create a layout manager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(my_context);
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);


// get recycler view
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_id);
// set
recyclerView.setLayoutManager(linearLayoutManager);

2. 固定尺寸
确保说明回收器视图是否具有固定大小

// set fixed size
recyclerView.setHasFixedSize(true); // or false depending on implementation

3. XML
确保你的回收器没有嵌套在太多的布局中,这可能会导致混乱,比如 ScrollView 和 RelativeLayout 的组合。让它变得简单,看看它是否修复了你的问题 < br >

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


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

已经找了一个多小时了。

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

recyclerView.setLayoutManager(new LinearLayoutManager(this));

看起来回收视图没有内置默认布局管理器选项,所以我们必须通过编程方式添加它。

如果你觉得有帮助的话,干杯。

在我的示例中,它使用 setHasStableIds (true) ; 在适配器中,当一些列表项在 getItemID ()中返回 -1时,所以我认为回收视图认为它们是相等的。

这已经很老了,但是在我的例子中,我使用的是 ConstraintLayout,而且高度设置错误,因此我的视图将有 0dp,然后适配器将保存以完成其工作,因为视图是0dp。

请确保高度和宽度是确定的,并且 RecyclerView是有一个积极的大小。

在我的例子中,a 有一个 FragmentRecyclerViewViewPager中。出现这个问题是因为我使用 Fragment.getFragmentManager()而不是 Fragment.getChildFragmentManager作为 FragmentStatePagerAdapter的构造函数。

使用布局检查器可能对调试这类问题有很大帮助。

如果将 wrash _ content 作为列表的高度以及项目列表的高度,则不会显示任何内容,也不会调用任何回收视图函数。

在我的例子中,在将 Activity 更改为 ViewModel 并使用 Binding 之后,我忘记从 onCreate方法中删除 setContentView。移除它,我的问题就解决了。

在实现 FirebaseListAdapter 时,需要注意以下几点才能正确设置它。

  1. 检查 xml 中回收视图的所有属性是否正确 例如,高度和宽度。
  2. 请检查 layoutManager 是否已设置,是否已处理 setHasFixedSize ()。
  3. 使 POJO 类变量与 firebase 子属性匹配。
  4. 设置了 Firebase迴收选项。
  5. Firebase珊瑚适配器的 onCreateViewHolder ()和 onBindViewHolder 都在这里。
  6. 处理生命周期事件。

注意- < strong > 使用 wrash _ content 作为 replerview 的高度是任何人都可能犯的最容易犯的错误之一。

小心使用适配器的线程。
In my case the problem was calling notifyDataSetChanged() from an activity when my data came from a service. Actually the method was calling from background thread. But the app didn't crash and there was nothing in Logcat (!).
所以我被称为 notifyDataSetChanged()在 UI 线程和问题解决了。

runOnUiThread(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});

当您将回收视图高度设置为匹配父(0)时,如果使用约束布局 这个问题出现了

我有以下情况:

@Override
protected void onStart() {
super.onStart();
Log.d("OnStart","Calling OnStart.");
FirebaseRecyclerOptions<Data> options = new FirebaseRecyclerOptions.Builder<Data>().setQuery(mDatabase, new SnapshotParser<Data>() {
@NonNull
@Override
public Data parseSnapshot(@NonNull DataSnapshot snapshot) {
Log.d("parseSnapshot",snapshot.child("name").getValue().toString());
return new Data(snapshot.child("name").getValue().toString(),
snapshot.child("description").getValue().toString(),
snapshot.child("id").getValue().toString(),
snapshot.child("date").getValue().toString());
}
}).build();
FirebaseRecyclerAdapter<Data,MyViewHolder> adapter = new FirebaseRecyclerAdapter<Data, MyViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i, @NonNull Data data) {
Log.d("OnBindViewHolder",data.getName());
myViewHolder.setName(data.getName());
myViewHolder.setDescription(data.getDescription());
myViewHolder.setDate(data.getDate());
}


@NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Log.d("OnCreateViewHolder","Creating the viewHolder");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.itemlayout,parent,false);
return new MyViewHolder(view);
}
};
recyclerView.setAdapter(adapter);
Log.d("OnStart","Exiting OnStart.");
}

没有调用 OnCreateViewHolder 和 OnBindViewHolder。

在我的例子中,我将回收器视图适配器设置为 recyclerview.apply { adapter = adapter }

两者都引用 getAdapter () ,因此将我的适配器变量名重命名为 folderAdapter

在我的例子中,我一直在使用分页库和 PagingDataAdapter。我设置了一个适配器后,它的所有数据已经从一个 PagingSure 和回收视图没有显示任何东西。我在设置适配器之后调用 adapter.refresh()解决了这个问题。像这样:

recyclerView.adapter = myAdapter
myAdapter.refresh()

我也有同样的问题。在我的情况下,刷新几次后,回收视图就空了。例如,当我单击一个项目并从另一个活动返回时。我有数据,但数据没有设置为回收视图,没有错误。

我在 OnCreate上创建了如下的回收视图方法:

        StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
binding.recyclerCommodityList2.setLayoutManager(staggeredGridLayoutManager);
binding.recyclerCommodityList2.addItemDecoration(new GridSpacingItemDecoration(2, 0, true));
adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(cardList.getCard(), context);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);


binding.recyclerCommodityList2.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NotNull RecyclerView recyclerView, int dx, int dy) {
visibleItemCount = staggeredGridLayoutManager.getChildCount();
totalItemCount = staggeredGridLayoutManager.getItemCount();


if (dy > 0) { //check for scroll down


pastVisibleItems = staggeredGridLayoutManager.findFirstVisibleItemPositions(null)[1];


if ((visibleItemCount + pastVisibleItems) >= totalItemCount / 2 ) {


if (loading) {
loading = false;
callGetListOfCommodity(selectedCategory); // call api again
}
}


}
}
});

我把数据放在 api onResponse 方法上,像这样:

adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(result.getCard(), MyTamukActivity.this);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);

所以我在 onResponse 方法上安排了一个新的布局管理器,像这样:

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
binding.recyclerCommodityList2.setLayoutManager(staggeredGridLayoutManager);


adapterCommodityList = new RecyclerAdapterMyCommoditiAndPost(result.getCard(), MyTamukActivity.this);
binding.recyclerCommodityList2.setAdapter(adapterCommodityList);

这个解决方案奏效了,但是有时候回收站还是空了。

所以这是我的最终解决方案:

我从 onCreate 中删除回收视图,然后在 继续方法中创建回收视图。所以布局经理总是正确地坐在回收视图上。

如果您有同样的问题,请检查您的布局管理器,以及您是如何在回收视图上设置它的。

有时候,如果将 viewpager 放在 scrollview 中,将会收缩父视图以及 viewpager 及其子片段,就会发生这个 bug。 因此,随着现在查找子片段 onCreateView 和 onBindView 方法将不会被调用。 只需删除 scrollview 或向布局中添加权重即可,这样视图就不会收缩。