【问题标题】:Recyclerview not call onCreateViewHolderRecyclerview 不调用 onCreateViewHolder
【发布时间】:2023-03-17 22:54:01
【问题描述】:

我的RecyclerView 不调用onCreateViewHolderonBindViewHolder 甚至MenuViewHolder 构造函数,因此RecyclerView 中没有出现任何内容。 我放了调试日志,没有显示日志。 可能是什么问题?

我的适配器:

public class MenuAdapter extends RecyclerView.Adapter<MenuAdapter.MenuViewHolder> {
private LayoutInflater inflater;
List<Menu> data = Collections.emptyList();

public MenuAdapter(Context context, List<Menu> data) {
    Log.i("DEBUG", "Constructor");
    inflater = LayoutInflater.from(context);
    Log.i("DEBUG MENU - CONSTRUCTOR", inflater.toString());
    this.data = data;
    for(Menu menu: this.data){
        Log.i("DEBUG MENU - CONSTRUCTOR", menu.menu);
    }
}

@Override
public MenuViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = inflater.inflate(R.layout.row_menu, parent, false);
    MenuViewHolder holder = new MenuViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(MenuViewHolder holder, int position) {
    Log.i("DEBUG MENU", "onBindViewHolder");
    Menu current = data.get(position);
    holder.title.setText(current.menu);
}

@Override
public int getItemCount() {
    return 0;
}

class MenuViewHolder extends RecyclerView.ViewHolder {
    TextView title;
    ImageView icon;

    public MenuViewHolder(View itemView) {
        super(itemView);
        title = (TextView) itemView.findViewById(R.id.menuText);
    }
}

我的自定义行 XML:

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

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/menuText"
    android:text="Dummy Text"
    android:layout_gravity="center_vertical"
    android:textColor="#222"/>

和我的片段:

public NavigationFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mUserLearnedDrawer = Boolean.valueOf(readFromPreferences(getActivity(), KEY_USER_LEARNED_DRAWER, "false"));
    if (savedInstanceState != null) {
        mFromSavedInstaceState = true;
    }
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment

    View view = inflater.inflate(R.layout.fragment_navigation, container, false);
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.drawer_list);
    MenuAdapter adapter = new MenuAdapter(getActivity(), getData());
    recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
    recyclerView.setAdapter(adapter);
    return view;
}

【问题讨论】:

  • 为什么要设置 recyclerView.setAdapter(adapter); 2次?
  • 转到您的 xml。并更改您的布局以包装内容。一个元素隐藏了下一个元素,因此方法不起作用!
  • 此问题的另一个原因是错误地使项目布局与父项的高度匹配,因此一次只显示一个项目。
  • 在我的例子中帮助这个:invoicesRecyclerView.setHasFixedSize(true) invoicesRecyclerView.setLayoutManager(GridLayoutManager(this, 1))

标签: java android android-recyclerview


【解决方案1】:

另一个是确保将布局管理器设置为 RecyclerView:

recycler.setLayoutManager(new LinearLayoutManager(this));

【讨论】:

  • 我经常回到这个答案……
  • 这甚至不在任何教程中;人们应该怎么知道这一点?几乎所有 android 模式都一样
  • 另一种指定布局管理器的方式可以是这样的xml属性:app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
  • 我花了比我想承认的时间更长的时间来整理
  • 你成就了我的一天!!!
【解决方案2】:

您的getItemCount 方法returns 0。所以RecyclerView 从不尝试实例化视图。让它返回一些东西greater than 0

例如

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

【讨论】:

  • 哦,天哪,我现在感觉好傻! :facepalm: 谢谢你!
  • 我刚刚为此浪费了一个小时,因为 getItemCount 远低于所有其他代码,而我没有看到它。 :|
  • 我有一个自定义适配器,忘记将我的 itemcount 设置为我的收藏大小
  • 我的项目计数是 3 仍然不可见,onBind 或 onCreateHolder 中没有调试点...但它来自 getItemCount
  • 天哪!我也在为此苦苦挣扎,想弄清楚为什么我的断点没有命中,现在我知道了……哈哈!该死!!!谢谢!
【解决方案3】:

添加后我忘记添加下面的行了

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

【讨论】:

【解决方案4】:

我真的真的希望有一天这对某人有所帮助。我刚刚花了一个多小时在这个疯了!

我有这个:

projects_recycler_view.apply {
            this.layoutManager = linearLayoutManager
            this.adapter = adapter
        }

当我应该拥有这个时:

projects_recycler_view.apply {
            this.layoutManager = linearLayoutManager
            this.adapter = projectAdapter
        }

