2012-04-02 10 views
1

私は、UIがスコア(CPUScoreとPlayerScore)のテキストビューで構成されているボードゲームをAndroidで作成しています。私が持っている問題は、onCreateが呼び出されたときにUIが初期値からスコアを更新しないということです。私は同様の質問を見てきました。ほとんどの場合、AsyncTaskを使用してUIスレッドをバックグラウンドで更新する方法があります。しかし、AsyncTaskでtextViewsを使用する方法を明示的に扱うソリューションは見つかりませんでした。Refresh Game Score AsyncTaskを使用したTextView

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

AsyncTaskのサブクラス:ここ

は私の試みです

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 

    } 

質問: はどのように私はAsyncTaskメソッドへのonCreateメソッド内で宣言textViewsを転送するのですか?私は困惑している。私はAndroid開発にかなり新しいです。

+0

'playerScoreForm'などをクラスメンバー/コンストラクタやカスタムAsyncTaskのパラメータに渡します。 – zapl

+0

どうすればいいか教えてください。 – Buzz

答えて

2

a)TextViewを設定した後に無効にする必要はありません。 Androidはそれを自動的に行う必要があります。

b)理論的には、TextViewの参照をメンバー変数に設定してから、doInBackgroundに渡す代わりにonPostExecuteで参照してください。 doInBackgroundは、新しいスコアを計算するためのデータのビット数を使用します。 doInBackgroundで行うことは、新しいスコアが計算されるような行動です。 doInBackgroundの戻り値はonPostExecuteに渡されます。次に、このデータでTextView(メンバ変数)をonPostExecuteに更新します。それは理にかなっていますか?これらのスコア値を更新するコードは実際にはここに掲載していません。

簡単な例としてhereを参照してください。

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

} 

編集:あなたがdoInBackgroundThreadで計算ロジックを行うにはしたくない場合、あなたはおそらく使用したい:

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

または:

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

ご意見ありがとうございます。スコアpublic int PlayerTotalとpublic int CPUTotalは、ゲームのプレイ中にゲームロジックによって更新されます。私の質問は変換する方法です:TextView playerScoreForm =(TextView)findViewById(R.id.PlayerTotalScore); playerScoreForm.setText(Integer.toString(PlayerTotal)); AsyncTaskプロセスに渡します。textView PlayerScoreFormでsetTextを実行すると、(ゲームループから更新された)PlayerTotalの更新された値はUIスレッドに渡されません。 – Buzz

+0

AsyncTaskはここで使用するのが適切ではないようです。私は私の答えを更新します。 –

+0

ありがとうございました。私はあなたの最初の編集の提案を使用し、voidメソッドのupdateScores()でそれを囲んます。public void updateScoresを(){ \t \t \t runOnUiThread(新しいRunnableを(){ \t \t \t @Override \t \t \tます。public void実行() { \t \t \t \t playerScoreForm.setText(持つInteger.toString(PlayerTotal)); \t \t \t \t CPUScoreForm.setText(持つInteger.toString(CPUTotal)); \t \t \t} \t \t}); \t}。そのトリックは、最初のスコアのためにonCreateから呼び出すことでした。そして、スコアが生成されるゲームのメソッドからそれを呼び出します。 – Buzz

0

あなたは渡すことができますAsyncTaskのコンストラクタ内のTextViewを更新し、onPostExecuteメソッドから更新します。

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

    } 

ノート:ユーザーすなわちあなた何らかの理由で活動構成変更がデバイスを回転させて、あなたAsyncTaskは、それはあなたがあなたのインスタンスを保持しなければならないので、TextViewあなたの更新は更新されませんタスクを完了していない場合AsyncTaskを更新し、TextViewを更新します。

+0

あなたの貢献に感謝します。私の間違いは、onCreateから得点を得ようとしていたことですが、onCreateが一度しか起動しない(つまり、アクティビティが最初に作成されたとき)ので、onCreateが実行されたときに得点を得ようとすると、初期化時にonに渡されました。 – Buzz

関連する問題