2012-04-02 11 views
1

Ich bin ein Brettspiel in Android zu schreiben, wo die Benutzeroberfläche von Textviews für die Bewertung (CPUScore und PlayerScore) besteht. Das Problem, das ich habe, ist, dass die Benutzeroberfläche nicht den Punktestand von seinem Anfangswert aktualisiert, wenn onCreate aufgerufen wird. Ich habe ähnliche Fragen untersucht und die am häufigsten vorgeschlagene Lösung ist die Verwendung von AsyncTask, um den UI-Thread im Hintergrund zu aktualisieren. Allerdings habe ich keine Lösung gefunden, die sich explizit mit der Verwendung von textViews in AsyncTask befasst.Refresh Spiel Ergebnis Textview AsyncTask mit

Hier ist mein Versuch:

@Override 
    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
//.... 
setContentView(R.layout.main_layout); 

//..... 
//------------ textViews declared here don't refresh ------------------- 
TextView playerScoreForm = (TextView) findViewById(R.id.PlayerTotalScore); 
     playerScoreForm.setText(Integer.toString(PlayerTotal)); 
     playerScoreForm.invalidate(); 

     TextView CPUScoreForm = (TextView) findViewById(R.id.CPUTotalScore); 
     CPUScoreForm.setText(Integer.toString(CPUTotal)); 
     CPUScoreForm.invalidate(); 
//--------------------------------------------------------------------------  
//AsyncTask method:  
     new updatePlayerScore().execute(PlayerTotal); 
     new updateCPUScore().execute(CPUScoreForm); 
    } 

Die AsyncTask Subklassen:

private class updatePlayerScore extends AsyncTask<TextView, Void, Void> { 

     @Override 
      protected TextView doInBackground(TextView... params) { 


        // what to put here?? 



      } 
      return playerScoreForm; 
     } 

      @Override 
     protected void onProgressUpdate(Integer... values) { 
      //?? 
     } 

     protected void onPostExecute(Integer result) { 
      playerScoreForm.setText(Integer.toString(result)); 
     } 

    } 


    private class UpdateCPUScore extends AsyncTask<TextView, Integer, Integer> { 
     // same syntax as updatePlayerScore 

    } 

Frage: wie übertrage ich die Textviews, die ich in der onCreate Methode zum AsyncTask Methode deklariert? Ich bin ratlos. Ich bin ziemlich neu in der Android-Entwicklung.

+0

make 'playerScoreForm' und so auf die Teilnehmer/geben sie im Konstruktor oder die params Ihrer benutzerdefinierten AsyncTask. – zapl

+0

Könnten Sie mir bitte ein ungefähres Beispiel dafür geben? – Buzz

Antwort

2

a) Ich bin mir ziemlich sicher, dass Sie sollten nicht die Textviews ungültig zu machen müssen, nachdem Sie sie eingestellt; Android sollte das automatisch machen.

b) Theoretisch würden Sie Ihre TextView Referenzen als Mitgliedsvariablen festlegen und dann in onPostExecute referenzieren, statt sie in doInBackground zu übergeben. doInBackground wiederum nimmt an, welche Daten die Berechnung des neuen Scores ermöglichen. Was Sie unter doInBackground tun würden, ist, welche Aktion auch immer eine neue Punktzahl berechnet. Der Rückgabewert von doInBackground wird an onPostExecute übergeben. Sie würden dann die TextView (jetzt eine Mitgliedsvariable) mit diesen Daten in onPostExecute aktualisieren. Ist das sinnvoll? Sie haben hier keinen Code veröffentlicht, der diese Werte aktualisiert.

Siehe here für ein schnelles Beispiel.

private TextView myScoreView; //initialized in onCreate as you do above. 


@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    //.... 
    setContentView(R.layout.main_layout); 

    //..... 

    myScoreView = (TextView) findViewById(R.id.PlayerTotalScore); 
    myScoreView.setText(Integer.toString(PlayerTotal)); 

    new updatePlayerScore().execute(1,2); //parameters for calculation 
} 

