RecyclerView不调用onCreateViewHolder或onBindView

时间:2015-03-11 17:06:21

标签: java android android-fragments android-recyclerview

没有收到任何错误,所有数据似乎都有效。出于某种原因,正在调用与视图相关的方法。我确定了以下内容:

  • 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);
    }
}

20 个答案:

答案 0 :(得分:81)

This may also help someone

First Use

recyclerView.setAdapter(adapter);

And then:

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

So it will look like this:

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

The order is reversed

答案 1 :(得分:28)

一直在追逐答案一个多小时。

在设置适配器之前,不要忘记调用这个衬垫。

recyclerView.setLayoutManager(new LinearLayoutManager(this));

似乎回收站视图没有内置默认布局管理器选项,因此我们必须以编程方式添加它。

如果你发现它有帮助,那就干杯。

答案 2 :(得分:19)

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

答案 3 :(得分:11)

我不知道这对任何人都有帮助,但我几乎有同样的问题。 我的问题不在于片段/类和回收器适配器。问题出现在父XML格式中,其中操作栏占用match_parent,其中片段被替换的FrameLayout -in没有获得任何可用的显示位置。这就是为什么这些方法没有被调用的原因。

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

答案 4 :(得分:8)

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

确保您没有不小心使用以下行。

recyclerView.setHasFixedSize(true);

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

答案 5 :(得分:4)

我还面临同样的问题,即onCreateViewHolderonBindView方法没有被调用,只有getItemCount被调用。因此RecyclerView的高度和重量基本上是问题,设置为wrap_content0dp。将其更改为某个值后修复了问题。

答案 6 :(得分:3)

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

确保高度和宽度正常且RecyclerView的大小正确。

答案 7 :(得分:2)

如果您将wrap_content作为列表的高度以及项目列表的高度,则不会显示任何内容,也不会调用您的recyclerView函数。

答案 8 :(得分:1)

就我而言,我将回收站视图适配器设置为 recyclerview.apply { adapter = adapter }

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

答案 9 :(得分:1)

实施FirebaseListAdapter时,需要注意以下几点以正确设置它。

  1. 检查xml中的recyclerview是否具有正确的所有属性。不要将包装内容用于 例如高度和宽度。
  2. 请检查是否已设置layoutManager并已处理setHasFixedSize()。
  3. 制作POJO类变量,使其与Firebase子属性匹配。
  4. 设置了FirebaseRecyclerOptions。
  5. FirebaseRecyclerAdapter的onCreateViewHolder()和onBindViewHolder在那里。
  6. 生命周期事件得到照顾。

注意- 使用wrap_content作为recyclerview的高度是任何人都可以做的最简单的错误之一。因此,请先检查一下。

答案 10 :(得分:1)

在我的情况下,它使用的是setHasStableIds(true);在适配器中,一些列表项在getItemID()中返回-1,所以我认为RecyclerView认为它们是相同的。

答案 11 :(得分:1)

我知道这个主题已经过时了,但如果你像我一样犯了同样的学习错误,你可能会觉得这很有帮助。

当我在一些关于RecyclerView的网站上学习并复制一些代码并适应我的上下文时,我创建了不同的变量(例如用户和数据),这些变量意味着做同样的事情,除了一些方法调用数据和一些正在呼叫用户。当你试图理解其他代码和java功能时,这是一个容易犯的错误(它总是发生在我身上)。

很高兴知道你可以在你的java代码中的任何地方打印你的控制台,这样你就可以很容易地调试。

祝你好运!

答案 12 :(得分:0)

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

<强> 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的组合。简单一点,看看它是否解决了你的问题

<?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>

答案 13 :(得分:0)

在我的案例中,Fragment内有一个RecyclerView ViewPager。出现此问题的原因是我使用了Fragment.getFragmentManager()代替Fragment.getChildFragmentManager来构建FragmentStatePagerAdapter的构造函数。

P.S。使用Layout Inspector可能对调试此类问题有很大帮助。

答案 14 :(得分:0)

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

答案 15 :(得分:0)

  

在我的情况下,我将RecyclerView的ID设置为&#34; recyclerView&#34;。似乎这个ID已经在某处定义了,因为当我将其更改为不同的ID时,适配器中的方法被正确调用。

Link to the answer

答案 16 :(得分:0)

请注意使用适配器的线程。
就我而言,问题是我的数据来自服务时从活动调用notifyDataSetChanged()。实际上,该方法是从后台线程调用的。但是该应用并未崩溃,并且Logcat(!)中没有任何内容。
因此我在UI线程中被称为notifyDataSetChanged(),问题得以解决。

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

答案 17 :(得分:0)

如果在设置recyclerview高度以匹配父级(0)时使用约束布局 发生此问题

答案 18 :(得分: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。

答案 19 :(得分:0)

我遇到了同样的问题,即onCreateViewHolder或onBindViewHolder都没有被调用。更改onCreateViewHolder方法以使用在构造函数中保存引用而不是执行parent.getContext()的Context应修复它:

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);