Recyclerview ruft onCreateViewHolder nicht auf


149

Mein RecyclerViewnicht nennen onCreateViewHolder, onBindViewHolderauch MenuViewHolderKonstruktor, also nichts erscheint in RecyclerView. Ich habe Protokolle zum Debuggen abgelegt, und es wird kein Protokoll angezeigt. Was könnte das Problem sein?

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

Meine benutzerdefinierte Zeilen-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"/>

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

Warum setzen Sie recyclerView.setAdapter (Adapter)? 2 Mal?
Panayiotis Irakleous

Eine weitere Ursache für dieses Problem besteht darin, dass das Elementlayout fälschlicherweise an die Höhe des übergeordneten Elements angepasst wird, sodass jeweils nur ein Element angezeigt wird.
Joe Lapp

In meinem Fall helfen Sie dies: invoicesRecyclerView.setHasFixedSize (true) invoicesRecyclerView.setLayoutManager (GridLayoutManager (this, 1))
a_subscriber

Antworten:


238

Ihre getItemCountMethode returns 0. RecyclerViewVersuchen Sie also niemals, eine Ansicht zu instanziieren. Lass es etwas zurückgeben greater than 0.

beispielsweise

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

25
Oh Gott, ich fühle mich gerade so dumm! : facepalm: Danke dafür!
Shinta S

3
Ich habe gerade eine Stunde verloren, weil der getItemCount weit unter dem anderen Code lag und ich ihn nicht gesehen habe. : |
Joel

Ich hatte einen benutzerdefinierten Adapter und hatte vergessen, meine Artikelanzahl auf die Größe meiner Sammlung
einzustellen

3
meine Elementanzahl ist 3 noch nicht sichtbar, keine Debug - Punkte kommen in onBind oder onCreateHolder ... aber es kommt in getItemCount
Dr. Andro

Oh Mann! Auch ich habe damit gekämpft, um herauszufinden, warum zum Teufel mein Haltepunkt nicht trifft und jetzt weiß ich ... LOL! VERDAMMT!!! DANKE!
Vincy

408

Zum anderen müssen Sie den Layout-Manager auf RecyclerView einstellen:

recycler.setLayoutManager(new LinearLayoutManager(this));

2
Ich komme zu oft auf diese Antwort zurück…
Finki

42

Ich habe vergessen, die folgende Zeile hinzuzufügen, nachdem ich hinzugefügt habe, dass es für mich funktioniert hat

recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

10
Wie unterscheidet sich diese Antwort von @Lay Leangsros über einer Antwort?
Mehdi Dehghani

15

Dies gilt nicht für Ihren speziellen Fall. Aber das könnte jemand anderem helfen.

Dieser Grund könnte die unachtsame Verwendung der folgenden Methode sein

recyclerView.setHasFixedSize(true);

Wenn dies nicht mit Vorsicht verwendet wird, kann dies dazu führen, dass das onBindViewund überhaupt onCreateViewHoldernicht aufgerufen wird, ohne dass ein Fehler in den Protokollen auftritt.


12

Bitte stellen Sie den Layout-Manager so ein, RecyclerViewdass er den folgenden Code mag:

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

Für das, was es wert ist, habe ich es beobachtet, als ich den Recycler-Ansichtsadapter eingestellt habe, bevor der Adapter tatsächlich initialisiert wurde. Die Lösung bestand darin, sicherzustellen, dass recyclerView.setAdapter(adapter)mit einem Nicht-Null-Adapter aufgerufen wurde


9

Ich hoffe wirklich, dass dies eines Tages jemandem hilft. Ich verbringe gerade über eine Stunde damit, verrückt zu werden!

Ich hatte das:

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

Wann hätte ich das haben sollen:

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

Da ich meinen Adapter törichterweise angerufen habe adapter, wurde er vom Adapter der Recycler-Ansicht im Apply-Block beschattet! Ich habe den Adapter in projectAdapter umbenannt, um ihn zu unterscheiden und das Problem zu lösen!


6

Einstellen der Höhe des TextViewin custom.xmloder RecyclerView. Wenn die Höhe ist wrap-content, ist die RecyclerViewnicht sichtbar.


Ich habe so viel Zeit damit verbracht. Die Höhe der Recycler-Ansicht war Null. Wenn es in einer Aktivität verwendet wird, hat es sich irgendwie erweitert. In einem Fragment in anderen Layouts ... nicht
Asif Shiraz

4

Dies geschah, als ich mich RecyclerViewin einem befand ScrollViewund die Android Support Library 23.0 verwendete. Um dies zu beheben, habe ich auf Android Support Library 23.2 aktualisiert:

In build.gradle:

dependencies {
    ...
    compile 'com.android.support:appcompat-v7:23.2.+'
    compile 'com.android.support:cardview-v7:23.2.+'
}

4

Fügen Sie dies Ihrer Adapterklasse hinzu

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

Es ist auch ein Duplikat
Ricardo A.

4

Vielleicht hilft es jemandem, aber wenn Sie die Sichtbarkeit Ihres RecycleView auf GONE setzen, werden die Adaptermethoden überhaupt nicht aufgerufen ... Ich habe einige Zeit gebraucht, um es herauszufinden.


unglaublich !!!!! ... Panzer so sehr ,,,
X-Black ...

3

