Verstehe nicht warum keine neue Fragen geladen werden

  • Antworten:18
  • Bentwortet
Syntac Moore
  • Forum-Beiträge: 44

04.02.2014, 22:36:52 via Website

Hey,
Ich hab hier schon Mal ein Problem gehabt, konnte das aber soweit lösen.
Nochmal eine kurze Übersicht zur App:
Also es ist eine Quiz App, die Oberfläche besteht aus 4 Buttons (für die Antworten), einer TextView (für die Frage) und einer ProgressBar.
Wenn eine Frage richtig beantwortet wurde, soll sich das Layout an sich nicht ändern sondern nur aktualisiert werden, also die Frage ausgetauscht werden.
Das neue Problem ist, dass wenn ich den Button mit der richtigen Frage drücke, keine neue Frage kommt. Es erscheint auch kein Fehler im LogCat.

Hier mal meine Klassen + Manifest.

Quiz.class
1package de.versuch;
2
3import android.app.Activity;
4import android.os.Bundle;
5import android.view.View;
6import android.view.View.OnClickListener;
7import android.widget.Button;
8
9public class Quiz extends Activity implements android.view.View.OnClickListener {
10 OnClickListener ln;
11
12 @Override
13 public void onCreate(Bundle savedInstanceState) {
14 super.onCreate(savedInstanceState);
15 setContentView(R.layout.activity_quiz);
16
17 // Spiellogik instanzieren
18 Spiellogik spiel = new Spiellogik();
19 // Antwort-Buttons mit Ereignislistener verbinden
20 for (int n = 1; n <= 4; n++) {
21 Button btn = null;
22
23 switch (n) {
24 case 1:
25 btn = (Button) this.findViewById(R.id.antwort1);
26 btn.setOnClickListener(ln);
27 break;
28 case 2:
29 btn = (Button) this.findViewById(R.id.antwort2);
30 btn.setOnClickListener(ln);
31 break;
32 case 3:
33 btn = (Button) this.findViewById(R.id.antwort3);
34 btn.setOnClickListener(ln);
35 break;
36 case 4:
37 btn = (Button) this.findViewById(R.id.antwort4);
38 btn.setOnClickListener(ln);
39 break;
40
41 }
42 }
43
44 // 1. Frage laden
45 spiel.fragen[spiel.aktFrage].anzeigen(this);
46 }
47
48 public void onClick(View v, Spiellogik spiel) {
49 int id = v.getId();
50
51 if (id == R.id.antwort1)
52 spiel.auswerten(1, this);
53 // spielAuswerten(1);
54 else if (id == R.id.antwort2)
55 spiel.auswerten(2, this);
56 // spielAuswerten(2);
57 else if (id == R.id.antwort3)
58 spiel.auswerten(3, this);
59 // spielAuswerten(3);
60 else if (id == R.id.antwort4)
61 spiel.auswerten(4, this);
62 // spielAuswerten(4);
63 }
64
65 @Override
66 public void onClick(View v) {
67 // TODO Auto-generated method stub
68
69 }
70}

