Recyclerview не вызывает onCreateViewHolder


150

Мой RecyclerViewне вызывает onCreateViewHolder, onBindViewHolderдаже 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 (адаптер); 2 раза?
Панайотис Ираклеус

Другой причиной этой проблемы является ошибочное приведение макета элемента в соответствие с высотой родительского элемента, поэтому одновременно отображается только один элемент.
Джо Лапп

В моем случае помогите это: invoicesRecyclerView.setHasFixedSize (true) invoicesRecyclerView.setLayoutManager (GridLayoutManager (this, 1))
a_subscriber

Ответы:


239

Твой getItemCountметод returns 0. Поэтому RecyclerViewникогда не пытается создать представление. Заставь это вернуть что-то greater than 0.

например

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

25
о боже, я чувствую себя так глупо прямо сейчас! Спасибо за это!
Шинта С

3
Я просто потерял час на это, потому что getItemCount был намного ниже всего остального кода, и я его не видел. : |
Джоэл

У меня был специальный адаптер, и я забыл установить количество предметов в соответствии с размером моей коллекции
Dooie

3
мой счетчик предметов 3 до сих пор не виден, точки отладки не входят в onBind или onCreateHolder ... но они входят в getItemCount
Dr.Andro

О чувак! Я тоже боролся с этим, чтобы понять, почему, черт возьми, моя точка останова не работает, и теперь я знаю ... LOL! ЧЕРТ!!! СПАСИБО!
Винси

409

Еще один, убедитесь, что вы установили менеджер макета на RecyclerView:

recycler.setLayoutManager(new LinearLayoutManager(this));

2
Я слишком часто возвращаюсь к этому ответу ...
Финки


15

Это не относится к вашему конкретному случаю. Но это может помочь кому-то еще.

Эта причина может быть небрежное использование следующего метода

recyclerView.setHasFixedSize(true);

Если не использовать с осторожностью, это может привести к тому, что onBindViewи onCreateViewHolderне будут вызываться вообще, без ошибок в журналах.


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, он был затенен адаптером представления переработчика в блоке применения! Я переименовал адаптер в projectAdapter, чтобы выделить его, и проблема решена!


6

Установка высоты TextViewв custom.xmlили RecyclerView. Если высота есть wrap-content, то RecyclerViewне будет видна.


Потратил так много времени на это .. высота обзора переработчика была равна нулю. Когда он используется в деятельности, он как-то расширяется. Во фрагменте внутри других макетов .. это не так
Асиф Шираз

4

Это произошло, когда я 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.+'
}


4

Может быть, это кому-то поможет, но если вы установите видимость вашего RecycleView в GONE, методы адаптера не будут вызываться вообще ... Мне потребовалось некоторое время, чтобы понять это.


невероятно !!!!! ... танков так много ,,,
X-Black ...

3

У меня была такая же проблема, потому что я использовал android.support.constraint.ConstraintLayoutв макете ресурса. Поменял на FrameLayoutпомог.


Спасибо за ваше решение. Любая идея, почему он ведет себя так, если родительский вид android.support.constraint.ConstraintLayout?
Адриан Бучуман

2

Другой вариант, если вы отправляете этот список objetc с помощью get, проверьте, если у вас есть правильная ссылка, например

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

В моем случае я установил идентификатор моего RecyclerView на «recyclerView». Кажется, этот идентификатор где-то уже был определен, потому что когда я изменил его на другой идентификатор, методы из адаптера были вызваны правильно.


1

Если вы используете собственный адаптер, не забудьте установить ItemCount на размер вашей коллекции.


1

В моем случае размер моего списка был равен 0, и он не вызывал метод onCreateViewHolder. Мне нужно было отобразить сообщение в центре для пустого списка в качестве заполнителя, поэтому я сделал это так, и это сработало как шарм. Ответ от @Konstantin Burov помог.

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

Это не очень хорошая идея. Лучше настроить видимость пустого сообщения при помещении данных в адаптер.
Невероятный Ян

1

Моим сторонником был переопределенный метод onBindViewHolder (держатель, позиция) RecyclerView.adaptor, который не вызывался. Был вызван метод onCreateViewHolder, вызван getItemCount. Если вы прочитаете спецификации для Recyclerview Adapter, вы узнаете, что если вы переопределили onBindViewHolder (держатель, позиция, список полезных нагрузок) будет вызван в пользу. Поэтому, пожалуйста, будьте осторожны.


Как вы решили проблему не звонить onBindViewHolder?
CoolMind

1

Если вы укажете wrap_content как высоту вашего списка, а также высоту вашего списка элементов, ничего не будет отображаться, и ни одна из ваших функций recyclerView не будет вызвана. Зафиксируйте высоту элемента или укажите match_parent для высоты списка. Это решило мою проблему.


1

Моей ошибкой было раздувание неверного представления во Fragment onCreateView.


1

перейти к вашему XML. И измените свой макет, чтобы обернуть содержимое. Один элемент скрывает следующий, поэтому методы не работают!


1
Добро пожаловать в StackOverflow @koala !. Посмотрите это Как написать хороший ответ здесь stackoverflow.com/help/how-to-answer
Шашин Бхайани


0

В моем случае после изменения Activity на использование ViewModel и DataBinding я забыл удалить setContentViewвызов onCreateметода из метода. Удалив его, моя проблема решена.


0

Для меня это было потому, что setHasStableIds (true); метод был установлен. Удалите это, и это будет работать


Но этот метод, по-видимому, не находится в минимальном воспроизводимом примере в вопросе. Если удаление этой подсказки что- то исправляет, это, вероятно, указывает на ошибку в реализации держателя представления или, возможно, уведомителя.


0

Убедитесь , что XMLи Koltin/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();
}

0

В моем случае я не могу установить ориентацию в LinearLayout.

После добавления ориентации проблема исправлена.

 android:orientation="vertical"

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.