0

TextView をモデルから更新するために、次のアプローチを試しました。

  1. TextChangeListeners - エラー
  2. その他のスレッド
  3. 非同期タスク
  4. データを更新する更新ボタンを追加しました。クリックを強制します

シナリオは次のとおりです。

  1. モデル(MVC)オブジェクトを毎秒更新する標準スレッド実行。これは完全に機能します。
  2. Model オブジェクトが更新されると、「Observer」を実装するすべてのクラスに通知されます。
  3. 私の GolfHomeScreen は Activity を拡張し、Observer を実装します (以下のコード)。
  4. GolfHomeScreen.update (Observable observable, Object data) メソッドは完全に機能します。期待どおりに毎秒実行され、正しいデータが SOP されます ( --> // * #1 *を参照)。
  5. これにより、スレッドが開始されます。このサイトで、ウィジェットを更新するコードを実行してから「runOnUiThread」メソッドを実行するには、UI スレッドを使用する必要があることを読みました。とにかく、このスレッドは実行されます ( --> // * #2を参照)) メソッド onClick(View v) を実行します ( --> // を参照)#3 * )。
  6. System.out.println("driverType :" + mvcModel.getDriverName());( --> // * #4 *を参照) 完全に機能します。
  7. // * #5 * - 更新する必要がありますが、更新しません。
  8. 実際にボタンを物理的にクリックすると、データが画面に正しく表示されます。私の唯一の推測は、強制クリックで画面を更新してはならないか、更新を行うために UI スレッドを使用していないということです。

注: 以下のコードに不足がある場合は、何が起こっているのかを簡単に理解するために大量のコードを削除したためです。

public class GolfHomeScreen extends Activity implements Observer
{
    GolfHomeScreen golfHomeScreen = null;
    TextView driverName = null; // Type of driver used by golfer (eg: 1 wood)
    Button refreshData = null;

  @Override public void onClick(View v) //*** #3 ***
  {
    if ((v.getId()) == 12345) // ID of wood (12345 = 1 wood)
    {
                    //*** #4 ***
        System.out.println("driverType              :" + mvcModel.getDriverName()); //THIS PRINTS OUT THE LATEST DATA!!!

                    //*** #5 ***
                    driverName.setText(String.valueOf(mvcModel.getDriverName()));   //THIS DOESN'T AFFECT THE SCREEN?? WHY  :-(
    }
  }

  @Override public void onCreate(Bundle savedInstanceState)
  {
    golfHomeScreen = this;
    refreshData = indViewById(R.id.golfhomescreen_button_refreshData);
    driverName = (TextView) findViewById(R.id.golfhomescreen_text_drivername);
  }

  @Override public void update(Observable observable, Object data)
  {
     // #1 ***
    System.out.println("driverType              :" + mvcModel.getDriverName());

    golfHomeScreen.runOnUiThread(new Runnable()
    {
        @Override
        public void run()
        {
            refreshData.performClick(); //*** #2 ***
        }
    });
  }

}

4

1 に答える 1

2

いくつかの提案といくつかの修正を実行します。問題が解決することを願っています。私が言っているのは、概念的に間違ったものがあるためです。私の答えは、それらの概念を修正するようなものです。

  • 削除するGolfHomeScreen golfHomeScreen = null;golfHomeScreen = this;、それ自体を参照するオブジェクトは必要ありません。混乱させているだけです。この行golfHomeScreen.runOnUiThread(new Runnable()に電話するだけですrunOnUiThread(new Runnable()
  • これに変更System.out.pr***するLog.d(TAG, MESSAGE);のは、それがログをダンプする Android の特殊な方法であり、結果にとって実際には問題にならないからです。これらのログをタグと重大度でフィルタリングできるため、標準の Java System.out よりも優れています。
  • refreshData.performClick();そのボタン内のアクションを実行する必要があるため、呼び出しなどは絶対に行わないでください。複数のソースから特定のことを実行したい場合は、 メソッド を作成しdoThatThing()、そこにアクションを配置して、 および からClickメソッドUpdateを呼び出します。あなたがやっている方法は、ボタンをクリックしてテキストを変更するために、何かを更新している「Rube Goldberg マシン」のようなものです。テキストを変更するだけです。
  • ビュー ID を番号と比較しないでくださいif ((v.getId()) == 12345)。XML から作成されたビューの ID は、コンパイル中にシステムによって生成され、固定番号かどうかはわかりません。次のように、そのビューの静的 int ID と比較する必要がありますif(v.getId() == R.id.golfhomescreen_text_drivername)。ビューが XML で作成されていない場合 (ここではそうではありません)、実際のオブジェクトと比較できます。if(v.equals(driverName))

これらの変更により、コードが機能すると思います。実際にそうである場合は、必ず私に知らせて正解としてマークしてください。

于 2013-03-03T22:45:12.157 に答える