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

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

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

2
Wracam do tej odpowiedzi zbyt często…
finki


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.


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

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


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!


6

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


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.+'
}


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ć.


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.


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

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;

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 :-)


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.


1

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


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

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.


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.


1

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



0

Proszę wykonaj następujące czynności

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

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.


0

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


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.


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 :)


0

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

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

0

W moim przypadku brakuje mi ustawienia orientacji w moim LinearLayout.

Po dodaniu problemu z orientacją naprawiono.

 android:orientation="vertical"

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.