因为我愚蠢地将我的适配器称为adapter,所以它被应用块中的回收器视图的适配器所遮蔽!我将适配器重命名为 projectAdapter 以区分它并解决问题!

【讨论】:

  • 就是这样。我希望 Kotlin/AndroidStudio 能够以不同的方式突出这一点,无论变量来自这个块还是其他地方。
  • this.adapter = this@YourFragment.adapter(或YourActivity)。
【解决方案5】:

请将布局管理器设置为RecyclerView,如下代码:

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view_right);
//set your recycler view adapter here
NavigationAdapter adapter = new NavigationAdapter(this, FragmentDrawer.getData());
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));

【讨论】:

    【解决方案6】:

    这不适用于您的特定情况。但这可能对其他人有所帮助。

    这个原因可能是以下方法的粗心使用

    recyclerView.setHasFixedSize(true);
    

    如果不小心使用,这可能会导致根本无法调用 onBindViewonCreateViewHolder,并且日志中不会出现错误。

    【讨论】:

      【解决方案7】:

      也许它对某人有帮助,但如果您将 RecycleView 的可见性设置为 GONE,则根本不会调用适配器方法...我花了一些时间才弄清楚。

      【讨论】:

      • 花了我 1-3 个小时,天哪 T_T 绝望了,已经筋疲力尽了 lmaooo
      【解决方案8】:

      对于它的价值,我在设置回收器视图适配器时观察到它适配器实际初始化之前。解决方案是确保使用非空适配器调用 recyclerView.setAdapter(adapter)

      【讨论】:

        【解决方案9】:

        custom.xmlRecyclerView 中设置TextView 的高度。如果高度为wrap-content,则RecyclerView 将不可见。

        【讨论】:

        • 在这上面花了这么多时间.. 回收站视图的高度为零。在活动中使用时,它会以某种方式扩展自身。在其他布局内的片段中......它没有
        【解决方案10】:

        当我的 RecyclerView 位于 ScrollView 中并且我使用的是 Android 支持库 23.0 时,就会发生这种情况。为了解决这个问题,我更新到了 Android 支持库 23.2:

        在 build.gradle 中:

        dependencies {
            ...
            compile 'com.android.support:appcompat-v7:23.2.+'
            compile 'com.android.support:cardview-v7:23.2.+'
        }
        

        【讨论】:

          【解决方案11】:

          我遇到了同样的问题,因为我在布局资源中使用了android.support.constraint.ConstraintLayout。 更改为 FrameLayout 有帮助。

          【讨论】:

          • 感谢您的解决方案。如果 View 父级是 android.support.constraint.ConstraintLayout ,知道为什么它会这样吗?
          【解决方案12】:

          将此添加到您的适配器类

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

          【讨论】:

          • 另外,它是重复的
          【解决方案13】:

          其他选项是如果您使用 get 发送此列表 objetc,请验证您是否有正确的参考,例如

          private list<objetc> listObjetc;
          //Incorrect
          public void setListObjetcs(list<objetc> listObjetc){
            listObjetc = listObjetc;
          }
          
          //Correct
          public void setListObjetcs(list<objetc> listObjetc){
            this.listObjetc = listObjetc;
          }
          

          【讨论】:

            【解决方案14】:

            在我的情况下,我的列表大小为 0,它没有调用 onCreateViewHolder 方法。我需要在空列表的中心显示一条消息作为占位符,所以我这样做了,它就像魅力一样。 @Konstantin Burov 的回答很有帮助。

              @Override
            public int getItemCount() {
                if (contactList.size() == 0) {
                    return 1;
                } else {
                    return contactList.size();
                }
            }
            

            【讨论】:

            • 这不是一个好主意。将数据放入适配器时最好设置空消息的可见性。
            【解决方案15】:

            我为这个问题苦苦挣扎了好几个小时。我正在使用一个片段。问题不在于返回view。以下是我的代码:

            ProductGridBinding binding = DataBindingUtil.inflate( inflater, R.layout.product_grid, container, false);
            
            
            
                mLinearLayoutManager = new LinearLayoutManager(getActivity());
                mLinearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
            
                binding.rvNumbers.setHasFixedSize(true);
                binding.rvNumbers.setLayoutManager(mLinearLayoutManager);
                binding.rvNumbers.setAdapter(adapter);
            
            
                View view = binding.getRoot();
            
            
                return view;
            

            【讨论】:

            • 奇怪的代码。这些变量和类很难理解。
            【解决方案16】:

            如果您使用的是 android 数据绑定库,请查看我的答案 - 确保您正在为 recyclerview 设置布局,并且项目计数必须大于 0

             @BindingAdapter({"entries", "layout"})
                public static void setEntries(RecyclerView view, ArrayList<LoginResponse.User> listOfUsers, int layoutId) {
                    if (view.getAdapter() == null) {
                        view.setLayoutManager(new LinearLayoutManager(view.getContext()));
                        SingleLayoutAdapter adapter = new SingleLayoutAdapter(layoutId) {
                            @Override
                            protected Object getObjForPosition(int position) {
            
                                return listOfUsers.get(position);
                            }
            
                            @Override
                            public int getItemCount() {
                                return listOfUsers.size();
                            }
                        };
                        view.setAdapter(adapter);
                    }
                }
            

            编码愉快 :-)

            【讨论】:

              【解决方案17】:

              如果您将 wrap_content 作为列表的高度以及项目列表的高度,则不会显示任何内容,也不会调用您的任何 recyclerView 函数。固定项目的高度或将 match_parent 设置为列表高度。这解决了我的问题。

              【讨论】:

              • 此外,将“match_parent”设置为项目高度会导致仅显示第一个项目(因为它占据了 RecyclerView 的整个高度)。
              【解决方案18】:

              在我的例子中,我将 RecyclerView 的 ID 设置为“recyclerView”。似乎该 ID 已在某处定义,因为当我将其更改为不同的 ID 时,适配器中的方法被正确调用。

              【讨论】:

                【解决方案19】:

                如果使用自定义适配器,请不要忘记将 ItemCount 设置为集合的大小。

                【讨论】:

                  【解决方案20】:

                  我的遭遇是未调用 RecyclerView.adaptor 的 onBindViewHolder(holder, position) 覆盖方法。方法 onCreateViewHolder 被调用,getItemCount 被调用。如果您阅读 Recyclerview Adapter 的规范,您将了解到如果您已覆盖 onBindViewHolder(holder, position, List payloads) 将被优先调用。所以请小心。

                  【讨论】:

                  • 你是如何解决无法调用onBindViewHolder的问题的?
                  【解决方案21】:

                  我的错误是在 Fragment onCreateView 中膨胀了错误的视图。

                  【讨论】:

                    【解决方案22】:

                    您在 xml 中忘记了这一行 app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"

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

                    【讨论】:

                      【解决方案23】:

                      请做以下事情

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

                      【讨论】:

                        【解决方案24】:

                        在我将 Activity 更改为使用 ViewModel 和 DataBinding 后,我忘记从 onCreate 方法中删除 setContentView 方法调用。通过删除它,我的问题解决了。

                        【讨论】:

                          【解决方案25】:

                          对我来说,这是因为 setHasStableIds(true); 方法已设置。 删除它,它会工作

                          【讨论】:

                          • 但是这个方法似乎不在问题的minimal reproducible example 中。如果删除此 hint 修复了某些问题,则可能表明视图持有者或通知程序的实现存在错误。
                          【解决方案26】:

                          recyclerView.setAdapter(适配器);叫 recyclerView 列表通过调用该方法填充。

                          【讨论】:

                            【解决方案27】:

                            确保您的 XMLKoltin/Java 代码匹配。就我而言,自从我写了ViewHolder 就遇到了问题:

                            var txt: AppCompatTextView = itemView.findViewById(R.id.txt)
                            

                            但由于我的 XML 代码是:

                            <TextView
                                    android:id="@+id/txt"
                                    android:layout_width="wrap_content"
                                    android:layout_height="wrap_content"
                                    .../>
                            

                            我不得不将 privious 行更改为:

                            var txt: TextView = itemView.findViewById(R.id.txt)
                            

                            另外,我还得删除:

                            recyclerView.setHasFixedSize(true);
                            

                            希望对你有帮助:)

                            【讨论】:

                              【解决方案28】:

                              就我而言,在适配器中设置列表后,我错过了调用notifyDataSetChanged()

                              public void setUserList(List<UserList> userList) {
                                    this.userList = userList;
                                      notifyDataSetChanged();
                              }
                              

                              【讨论】:

                                【解决方案29】:

                                在我的情况下,我想在我的 LinearLayout 中设置方向。

                                添加方向问题后已修复。

                                 android:orientation="vertical"
                                

                                【讨论】:

                                  【解决方案30】:

                                  我的问题是 layout_heightlayout_width 的 RecyclerView 设置为 0dp

                                  【讨论】:

                                    猜你喜欢
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 1970-01-01
                                    • 2021-08-07
                                    • 1970-01-01
                                    • 2023-03-21
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多