Recyclerview NullpointerException in onBindViewHolder(...

W

washpuda

Neues Mitglied
0
Wo habe ich den hier den Denkfehler? Ich habe mir bereits viele Beispiele im Internet angeschaut, ich sehe nicht was ich anders mache. Ich hoffe es kann mir jemand helfen.

Ich versuche eine einfache horizontale Recyclerview zu erstellen und erhalte eine NullpointerException. Wenn ich if(holder.textView == null){return;} einkommentiere, werden einige Texte gesetzt, bei den anderen bleibt der Inhalt einfach "TextView" erhalten und die Reihenfolge der Items ist durcheinander.

Die Darstellung und alles andere ist perfect, lediglich die Zuordnung zu den textViews funktioniert irgendwie nicht richtig.

Code:
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

import de.bajestro.picmaptogo.R;

public class ChooseAuswDialog extends AppCompatActivity {

    RecyclerView layerTabListView;
    private RecyclerView.Adapter adapterLayerTap;
      @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose_ausw_dialog);

        layerTabListView = findViewById(R.id.layerTabList);
        layerTabListView.setHasFixedSize(true);
        List<String> testList = new ArrayList<>();
        testList.add("Itme 1");
        testList.add("Itme 2");
        testList.add("Itme 3");
        testList.add("Itme 4");
        testList.add("Itme 5");
        testList.add("Itme 6");
        testList.add("Itme 7");
        testList.add("Itme 8");
        testList.add("Itme 9");
        adapterLayerTap = new LayerListRecyclerViewAdapter(testList);
        layerTabListView.setAdapter(adapterLayerTap);
        LinearLayoutManager layoutManager
                = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
        layerTabListView.setLayoutManager(layoutManager);
        Button btnCancel = findViewById(R.id.btnCancel);
        btnCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ChooseAuswDialog.this.finish();
            }
        });

    }

    public class LayerListRecyclerViewAdapter extends RecyclerView.Adapter<LayerListRecyclerViewAdapter.LayerListViewHolder>{
        List<String> layers;

        public LayerListRecyclerViewAdapter(List<String> layers) {
            this.layers = layers;
        }

        @Override
        public LayerListViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view =  LayoutInflater.from(parent.getContext()).inflate(R.layout.item_simple_string, parent, false);
            return new LayerListViewHolder(view);
        }

        @Override
        public void onBindViewHolder(final LayerListViewHolder holder, final int position) {
            String layer = layers.get(position);
          //  if(holder.textView == null){return;}
            holder.textView.setText(layer);
        }
        @Override
        public int getItemCount() {
            return layers.size();
        }
        public class LayerListViewHolder extends RecyclerView.ViewHolder{
            //public String layer;
            public View mView;
            TextView textView;

            public LayerListViewHolder(View view) {
                super(view);
                mView = view;
                textView =  findViewById(R.id.stringTextView);
            }
        }
     }
   }
 
@washpuda

Hallo washpuda,

Vorab : Zu deinem vorherigen Problem hast du dich seit Tagen nicht mehr geäussert.
Bitte beachte, dass sich die Helfer hier im Forum für dein Problem viel Zeit nehmen.

Dann ist es nicht gerade erbaulich , wenn gar kein Feedback deinerseits kommt
Das demotiviert die Bereitschaft, dir in Zukunft zu helfen.


Ich versuche eine einfache horizontale Recyclerview zu erstellen und erhalte eine NullpointerException.

Bitte liefere uns bei exeptions immer deinen Errorlog mit ,ansonsten wäre es eine Aufgabe für die Kristallkugel.
[LEITFADEN] Wie bekomme ich hier die effektivste Hilfe ?

Danke
 
Zuletzt bearbeitet:
Hallo swa00,

zu meinem vorherigen Problem, war ja die Verwendung von Fragmenten nicht der richtige Weg. Ich baue jetzt für jeden Dialog eine eigene Activity. Ich werde dazu auch noch was schreiben. Gar nicht so einfach in die Android Programmierung reinzukommen. Für die Hilfe der anderen bin ich sehr dankbar.

Nachfolgend mein Fehlercode.