Frage.class
1package de.versuch;
2
3import android.app.Activity;
4import android.widget.Button;
5import android.widget.TextView;
6
7class Frage {
8 private String frage;
9 private String option1;
10 private String option2;
11 private String option3;
12 private String option4;
13 private int loesung;
14
15 public Frage(String f,
16 String o1, String o2, String o3, String o4,
17 int l) {
18 frage = f;
19 option1 = o1;
20 option2 = o2;
21 option3 = o3;
22 option4 = o4;
23 loesung = l;
24 }
25 public void anzeigen(Activity quizActivity) {
26 ((TextView) quizActivity.findViewById(R.id.frage)).setText(frage);
27 ((Button) quizActivity.findViewById(R.id.antwort1)).setText(option1);
28 ((Button) quizActivity.findViewById(R.id.antwort2)).setText(option2);
29 ((Button) quizActivity.findViewById(R.id.antwort3)).setText(option3);
30 ((Button) quizActivity.findViewById(R.id.antwort4)).setText(option4);
31 }
32
33 public boolean richtig(int ausgewaehlt) {
34 if (ausgewaehlt == this.loesung)
35 return true;
36 else
37 return false;
38 }
39 }
Spiellogik.class
1package de.versuch;
2
3import android.app.Activity;
4import android.widget.Button;
5import android.widget.ProgressBar;
6import android.widget.Toast;
7
8class Spiellogik {
9 final int ANZAHL_FRAGEN = 8;
10
11 Frage[] fragen = new Frage[ANZAHL_FRAGEN];
12 byte aktFrage = 0;
13 int gewinnstufe = 0;
14 Spiellogik() {
15 // Fragen erzeugen
16 fragen[0] =
17 new Frage("Wer ist Lukes Vater?",
18 "Darth Vader", "Obi Wan Kenobi",
19 "Der Imperator", "Bail Organa", 1);
20
21 fragen[1] =
22 new Frage("Wer tötet den Imperator?",
23 "Luke", "Darth Vader", "Obi Wan Kenobi", "Lea", 2);
24
25 // und so fort
26 }
27
28 void auswerten(int schalter, Activity quizActivity) {
29
30 if (!fragen[aktFrage].richtig(schalter)) {
31 // falsche Antwort
32 if (gewinnstufe == 0) {
33 Toast.makeText(quizActivity,
34 "Leider nichts gewonnen. :-(",
35 Toast.LENGTH_LONG).show();
36 }
37 else {
38 String str = "Sie haben Gewinnstufe " + gewinnstufe +
39 " erreicht! :-) - Glückwunsch!!!";
40 Toast.makeText(quizActivity, str,
41 Toast.LENGTH_LONG).show();
42 } // Schalter deaktivieren
43 ((Button) quizActivity.findViewById(R.id.antwort1)).setEnabled(false);
44 ((Button) quizActivity.findViewById(R.id.antwort2)).setEnabled(false);
45 ((Button) quizActivity.findViewById(R.id.antwort3)).setEnabled(false);
46 ((Button) quizActivity.findViewById(R.id.antwort4)).setEnabled(false);
47
48 }
49 else {
50 if (aktFrage < ANZAHL_FRAGEN-1) {
51 fragen[++aktFrage].anzeigen(quizActivity);
52
53 gewinnstufe++;
54 ((ProgressBar) quizActivity.findViewById(
55 R.id.progressBar1)).setProgress(gewinnstufe);
56 }
57 else {
58 gewinnstufe++;
59 ((ProgressBar) quizActivity.findViewById(
60 R.id.progressBar1)).setProgress(gewinnstufe);
61 String str = "Super, Alles richtig beantwortet!!!";
62 Toast.makeText(quizActivity, str,
63 Toast.LENGTH_LONG).show();
64 // Schalter deaktivieren
65 ((Button) quizActivity.findViewById(R.id.antwort1)).setEnabled(false);
66 ((Button) quizActivity.findViewById(R.id.antwort2)).setEnabled(false);
67 ((Button) quizActivity.findViewById(R.id.antwort3)).setEnabled(false);
68 ((Button) quizActivity.findViewById(R.id.antwort4)).setEnabled(false);
69
70 }
71 }
72 }
73 }

Manifest:
1<manifest xmlns:android="schemas.android.com/apk/res/android"
2 package="de.versuch"
3 android:versionCode="1"
4 android:versionName="1.0" >
5
6 <uses-sdk
7 android:minSdkVersion="8"
8 android:targetSdkVersion="15" />
9
10 <application
11 android:icon="@drawable/ic_launcher"
12 android:label="@string/app_name"
13 android:theme="@style/AppTheme" >
14 <activity
15 android:name=".Quiz"
16 >
17 <intent-filter>
18 <action android:name="android.intent.action.MAIN" />
19
20 <category android:name="android.intent.category.LAUNCHER" />
21 </intent-filter>
22 </activity>
23 </application>
24
25</manifest>
Ich hoffe ihr könnt mir wieder weiter helfen ;)

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 15:55:20 via Website

Mit UiThread hab ich mich jetzt noch gar nicht auseinander gesetzt. Könntest du mir evtl. ein Beispiel dazu geben, damit ich ungefähr verstehe was ich machen muss?

