findViewById liefert Null in MainActivity bei Aufruf aus ViewPager-Tab (Anfänger/Hirachie-Problem??)

  • Antworten:6
  • Bentwortet
Herbert G
  • Forum-Beiträge: 6

06.01.2016, 18:31:20 via Website

Liebe Androidpit Gemeinde

als Anfänger mit Java und Android kämpfe ich mit einem wahrscheinlich simplen Problem und hoffe ihr könnt mir helfen (googeln und div Bücher haben mich noch nicht auf den richtigen Weg gebracht).

In der ActivityMain gibt es zwei Zeilen u.a. ein Textfeld für einen Timer, und darunter ein Viewpager mit 4 Tabs.
In der MainActivity habe ich eine Funktion TimerStart die mir den CountDownTimer auf den Wert setzt und startet. Bei TimerStart und in der CounterClass Timer (CountDownTimer) bei onTick wird die Zeit in einem String (ms) geschrieben und ausgegeben mit:

mCounter = (TextView) findViewById(R.id.myCounter);
mCounter.setText(ms);

Dies funktioniert soweit recht gut, solange der Counter in der MainActivity.java bei onCreate auch über einen Button hier geändert/gestartet wird. Wird jedoch TimerStart aus dem ViewPager über einen Button im Tab1 aus der Tab1.java aufgerufen mit:

MainActivity mActivity = new MainActivity();
mActivity.StartTimer(lngTimer);

habe ich das Problem, dass findViewById(R.id.myCounter) NULL retour liefert und die APP angehalten wird.
Ich habe auch schon mCounter in der MainActivity deklariert und bei OnCreate gesetzt, aber auch hier ist diese wenn sie von der Tab1.java aufgerufen wird Null.

Habt ihr irgendwelche Ideen oder Tipps für mich???

Danke, LG Herbert

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

06.01.2016, 18:36:36 via Website

Hallo Herbert,
Du darfst auch keine neue Istanz der MainActivity machen.
(!): Sowas heir ist für Activities tödlich ;)

MainActivity mActivity = new MainActivity();

benutz lieber im Fragment die getActivity() Methode und caste diese in deine mainActivity.
z.b. so:
(Das hier passoert im Fragment)

MainActivity main = (MainActivity)getActivity();
main.StartTimer(lngTimer);

Aber warum muss denn der Timer ausgerechnet in der MainAcitvity liegen?
Du kannst diese doch genauso in eine andere Klasse auslagern, dann hast du das Problem nicht.

LG Pascal //It's not a bug, it's a feature. :) ;)

Herbert G

Antworten
Henrik Martens
  • Forum-Beiträge: 607

06.01.2016, 18:40:18 via Website

Man kann Views nur aus der Class ansprechen, aus der sie auch erstellt wurden.

Mit ähnlichem Problem hatte ich auch schon zu kämpfen. Ich habe es wie folgt gelöst, ob es die beste Lösung ist, weiß ich nicht.

Wenn du in deiner MainActivity eine void erstellst, welche das ansprechen des Views übernimmt, und du aus den anderen Classes nur die void aufrufst sollte es klappen. Wichtig dabei ist, dass du der void keine Variablen übergeben darfst.

Diese müsstest du also per setter vorher in der ensprechenden Activity speichern.

So klappt es bei mir.

Henrik

Antworten
Herbert G
  • Forum-Beiträge: 6

06.01.2016, 19:29:06 via Website

Hallo Pascal,
danke für die rasche Antwort. Habe es wie du schreibst mit

MainActivity main = (MainActivity)getActivity();
main.StartTimer(lngTimer);

ausprobiert und es funktioniert.

Der Timer liegt in der MainActivity, da ich mal langsam mit demTimer angefangen habe. Ich habe mit diesen Getter/Setter und Datenünbergaben noch nicht viel Erfahrung (grad mal einen Broadcastreceiver für eine galleryview). Ich denke wenn ich das in eine andere Klasse gebe habe ich doch auch das Problem oder? Bzw wie müste ich dann auf das Textfeld zugreifen um die Zeit reinzuschreiben? Würde dann findViewById funktionieren oder ist das auch anders (neue Hürden ;))
LG Herbert

Antworten
Herbert G
  • Forum-Beiträge: 6

06.01.2016, 19:44:50 via Website

Hallo Henrik
danke für die rasche Antwort, leider hat es bei mir mit der void (ohne Variable, hab ich intern zum testen auf fixen Wert gesetzt) nicht funktioniert. Die Lösung von Pascal mit

MainActivity main = (MainActivity)getActivity();
main.StartTimer(lngTimer);

jedoch schon.
LG Herbert

Antworten
Pascal P.
  • Admin
  • Forum-Beiträge: 11.286

06.01.2016, 19:50:52 via Website

Da hast du allerdings recht.
Mit findViewById würde es dann nicht mehr gehen.
Alternativ, die TextView als ObjektParameter übergeben und setzen oder ein Callback definieren. Das würde aber gerade am Anfang alles nur noch schwieriger machen.
Ich denke so müsste es forerst passen.

Da deine Frage jetzt geklärt ist setze bittte noch deinen Thread auf beantwortet, indem du über deinem ersten Post auf Mehr-> Beantwortet setzen klickst.
Danke

LG Pascal //It's not a bug, it's a feature. :) ;)

Antworten
Herbert G
  • Forum-Beiträge: 6

06.01.2016, 20:04:40 via Website

OK, Danke

Antworten