E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.bajestro.picmaptogo, PID: 18682
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at de.bajestro.picmaptogo.dialogs.ChooseAuswDialog$LayerListRecyclerViewAdapter.onBindViewHolder(ChooseAuswDialog.java:80)
at de.bajestro.picmaptogo.dialogs.ChooseAuswDialog$LayerListRecyclerViewAdapter.onBindViewHolder(ChooseAuswDialog.java:61)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5858)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5854)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2230)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1557)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1517)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:612)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3924)
at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3336)
at android.view.View.measure(View.java:24939)
at androidx.constraintlayout.widget.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:1227)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1572)
at android.view.View.measure(View.java:24939)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7132)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at androidx.appcompat.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:143)
at android.view.View.measure(View.java:24939)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7132)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1535)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:825)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:704)
at android.view.View.measure(View.java:24939)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7132)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at android.view.View.measure(View.java:24939)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7132)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1535)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:825)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:704)
at android.view.View.measure(View.java:24939)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7132)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:993)
at android.view.View.measure(View.java:24939)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:3286)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:2013)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2315)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1873)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8478)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:949)
at android.view.Choreographer.doCallbacks(Choreographer.java:761)
at android.view.Choreographer.doFrame(Choreographer.java:696)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:935)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6986)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
 
Hallo jetzt funktioniert es bei mir genau so wie es soll. Was genau die Fehlerursache war kann ich leider nicht sagen. Funktioniert hat es erst als ich die abschließende Klammer der Activity nach oben gesetzt habe, so dass die Adapterklasse sich außerhalb der Activity befindet und nicht mehr innerhalb. Es funktioniert nun aber auch, wenn ich die Klammer zurücksetze so dass der Adapter wieder innerhalb der Activity Klasse befindet. Ich vermute, dass ich hier irgendeine Aktualisierung der Projektstruktur vornehmen hätte sollen. Hat vielleicht irgendjemand eine Idee. Wie lässt sich so etwas vermeiden.
 
Hallo also an der klammer wird es nicht gelegen haben . Wenn die Adapter Klasse außerhalb gewesen wäre hättest du einen Compiler Fehler bekommen.
Das müsstest du als java Entwickler wissen.

Wenn das was du uns gepostet hast dein richtiger Code ist und nicht eine gekürzte version. Kann das nicht sein.

Dein Fehler Inder Version die du s gegeben hast ist der Fehler bei dem findviewbyid denn da hat du den Kontext der View in der inneren Klasse vergessen.
Laut log hast du auch eine NullPointerException und das hat mit den klammern nichts zu tun.

Wenn das mit den klammern stimmt hast du uns verarscht und den falschen Code gepostet.
Oder du hast nun den Code richtig aus dem tutorial kopiert.. Und dieses mal die klammer vergessen.

