Recyclerview nie wywołuje onCreateViewHolder

149

Mój RecyclerViewnie wywołuje onCreateViewHolder, onBindViewHoldernawet MenuViewHolderkonstruktora, dlatego nic nie pojawia się w RecyclerView. Umieszczam dzienniki do debugowania i żaden dziennik nie jest wyświetlany. Co może być problemem?

Mój adapter:

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

Mój niestandardowy wiersz 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"/>

i mój fragment:

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
źródło
dlaczego u ustawić recyklerView.setAdapter (adapter); 2 razy?
Panayiotis Irakleous,
Inną przyczyną tego problemu jest błędne dopasowanie układu elementu do wysokości elementu nadrzędnego, więc w danym momencie wyświetlany jest tylko jeden element.
Joe Lapp
W moim przypadku pomóż w tym: invoicesRecyclerView.setHasFixedSize (true) fakturyRecyclerView.setLayoutManager (GridLayoutManager (this, 1))
a_subscriber

Odpowiedzi:

238

Twoja getItemCountmetoda returns 0. Dlatego RecyclerViewnigdy nie próbuj tworzyć instancji widoku. Niech coś zwróci greater than 0.

na przykład

@Override
public int getItemCount() {
    return data.size();
}
Konstantin Burov
źródło
25
o Boże, czuję się teraz taki głupi! : facepalm: Dziękuję za to!
Shinta S,
3
Właśnie straciłem na to godzinę, ponieważ getItemCount był znacznie niższy niż cały inny kod i nie widziałem go. : |
Joel
Miałem niestandardowy adapter i zapomniałem ustawić liczbę przedmiotów na rozmiar mojej kolekcji
Dooie
3
liczba moich przedmiotów nadal nie jest widoczna, brak punktów debugowania onBind lub onCreateHolder ... ale pojawia się w getItemCount
Dr. aNdRO
O stary! Ja też walczyłem z tym, aby dowiedzieć się, dlaczego do cholery mój punkt przerwania nie trafia, a teraz wiem ... LOL! CHOLERA!!! DZIĘKUJĘ CI!
Vincy
409

Kolejnym jest upewnienie się, że ustawiłeś menedżera układu na RecyclerView:

recycler.setLayoutManager(new LinearLayoutManager(this));
Lay Leangsros
źródło
2
Wracam do tej odpowiedzi zbyt często…
finki
42

Zapomniałem dodać poniższy wiersz po dodaniu, które zadziałało

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
Sai Gopi N.
źródło
10
Czym ta odpowiedź różni się od @Lay Leangsros powyżej jednej odpowiedzi?
Mehdi Dehghani
15

Nie dotyczy to twojego konkretnego przypadku. Ale to może pomóc komuś innemu.

Przyczyną może być nieostrożne użycie następującej metody

recyclerView.setHasFixedSize(true);

Jeśli nie jest używany ostrożnie, może to spowodować, że onBindViewand onCreateViewHoldernie będzie w ogóle wywoływany, bez błędów w dziennikach.

Venky
źródło
12

Ustaw menedżera układu na RecyclerViewtaki jak poniższy kod:

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));
Mandeep Yadav
źródło
9

Co jest warte, zauważyłem to, kiedy ustawiłem adapter widoku recyklera, zanim adapter został faktycznie zainicjowany. Rozwiązaniem było upewnienie się, że recyclerView.setAdapter(adapter)został wywołany z niepustym adapterem

kip2
źródło
9

Naprawdę naprawdę nadzieję, że to pomoże ktoś kiedyś. Właśnie spędziłem ponad godzinę na tym, żeby oszaleć!

Miałem to:

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

Kiedy powinienem był to mieć:

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

Ponieważ głupio zadzwoniłem do mojego adaptera adapter, był on zasłaniany przez adapter widoku recyklera w bloku stosowania! Zmieniłem nazwę adaptera na projectAdapter, aby go odróżnić i problem został rozwiązany!

the_new_mr
źródło
6

Ustawienie wysokości TextVieww custom.xmllub RecyclerView. Jeśli wysokość to wrap-content, RecyclerViewikona nie będzie widoczna.

jian lang
źródło
Spędziłem na tym tyle czasu ... wysokość widoku recyklera wynosiła zero. Kiedy jest używany w działaniu, w jakiś sposób się rozszerza. We fragmencie wewnątrz innych układów… nie udało się
Asif Shiraz
4

Stało się tak, gdy mój RecyclerViewbył w środku a ScrollViewi korzystałem z biblioteki obsługi systemu Android 23.0. Aby to naprawić, zaktualizowałem do Android Support Library 23.2:

W build.gradle:

dependencies {
    ...
    compile 'com.android.support:appcompat-v7:23.2.+'
    compile 'com.android.support:cardview-v7:23.2.+'
}
J Wang
źródło
4

Dodaj to do swojej klasy adaptera

 @Override
    public int getItemCount() {
        return mDataset.size();
    } 
Brinda Rathod
źródło
również jest to duplikat
Ricardo A.
4

Może to komuś pomoże, ale jeśli ustawisz widoczność RecycleView na GONE, metody adaptera nie zostaną w ogóle wywołane ... Zajęło mi trochę czasu, aby to zrozumieć.

linia nieciągłości
źródło
niewiarygodne !!!!! ... tyle czołgów ,,,
X-Black ...
3

Miałem ten sam problem, ponieważ korzystałem android.support.constraint.ConstraintLayoutz zasobów układu. Zmiana na FrameLayoutpomoc.