private class updatePlayerScore extends AsyncTask<Integer, Integer, Integer> { 

     @Override 
     protected TextView doInBackground(Integer... params) { 

       int score = params[0] + 2 * params[1]; 
       return score; 
     } 


     @Override 
     protected void onProgressUpdate(Integer... values) { 
      //if you want to provide some indication in the UI that calculation 
      //is happening, like moving a progress bar, that's what you'd do here. 
     } 

     @Override 
     protected void onPostExecute(Integer scoreCalculationResult) { 
      myScoreView.setText(Integer.toString(scoreCalculationResult)); 
     } 

} 

Edit: Wenn Sie die Berechnungslogik in doInBackgroundThread nicht tun wollen, Sie wollen wahrscheinlich nur verwenden:

runOnUiThread(new Runnable(){ 
    @Override 
    public void run(){ 
     myScoreView.setText(PlayerScoreValue); 
    } 
}); 

Oder: kann

myScoreView.post(new Runnable(){ 
    @Override 
    public void run(){ 
     myScoreView.setText(PlayerScoreValue); 
    } 
}); 
+0

Danke für Ihren Kommentar. Die Punkte public int PlayerTotal und public int CPUTotal werden während des Spiels durch die Spiellogik aktualisiert. Meine Frage ist, wie man konvertiert: TextView playerScoreForm = (TextView) findViewById (R.id.PlayerTotalScore); playerScoreForm.setText (Integer.toString (PlayerTotal)); zu einem AsyncTask-Prozess.Wenn setText für textView PlayerScoreForm ausgeführt wird, wird der aktualisierte Wert von PlayerTotal (aus der Game-Schleife aktualisiert) nicht an den UI-Thread übergeben. – Buzz

+0

Es klingt wie AsyncTask ist nicht das richtige, hier zu verwenden, dann. Ich werde meine Antwort aktualisieren. –

+0

Vielen Dank. Früher habe ich Ihren ersten bearbeiten Vorschlag und eingeschlossen in einem Void-Methode updateScores(): public void updateScores() { \t \t \t runOnUiThread (neu Runnable() { \t \t \t @Override \t \t \t public void run() { \t \t \t \t playerScoreForm.setText (Integer.toString (PlayerTotal)); \t \t \t \t CPUScoreForm.setText (Integer.toString (CPUTotal)); \t \t \t} \t \t}); \t}. Der Trick bestand darin, es von onCreate für die anfängliche Punktzahl zu nennen, dann rufen Sie es von der Methode in dem Spiel auf, in dem die Punktzahlen erzeugt werden. – Buzz

0

Sie den Pass TextView im Konstruktor der AsyncTask und aus der onPostExecute Methode aktualisieren

private class updatePlayerScore extends AsyncTask<Void, Void, Integer> { 
private TextView view; 
public updatePlayerScore(TextView textView){ 
this.view = textView; 
} 
     @Override 
      protected Integer doInBackground(Void... params) { 
      int score = 0; 

        //do you calculation the 

      return score; 
     } 
     protected void onPostExecute(Integer result) { 
      view.setText(Integer.toString(result)); 
     } 

    } 

Anmerkung: Wenn Sie Aktivität Konfigurationsänderung aus irgendeinem Grund dh der Benutzer drehen das Gerät und die Sie AsyncTask hat es das Update von Ihnen nicht Aufgabe beenden TextView werden nicht aktualisiert, so dass Sie eine Instanz von Ihnen behalten sollte AsyncTask und aktualisieren die die Textview

+0

Danke für Ihren Beitrag. Mein Fehler war, dass ich versuchte, Punkte von onCreate zu bekommen, aber das war falsch, da onCreate nur einmal ausgelöst wird (dh wenn die Aktivität zum ersten Mal erstellt wird), also versucht, Punkte zu erhalten, wenn onCreate ausgeführt wurde die bei der Initialisierung an onCreate übergeben wurden. – Buzz