[Wie lässt sich so etwas vermeiden

Durch richtiges kopieren vom original Code.[
 
Zuletzt bearbeitet:
Hallo Jogimuc,

also ich versichere Ihnen, dass ich hier niemanden verarschen möchte. Auch möchte ich sagen, dass ich mich mit zwei Problemen hier an das Forum gewandt habe, aber nicht wirklich eine hilfreiche Lösung erhalten habe. In anderen Java Foren habe ich ein besseres Gefühl.

Warum sollte es denn ein Compilerfehler geben, wenn die Adapter Klasse außerhalb der Klasse aber im selben Klassendatei definiert wird (siehe Nested Classes). Eine Einschränkung ist lediglich, dass die Klasse nicht als public definiert werden kann. Die Adapterklasse kann innerhalb, außerhalb der Klasse oder als Klasse in einem eigenen File gespeichert werden. Damit kann man sich eine Menge zusätzlicher Dateien ersparen und den Quellcode besser strukturieren.

Wenn ich einen Quellcode poste, ist dieser möglichst auf das Problem heruntergebrochen und wird grundsätzlich aus dem Quellfenster kopiert. Alles andere macht ja keinen Sinn, wie schnell ergeben sich Tippfehler. Und es kann doch sein, weil bei mir war es ja so, warum sollte ich mir das ausdenken.
 
Du hattest eine NullPointerException und die muss bei der findviewbyid gewesen sein. Laut deinem Code


Wenn du schon zwei verschiedene Code machst das teste auch den Code den du uns postest den da ist der Fehler in der findviewbyid den die variable ist null.
Teste den Code denn du uns gegeben hast. Wirst es merken

Ja Nesdet Klasse oder innere klasse gibt es machst du ja auch. Klar geht es den Adapter auch außerhalb der ativity Klasse zu erstellen. Nur müsste der dann in eine eigene Datei.
Zwei unabhängige klasse in einer Datei geht bei Java nicht. Bei Kotlin schon.

Wie gesagt Fehler ist die NullPointerException gewesen und die kann nicht von der Kammer komme.

Im anderen Thread hast du auch Hilfe bekommen denke auch genug.
Du hast ja selber da das Handtuch geworfen.
Würdest du da auch antworten wäre die Hilfe auch weiter gegangen.



textView = view.findViewById(R.id.stringTextView);
Wäre richtig.
Zu diesen Tipp äußerst du dich nicht.behauptest die Kammere sind es .
Und dir selber kommt es komisch vor das es auch mit der ersten klammer Variante geht. Du widerspricht sich selber.


Von mir war es das jetzt. Wünsche dir noch viel Erfolg.
 
Zuletzt bearbeitet:
jogimuc schrieb:
Zwei unabhängige klasse in einer Datei geht bei Java nicht. Bei Kotlin schon.

Doch geht. Darf nicht public oder protected sein, sondern package-protected.

Zum Thema: für mich hat der Ausschnitt nicht gereicht zu sagen warum die View da null ist. Das Verhalten mit innerer Klasse und äußerer ist seltsam.
Kleine Anmerkung: Du musst unter Android aufpassen mit inneren Klassen in Activities. Das ist so ein bisschen ein Anti-Pattern. Eine innere Klasse die nicht static ist hat ja eine hidden Referenz auf die äußere Klasse. Unter Android sorgt das potentiell dafür dass die Activity (die recht speicherintensiv ist) nicht vom Garbage Collector aberäumt werden kann sofern irgendwoe noch eine live reference auf die innere KLasse existiert. (häufig bei AsyncTasks der Fall, aber auch bie Hilfsklassen die man durch die App an verschiedenen Stellen durchreicht)
 
  • Danke
Reaktionen: swa00
  1. "
[doublepost=1565086845,1565084578][/doublepost]Ok eine public und eine prodectet Klasse in einer Datei geht. Sorry. @deek

Das ändert aber nicht an der Tatsache das es an dem nullpointer lag. Auch ersichtlich aus dem log.
Ob der Adapter in einer inneren oder separaten Klasse ist ist gleich.
In dem Adapter ist eine internne ViewHolder Klasse. In dieser wird immer nur ein Listen Element gespeichert. Von dieser Klasse giebt es zur Laufzeit mehre instanzen. Anzahl der Listen Elemente.
Da für jedes Element ja das gleiche Layout benutzt wird und somit auch die gleiche id aus dem xml geht das mit dem einfache findv.. Nicht. Nicht ohne Grund wird die View an den ViewHolder als Parameter übergeben. Ohne die View kann die id nicht gefunden werden.
Das kann man allen Beispiele im Netz sehen. Sogar in der Google Doku.

Das ist der Grund und nicht die klammern.

Zu diesem Thema hat der TE keine Stellung bezogen.
Hallt immer noch an seinen klammern fest..
 
jogimuc schrieb:
Da für jedes Element ja das gleiche Layout benutzt wird und somit auch die gleiche id aus dem xml geht das mit dem einfache findv.. Nicht. Nicht ohne Grund wird die View an den ViewHolder als Parameter übergeben.

Jetzt habe ich gesehen
Code:
textView =  findViewById(R.id.stringTextView);

Hier muss es so aussehen:
Code:
textView =  view.findViewById(R.id.stringTextView);

Wahrscheinlich hast du das im Zuge der Klammerverschiebung gemacht. Und an dem Beispiel sieht man sehr deutlich warum innere Klassen, die nicht static sind, eine sehr schlechte Idee sind. Du hast die Activity Instanz einfach komplett durch deine Klassenhierarchie durchgereicht und deswegen war findViewById kein compile Fehler sondern wurde einfach auf der Activity aufgerufen.
 
@deek genau das habe ich ja auch schon in einen meiner ersten post gesagt.
schön das auch du es erkant hast.
[doublepost=1565102531,1565101920][/doublepost]Richtig ja bei Google ist es static.
Create a List with RecyclerView  |  Android Developers

In vielen Beispielen im Netz nicht.
[doublepost=1565103104][/doublepost]Und das mit der View vor dem findViewById wird dir wohl Android Studio vorgeschlagen haben als du den Adapter als separate Klasse hattest. Denn da kante er bestimmt nicht das findViewById denn du warst nicht mehr in der Activity Klasse.
 
Hallo, hatte gar nicht gemerkt, dass es noch ein paar Beiträge gab. Auf jeden Fall war das was Deek gesagt hat die Ursache. Hier vielen Dank ; -)
 

Ähnliche Themen

J
Antworten
5
Aufrufe
929
swa00
swa00
E
Antworten
2
Aufrufe
777
ekaya999
E
D
Antworten
23
Aufrufe
2.542
Data2006
D
Zurück
Oben Unten