Antworten
Michele
  • Forum-Beiträge: 1.525

05.02.2014, 16:00:07 via Website

Hallo.

Gibt doch erstmal in Google z.B "android runonuithread example" ein.

Da findest du genug :D Und wenn du dann noch fragen hast, kannst du gerne wieder fragen.


LG

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 16:34:15 via Website

Ich hab jetzt mal das Beispiel von developer.android.com/training/multiple-threads/define-runnable.html genommen.
Ich hab schon gegoogelt, nur war ich mir nicht sicher wie ich das genau umsetzen soll :)


Wäre das so richtig? Oder muss die auswerten-Methode rein?

1class PhotoDecodeRunnable implements Runnable {
2...
3 /*
4 * Defines the code to run for this task.
5 */
6// 1. Frage laden
7 spiel.fragen[spiel.aktFrage].anzeigen(this);
8 }
9
10 public void onClick(View v, Spiellogik spiel) {
11 int id = v.getId();
12
13 if (id == R.id.antwort1)
14 spiel.auswerten(1, this);
15 // spielAuswerten(1);
16 else if (id == R.id.antwort2)
17 spiel.auswerten(2, this);
18 // spielAuswerten(2);
19 else if (id == R.id.antwort3)
20 spiel.auswerten(3, this);
21 // spielAuswerten(3);
22 else if (id == R.id.antwort4)
23 spiel.auswerten(4, this);
24 // spielAuswerten(4);
25 }
26
27 @Override
28 public void run() {
29 // Moves the current Thread into the background
30 android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
31 ...
32 /*
33 * Stores the current Thread in the PhotoTask instance,
34 * so that the instance
35 * can interrupt the Thread.
36 */
37 mPhotoTask.setImageDecodeThread(Thread.currentThread());
38 ...
39 }
40...
41}

Antworten
Michele
  • Forum-Beiträge: 1.525

05.02.2014, 16:43:18 via Website

Guck mal.
Bin zwar schlecht in erklären aber ich versuche es mal.

Es lässt sich wie z.B der TextView usw in der Activity nur in den runOnUiThread aktualisieren, zumindestens wenn es das von selbst machen soll.
So kenne ich das.

Wie geht man dann vor?

1runOnUiThread(new Runnable() {
2 @Override
3 public void run() {
4
5// Dein Text der im lauf der Activity aktualisiert werden soll
6
7 }
8 });



LG

— geändert am 05.02.2014, 16:52:41

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 16:52:29 via Website

Ah verstehe also in meinem Beispiel dann nur die anzeigen Methode, also das was die Fragen und Antworten auf den Oberflächen-Objekte anzeigt?


11 runOnUiThread(new Runnable() {
22 @Override
33 public void run() {
44
55// Dein Text der im lauf der Activity aktualisiert werden soll
6public void anzeigen(Activity quizActivity) {
7 ((TextView) quizActivity.findViewById(R.id.frage)).setText(frage);
8 ((Button) quizActivity.findViewById(R.id.antwort1)).setText(option1);
9 ((Button) quizActivity.findViewById(R.id.antwort2)).setText(option2);
10 ((Button) quizActivity.findViewById(R.id.antwort3)).setText(option3);
11 ((Button) quizActivity.findViewById(R.id.antwort4)).setText(option4);
12 }
13
14}
15 });

Antworten
Michele
  • Forum-Beiträge: 1.525

05.02.2014, 16:53:32 via Website

Jap denke schon.

Versuche es :D


LG

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 17:24:35 via Website

Kann ich das in der Frage.class ändern oder muss ich dazu eine neue Class anlegen?

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

05.02.2014, 17:31:14 via Website

ist egal, am einfachsten ist es wenn du dies in die Fragen Klasse schreibt

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

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 17:32:28 via Website

Ok danke, werde es gleich Mal ausprobieren ;)

— geändert am 05.02.2014, 17:33:06

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 17:56:28 via Website

Ich hab das jetzt mal so eingebaut

