Recyclerview不调用onCreateViewHolder


149

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次?
Panayiotis Irakleous

造成此问题的另一个原因是错误地使项目布局与父项的高度匹配,因此一次仅显示一个项目。
乔·拉普

以我
为例

Answers:


238

你的getItemCount方法returns 0。因此,RecyclerView永远不要尝试实例化视图。让它返回一些东西greater than 0

例如

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

25
哦,天哪,我现在真傻!:facepalm:谢谢你!
Shinta S 2015年

3
我为此花了一个小时,因为getItemCount低于所有其他代码,而且我没有看到它。:|
乔尔

我有一个自定义适配器,却忘记了将itemcount设置为我的收藏的大小
Dooie

3
我的项目计数为3仍不可见,onBind或onCreateHolder中没有调试点...但是它出现在getItemCount中
aNdRO博士17年

天啊!我也一直在与这个斗争,以找出为什么我的断点没有被击中,现在我知道...大声笑!该死的!!!谢谢!
'18

409

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

recycler.setLayoutManager(new LinearLayoutManager(this));

2
我回到这个答案waaay往往...
finki


15

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

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

recyclerView.setHasFixedSize(true);

如果没有谨慎使用,这可能会导致onBindViewonCreateViewHolder根本不被调用,并在日志中没有错误。


12

请设置布局管理器,使其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));

9

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


9

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

我有这个:

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

当我应该有这个:

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

因为我愚蠢地称呼我的适配器adapter,所以它被apply块中的recycler视图的适配器遮盖了!我将适配器重命名为projectAdapter来区分它并解决了问题!


6

TextViewcustom.xml或中设置的高度RecyclerView。如果height为wrap-contentRecyclerView则将不可见。


在此上花费了很多时间..回收器视图的高度为零。在活动中使用时,它会以某种方式自我扩展。在其他布局中的一个片段中..并非如此
Asif Shiraz

4

这发生在我RecyclerView位于a内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.+'
}


4

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


令人难以置信!!!!! ...坦克那么多,
X-Black ...

3

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


谢谢您的解决方案。任何想法,如果View父级是为什么会表现出这样的行为android.support.constraint.ConstraintLayout
Adrian Buciuman

2

其他选项是如果您使用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;
}

2

我为这个问题苦苦挣扎了好几个小时。我正在使用一个片段。而且问题没有退还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;

奇怪的代码。这些变量和类很难理解。
CoolMind

2

如果您使用的是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);
        }
    }

快乐编码:-)



1

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


1

就我而言,列表大小为0,并且没有调用onCreateViewHolder方法。我需要在空白列表的中心显示一条消息作为占位符,所以我做到了这一点,并且像魅力一样工作。@Konstantin Burov的回答有所帮助。

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

这不是一个真正的好主意。将数据放入适配器时,最好设置空消息的可见性。
令人难以置信的

1

我的伙伴是未调用RecyclerView.adaptor的onBindViewHolder(holder,position)重写的方法。调用了onCreateViewHolder方法,调用了getItemCount。如果您阅读了Recyclerview Adapter的规范,您将了解到,如果您已重写onBindViewHolder(holder,position,List有效负载),将被优先使用。所以请注意。


您如何解决不打电话的问题onBindViewHolder
CoolMind

1

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


1

我的错误是在Fragment onCreateView中夸大了错误的视图。





0

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


但是,该方法似乎不是问题中的最小可重现示例。如果删除此提示可以解决问题,则可能表示视图持有者或通知程序的实现存在错误。


0

确保您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"
        .../>

我不得不将私密的行更改为:

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

此外,我还必须删除:

recyclerView.setHasFixedSize(true);

我希望这可以对您有所帮助:)


0

就我而言,我没有notifyDataSetChanged()在适配器中设置列表后调用。

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.