Ich hatte das gleiche Problem, weil ich android.support.constraint.ConstraintLayoutin Layout-Ressource verwendet. Wechsel zu FrameLayoutgeholfen.


Vielen Dank für Ihre Lösung. Irgendeine Idee, warum es sich so verhält, wenn das übergeordnete Element Ansicht ist android.support.constraint.ConstraintLayout?
Adrian Buciuman

2

Eine andere Option ist, wenn Sie diese Liste objetc mit get senden, überprüfen Sie beispielsweise, ob Sie die richtige Referenz haben

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

//Correct
public void setListObjetcs(list<objetc> listObjetc){
  this.listObjetc = listObjetc;
}

2

Ich hatte viele Stunden mit diesem Problem zu kämpfen. Ich habe ein Fragment verwendet. Und das Problem war nicht die Rückkehr der view. Unten ist mein Code:

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;

Seltsamer Code. Diese Variablen und Klassen sind schwer zu verstehen.
CoolMind

2

Siehe meine Antwort, wenn Sie eine Android-Datenbindungsbibliothek verwenden. - Stellen Sie sicher, dass Sie das Layout für die Recycling-Ansicht festlegen und die Anzahl der Elemente größer als 0 sein muss

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

Viel Spaß beim Codieren :-)


1

In meinem Fall habe ich die ID meines RecyclerView auf "recyclerView" gesetzt. Es scheint, dass diese ID bereits irgendwo definiert wurde, denn als ich sie in eine andere ID änderte, wurden die Methoden des Adapters ordnungsgemäß aufgerufen.


1

Wenn Sie einen benutzerdefinierten Adapter verwenden, vergessen Sie nicht, den ItemCount auf die Größe Ihrer Sammlung festzulegen.


1

In meinem Fall war meine Listengröße 0 und es wurde nicht die onCreateViewHolder-Methode aufgerufen. Ich musste eine Nachricht in der Mitte für die leere Liste als Platzhalter anzeigen, also habe ich es so gemacht und es hat wie ein Zauber funktioniert. Antwort von @Konstantin Burov half.

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

Das ist keine wirklich gute Idee. Es ist besser, die Sichtbarkeit der leeren Nachricht festzulegen, wenn Daten an den Adapter gesendet werden.
Der unglaubliche

1

Mein Encouter war die überschriebene Methode onBindViewHolder (Inhaber, Position) des nicht aufgerufenen RecyclerView.adaptor. Die Methode onCreateViewHolder wurde aufgerufen, getItemCount wurde aufgerufen. Wenn Sie die Spezifikationen für den Recyclerview-Adapter lesen, werden Sie feststellen, dass, wenn Sie onBindViewHolder (Inhaber, Position, Listennutzdaten) überschrieben haben, dies bevorzugt wird. Also bitte sei vorsichtig.


Wie haben Sie ein Problem gelöst, bei dem Sie nicht angerufen haben onBindViewHolder?
CoolMind

1

Wenn Sie wrap_content als Höhe Ihrer Liste sowie als Höhe Ihrer Artikelliste angeben, wird nichts angezeigt und keine Ihrer recyclerView-Funktionen wird aufgerufen. Korrigieren Sie die Höhe des Elements oder setzen Sie match_parent für die Listenhöhe. Das hat mein Problem gelöst.


1

Mein Fehler war das Aufblasen der falschen Ansicht in Fragment onCreateView.


1

Gehe zu deiner XML. Und ändern Sie Ihr Layout, um Inhalte zu verpacken. Das eine Element versteckt das nächste, daher funktionieren die Methoden nicht!


1
Willkommen bei StackOverflow @koala!. Siehe dies Wie schreibe ich
Shashin Bhayani

0

Bitte machen Sie folgendes

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

0

In meinem Fall hatte ich nach dem Ändern der Aktivität zur Verwendung von ViewModel und DataBinding vergessen, den setContentViewMethodenaufruf aus der onCreateMethode zu entfernen . Durch das Entfernen wurde mein Problem gelöst.


0

Für mich lag es daran, dass setHasStableIds (true); Methode wurde eingestellt. Entfernen Sie das und es wird funktionieren


Diese Methode scheint jedoch nicht das minimal reproduzierbare Beispiel in der Frage zu sein. Wenn das Entfernen dieses Hinweises etwas behebt, ist dies wahrscheinlich ein Hinweis auf einen Fehler in der Implementierung des Ansichtsinhabers oder möglicherweise des Benachrichtigers.

0

recyclerView.setAdapter (Adapter); Die recyclerView-Liste wird durch Aufrufen der Methode gefüllt.


0

Stellen Sie sicher, dass Ihre XMLund Koltin/JavaCode übereinstimmen. In meinem Fall hatte ich ein Problem mit dem, ViewHolderseit ich geschrieben hatte:

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

Aber da mein XML-Code ist:

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

Ich musste die private Reihe ändern in:

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

Außerdem musste ich auch entfernen:

recyclerView.setHasFixedSize(true);

Ich hoffe das kann dir helfen :)


0

In meinem Fall fehlte mir der Anruf notifyDataSetChanged()nach dem Einstellen der Liste im Adapter.

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

0

In meinem Fall vermisse ich es, die Ausrichtung in meinem LinearLayout festzulegen.

Nach dem Hinzufügen des Orientierungsproblems behoben.

 android:orientation="vertical"

0

Mein Problem war layout_heightund layout_widthder RecyclerView auf eingestellt 0dp.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.