1package de.versuch;
2
3import android.app.Activity;
4
5import android.widget.Button;
6import android.widget.TextView;
7
8class Frage {
9 private String frage;
10 private String option1;
11 private String option2;
12 private String option3;
13 private String option4;
14 private int loesung;
15
16 public Frage(String f,
17 String o1, String o2, String o3, String o4,
18 int l) {
19 frage = f;
20 option1 = o1;
21 option2 = o2;
22 option3 = o3;
23 option4 = o4;
24 loesung = l;
25 }
26
27 //******************************************************************
28 Runnable runOnUiThread = new Runnable() {
29 public void run(Activity quizActivity) {
30
31 ((TextView) quizActivity.findViewById(R.id.frage)).setText(frage);
32 ((Button) quizActivity.findViewById(R.id.antwort1)).setText(option1);
33 ((Button) quizActivity.findViewById(R.id.antwort2)).setText(option2);
34 ((Button) quizActivity.findViewById(R.id.antwort3)).setText(option3);
35 ((Button) quizActivity.findViewById(R.id.antwort4)).setText(option4);
36
37 }
38
39@Override
40public void run() {
41 // TODO Auto-generated method stub
42
43}
44};
45
46
47
48
49
50 //**********************************************************************
51 public boolean richtig(int ausgewaehlt) {
52 if (ausgewaehlt == this.loesung)
53 return true;
54 else
55 return false;
56
57 }
58
59
60 }

Also zuerst hat ich einen Klammer Fehler, den hab ich behoben, dann kam der Fehler, "The type new Runnable(){} must implement the inherited astract method Runnable.run()", hab den Lösungsvorschlag genommen, Fehler war weg, jetzt aber wurde dadurch ein neues @override public void run erschaffen, zu sehen in Z. 39. Das hat dann auch den nächsten Fehler gebracht, nämlich "The method run(Activity) from the type new Runnable(){} is never used locally" . Wenn ich aber das ab Z.39 lösche, bekomm ich wieder den Fehler "The type new Runnable(){} must implement the inherited abstract method Runnable.run()"
Was mach ich falsch?..

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

05.02.2014, 18:16:41 via Website

Alles muss in die Run Methode Verschoben werden, und du kannst die Activity nicht übergeben sondern musst sie als Klassenvariable der Klasse Frage anlegen und im RunOnUI dann abfragen.

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

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 18:47:05 via Website

Der Fehler in der Frage.class ist zwar jetzt weg aber in den andern beiden Klassen hab ich jetzt den Fehler "The left-hand side of an assignment must be a variable", der taucht da auf wo ich die Methode "anzeigen" zu "run" geändert hab.

Was bedeutet der Fehler?

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

05.02.2014, 19:05:11 via Website

Wieso änderst du irgendwas?
Du hast das noch nicht ganz verstanden.
Machst du denn Überhaupt einen anderen Thread auf, der immer eine andere Frage aufruft? Sonst ist die RunOnUi unötig.
Bitte Poste den entsprechenden Code

— geändert am 05.02.2014, 19:05:22

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

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 19:50:16 via Website

1package de.versuch;
2
3import android.app.Activity;
4import android.widget.Button;
5import android.widget.TextView;
6import de.versuch.R;
7
8public class Frage implements Runnable {
9 Activity quizActivity;
10 private String frage;
11 private String option1;
12 private String option2;
13 private String option3;
14 private String option4;
15 private int loesung;
16
17 public Frage(String f, String o1, String o2, String o3, String o4, int l) {
18 frage = f;
19 option1 = o1;
20 option2 = o2;
21 option3 = o3;
22 option4 = o4;
23 loesung = l;
24 }
25
26 @Override
27 public void run() {
28
29 ((TextView) quizActivity.findViewById(R.id.frage)).setText(frage);
30 ((Button) quizActivity.findViewById(R.id.antwort1)).setText(option1);
31 ((Button) quizActivity.findViewById(R.id.antwort2)).setText(option2);
32 ((Button) quizActivity.findViewById(R.id.antwort3)).setText(option3);
33 ((Button) quizActivity.findViewById(R.id.antwort4)).setText(option4);
34
35 }
36
37 public boolean richtig(int ausgewaehlt) {
38 if (ausgewaehlt == this.loesung)
39 return true;
40 else
41 return false;
42 }
43
44}