Dziki Teddy
źródło
Dziękuję za rozwiązanie. Masz jakiś pomysł, dlaczego zachowuje się tak, jeśli rodzic View jest android.support.constraint.ConstraintLayout?
Adrian Buciuman
2

Inną opcją jest, jeśli wyślesz tę listę objetc za pomocą get, na przykład sprawdź, czy masz poprawne odniesienie

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

//Correct
public void setListObjetcs(list<objetc> listObjetc){
  this.listObjetc = listObjetc;
}
David Hackro
źródło
2

Zmagałem się z tym problemem przez wiele godzin. Użyłem fragmentu. Problem nie polegał na zwróceniu pliku view. Poniżej mój kod:

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
źródło
Dziwny kod. Te zmienne i klasy są trudne do zrozumienia.
CoolMind
2

Zobacz moją odpowiedź, jeśli korzystasz z biblioteki powiązań danych systemu Android - upewnij się, że ustawiasz układ dla widoku recyklingu, a liczba elementów musi być większa niż 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);
        }
    }

Miłego kodowania :-)

Bajrang Hudda
źródło
1

W moim przypadku ustawiłem identyfikator mojego RecyclerView na „recyclinglerView”. Wygląda na to, że ten identyfikator był już gdzieś zdefiniowany, ponieważ kiedy zmieniłem go na inny identyfikator, metody z adaptera zostały wywołane poprawnie.

Mateusz Włodarczyk
źródło
1

Jeśli używasz niestandardowego adaptera, nie zapomnij ustawić ItemCount na rozmiar swojej kolekcji.

Dooie
źródło
1

W moim przypadku rozmiar mojej listy wynosił 0 i nie wywoływał metody onCreateViewHolder. Musiałem wyświetlić wiadomość w środku pustej listy jako element zastępczy, więc zrobiłem to w ten sposób i działało jak urok. Odpowiedź udzielona przez @Konstantin Burov pomogła.

  @Override
public int getItemCount() {
    if (contactList.size() == 0) {
        return 1;
    } else {
        return contactList.size();
    }
}
MRX
źródło
To nie jest dobry pomysł. Podczas przesyłania danych do adaptera lepiej ustawić widoczność pustego komunikatu.
Niesamowity
1

Mój szyfrator był metodą onBindViewHolder (posiadacz, pozycja) nadpisanej metody RecyclerView.adaptor, która nie została wywołana. Wywołano metodę onCreateViewHolder, wywołano getItemCount. Jeśli przeczytasz specyfikacje adaptera Recyclerview, dowiesz się, że jeśli nadpisałeś onBindViewHolder (posiadacz, pozycja, ładunki listy), zostanie wywołany na korzyść. Więc proszę uważaj.

Yaojin
źródło
Jak rozwiązałeś problem braku dzwonienia onBindViewHolder?
CoolMind
1

Jeśli umieścisz wrap_content jako wysokość swojej listy, a także wysokość listy pozycji, nic się nie pojawi i żadna z twoich funkcji recyclinglerView nie zostanie wywołana. Popraw wysokość elementu lub wpisz match_parent jako wysokość listy. To rozwiązało mój problem.

Meriam
źródło
1

Moim błędem było zawyżenie niewłaściwego widoku w Fragment onCreateView.

Jeffrey
źródło
1

przejdź do swojego xml. I zmień układ, aby zawijać zawartość. Jeden element ukrywa następny, więc metody nie działają!

Koala
źródło
1
Witamy w StackOverflow @koala !. Zobacz to Jak napisać dobrą odpowiedź tutaj stackoverflow.com/help/how-to-answer
Shashin Bhayani
0

Proszę wykonaj następujące czynności

@Override
public int getItemCount() {
    return data.size();
}
Saurav Mir
źródło
0

W moim przypadku po zmianie Activity na używanie ViewModel i DataBinding, zapomniałem usunąć setContentViewwywołanie onCreatemetody z metody. Usuwając go, mój problem został rozwiązany.

Siamak Ferdos
źródło
0

U mnie było tak, ponieważ setHasStableIds (true); metoda została ustawiona. Usuń to i zadziała

Catalin
źródło
Ale ta metoda nie wydaje się być w minimalnym powtarzalnym przykładzie w pytaniu. Jeśli usunięcie tej wskazówki coś naprawia, prawdopodobnie jest to wskazanie błędu w implementacji uchwytu widoku lub powiadamiającego.
0

recyklerView.setAdapter (adapter); wywołana Lista recyclinglerView jest wypełniana przez wywołanie metody.

Mesut Beysülen
źródło
0

Upewnij się, że Twój kod XMLi Koltin/Javakod są zgodne. W moim przypadku miałem problem ze ViewHolderskoro napisałem:

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

Ale ponieważ mój kod XML to:

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

Musiałem zmienić tajny wiersz na:

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

Dodatkowo musiałem też usunąć:

recyclerView.setHasFixedSize(true);

Mam nadzieję, że to ci pomoże :)

Mattia Ferigutti
źródło
0

W moim przypadku brakowało dzwonienia notifyDataSetChanged()po ustawieniach listy w adapterze.

public void setUserList(List<UserList> userList) {
      this.userList = userList;
        notifyDataSetChanged();
}
nkadu1
źródło
0

W moim przypadku brakuje mi ustawienia orientacji w moim LinearLayout.

Po dodaniu problemu z orientacją naprawiono.

 android:orientation="vertical"
Ranjith Kumar
źródło
0

Mój problem był layout_heighti layout_widthzestawu RecyclerView do 0dp.

Zezi Reeds
źródło