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;
}
Malinosqui
источник
почему вы устанавливаете 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));
Lay Leangsros
источник
2
Я слишком часто возвращаюсь к этому ответу ...
Финки
42

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

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
Саи Гопи Н
источник
10
Чем этот ответ отличается от @Lay Leangsros выше одного ответа?
Мехди Дехани
15

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

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

recyclerView.setHasFixedSize(true);

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

Venky
источник
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)был вызван с ненулевым адаптером

kip2
источник
9

Я действительно очень надеюсь, что это поможет кому-нибудь когда-нибудь. Я просто потратил больше часа на этот сумасшедший!

У меня было это:

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

Когда я должен был иметь это:

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

Поскольку я по глупости назвал свой адаптер adapter, он был затенен адаптером представления переработчика в блоке применения! Я переименовал адаптер в projectAdapter, чтобы выделить его, и проблема решена!

the_new_mr
источник
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

Добавьте это в свой класс адаптера

 @Override
    public int getItemCount() {
        return mDataset.size();
    } 
Бринда Ратод
источник
Кроме того, это дубликат
Рикардо А.
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;
TharakaNirmana
источник
Странный код Эти переменные и классы трудно понять.
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 на размер вашей коллекции.

Dooie
источник
1

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

  @Override
public int getItemCount() {
    if (contactList.size() == 0) {
        return 1;
    } else {
        return contactList.size();
    }
}
MRX
источник
Это не очень хорошая идея. Лучше настроить видимость пустого сообщения при помещении данных в адаптер.
Невероятный Ян
1

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

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

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

Meriam
источник
1

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

Джеффри
источник
1

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

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

Пожалуйста, сделайте следующее

@Override
public int getItemCount() {
    return data.size();
}
Саурав Мир
источник
0

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

Сиамак Фердос
источник
0

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

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

recyclerView.setAdapter (адаптер); Вызванный список recyclerView заполняется путем вызова метода.

Месут Бейсюлен
источник
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();
}
nkadu1
источник
0

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

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

 android:orientation="vertical"
Ранджит Кумар
источник
0

Моя проблема была layout_heightи layout_widthRecyclerView установлен в 0dp.

Зези Ридс
источник