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

чому ви встановлюєте recilerView.setAdapter (адаптер); 2 рази?
Панайотис Іраклеус

Іншою причиною цієї проблеми є помилкове приведення макета елемента до висоти батьківського, тому відображається одночасно лише один елемент.
Джо Лапп

У моєму випадку допоможіть цьому: invoicesRecyclerView.setHasFixedSize (true) factsRecyclerView.setLayoutManager (GridLayoutManager (this, 1))
a_subscriber

Відповіді:


239

Ваш getItemCountметод returns 0. Тому RecyclerViewніколи не намагається придумати погляд. Змусити щось повернути greater than 0.

наприклад

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

25
о боже, я зараз почуваюся такою німою! : facepalm: Дякую за це!
Shinta S

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

У мене був користувальницький адаптер і забув встановити свій номер товару за розміром своєї колекції
Dooie

3
кількість моїх предметів 3 досі не видно, жодних балів налагодження не надходить onBind або onCreateHolder ... але він надходить у getItemCount
Dr. aNdRO

О людино! Я теж боровся з цим, щоб зрозуміти, чому чорт моєї точки розриву не вражає, і тепер я знаю ... LOL! ДЕНЬ !!! СПАСИБІ!
Вінсі

409

Ще один - переконайтеся, що ви встановили менеджер макетів на RecyclerView:

recycler.setLayoutManager(new LinearLayoutManager(this));

2
До цієї відповіді я повертаюсь занадто часто…
finki


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був у a, ScrollViewі я використовував Android Support Library 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?
Адріан Буціаман

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 - Переконайтеся, що ви встановлюєте макет для перегляду рециркуляторів, а кількість елементів має бути більше 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 на "recilerView". Здається, цей ідентифікатор вже десь був визначений, тому що коли я змінив його на інший ідентифікатор, методи з адаптера були названі належним чином.


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, ви дізнаєтесь, що якщо ви перекрили onBindViewHolder (власник, позиція, список корисних навантажень), вам буде надано користь. Тож будьте обережні.


Як ви вирішили проблему не дзвонити onBindViewHolder?
CoolMind

1

Якщо ви поставите wrap_content як висоту свого списку, так і висоту списку ваших елементів, нічого не відображатиметься, і жодна з ваших функцій recilerView не буде викликана. Зафіксуйте висоту елемента або поставте match_parent для висоти списку. Це вирішило мою проблему.


1

Моєю помилкою було роздуття неправильного погляду у фрагменті onCreateView.


1

перейдіть на ваш xml І змініть ваш макет, щоб обернути вміст. Один елемент ховає наступний, тому методи не працюють!


1
Ласкаво просимо до StackOverflow @koala !. Дивіться це Як написати хороший відповідь тут stackoverflow.com/help/how-to-answer
Шашина Bhayani


0

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


0

Для мене це було тому, що набірHasStableIds (true); метод був встановлений. Видаліть це, і воно спрацює


Але цей метод, мабуть, не є мінімальним відтворюваним прикладом у питанні. Якщо видалення цього підказки щось виправляє, це, мабуть, є вказівкою на помилку в реалізації власника перегляду або, можливо, сповіщувача.

0

recilerView.setAdapter (адаптер); називається список recilerView заповнюється за допомогою виклику методу.


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.