Ich dachte ich muss das ändern? Weil jetzt doch alles in die Run-Methode muss?
Wenn du den Code von den anderen Klassen meintest, die sind noch unverändert und ganz oben.

Antworten
impjor
  • Forum-Beiträge: 1.793

05.02.2014, 21:02:29 via App

Dein Code vom allerersten Post in diesem Thread war eigentlich komplett in Ordnung und du kannst das ganze Zeug mit runOnUiThread weglassen, da du ja nur einen Thread benutzt.

Du hast nur zwei Fehler gemacht:
1. In deiner Activity-Klasse gibt es die Methode onClick(View v, Spiellogik spiel) diese wird NIE aufgerufen. Stattdessen würde (s. Punkt 2) immer onClick(View v) aufgerufen werden (die zweite leere Methode darunter.)
Ein onClickListener ruft immer eine Methode onClick(View egal) auf, also nur mit EINEM VIEW Parameter, woher sollte sie auch den zweiten Paramter (Spiellogik) kennen? Insofern sind beide Methoden sinnlos, verschiebe mal alles von OnClick(View v, Spiellogik spiel) in die Methode onClick(View v)

2. Du setzt allen Buttons den OnClickListener ls. Dieser macht aber gar nichts, er hat ja gar keine onClick-Methode. Deine Activity hat aber eine onClick(View v) - Methode. Setze also die Activity als OnClickListener! Button#setOnClickListener(this);
(this meint das aktuelle Objekt (in diesem Fall Activity)
LG

— geändert am 05.02.2014, 21:05:34

Liebe Grüße impjor.

Für ein gutes Miteinander: Unsere Regeln
Apps für jeden Einsatzzweck
Stellt eure App vor!

Syntac Moore

Antworten
Michele
  • Forum-Beiträge: 1.525

05.02.2014, 21:09:55 via Website

impjor
Dein Code vom allerersten Post in diesem Thread war eigentlich komplett in Ordnung und du kannst das ganze Zeug mit runOnUiThread weglassen, da du ja nur einen Thread benutzt.

Du hast nur zwei Fehler gemacht:
1. In deiner Activity-Klasse gibt es die Methode onClick(View v, Spiellogik spiel) diese wird NIE aufgerufen. Stattdessen würde (s. Punkt 2) immer onClick(View v) aufgerufen werden (die zweite leere Methode darunter.)
Ein onClickListener ruft immer eine Methode onClick(View egal) auf, also nur mit EINEM VIEW Parameter, woher sollte sie auch den zweiten Paramter (Spiellogik) kennen? Insofern sind beide Methoden sinnlos, verschiebe mal alles von OnClick(View v, Spiellogik spiel) in die Methode onClick(View v)

2. Du setzt allen Buttons den OnClickListener ls. Dieser macht aber gar nichts, er hat ja gar keine onClick-Methode. Deine Activity hat aber eine onClick(View v) - Methode. Setze also die Activity als OnClickListener! Button#setOnClickListener(this);
(this meint das aktuelle Objekt (in diesem Fall Activity)
LG

Ok stimmt, wenn du es so sagst.
Dachte lag erst am "runOnUiThread" bereich etc.
Hätte besser hingucken sollen.


LG

— geändert am 05.02.2014, 21:10:31

Antworten
Syntac Moore
  • Forum-Beiträge: 44

05.02.2014, 22:55:12 via Website

Jaaaaaa, es funktioniert!! Vielen vielen Dank an alle die mir hier geholfen haben, besonders für eure Geduld! :D Ihr glaubt gar nicht wie lang ich schon an diesem Problem dran saß... :)

Ich werde jetzt noch vor, das ganze mit einer Datenbank zu verknüpfen und einen Highscore mit 10 Plätzen einzufügen, Ersteres dürfte nicht all zu schwer sein, beim Highscore bin ich aber noch am überlegen, mit Shared Preferences müsste das ganz gut funktionieren denk ich, oder habt ihr noch andere Vorschläge?

Vielen Dank nochmal,
Syntac

— geändert am 05.02.2014, 23:32:45

Antworten