Android TextViewでテキストを変更する方法


91

私はこれをやろうとしました

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    t=new TextView(this); 

    t=(TextView)findViewById(R.id.TextView01); 
    t.setText("Step One: blast egg");

    try {
        Thread.sleep(10000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    t.setText("Step Two: fry egg");

しかし、何らかの理由で、実行すると2番目のテキストのみが表示されます。Thread.sleep()メソッドのブロッキングと関係があるのではないかと思います。それで、誰かにタイマーを「非同期に」実装する方法を教えてもらえますか?

ありがとう。


2
2行目のみが表示されるの.setText()は、「ウィジェット」全体を、設定するように指示したテキストに置き換えるためです。あなたがすでにそこに置いたテキストを含む。
georgiaboy82 2015年

回答:


45

この回答をandroid-discuss googleグループに投稿しました

ビューにテキストを追加して「ステップ1:ブラストエッグステップ2:フライエッグ」を表示t.appendText("Step Two: fry egg"); する場合は、次の代わりに使用することを検討してください。t.setText("Step Two: fry egg");

TextView起動時に「Step One:blast egg」と表示され、後で「Step Two:fry egg」と表示されるように内容を完全に変更する場合は、常に

悲しい男の子が与えた実行可能な例

幸運を


147

あなたのonCreate()方法にはいくつかの大きな欠陥があります:

1)アクティビティをonCreate 準備します。ここで行うことは、このメソッドが完了するまでユーザーには表示されません。たとえば-あなたが変えることができることはありませんTextView、ここでより多くのテキストをONEのみ最後の変更として、時間が描かれ、ユーザに、見えるようになります!

2)Androidプログラムは、デフォルトでは1つのスレッドでのみ実行されることに注意してください。したがって、UIを担当するメインスレッドで、Thread.sleep()またはThread.wait()メインスレッドで使用しないでください。(詳細については、「アプリをレスポンシブに保つ」を読んでください!)

どのようなあなたの初期化、あなたの活動のでないことは次のとおりです。

  • 理由もなく、新しいTextViewオブジェクトを作成しますt
  • TextView変数のレイアウトはt後で選択します。
  • のテキストを設定しますt(ただし onCreate()終了してアプリケーションのメインイベントループが実行された後にのみ表示されます!)
  • あなたが待つ10秒あなたの内のonCreate方法-これが行われてはならない、それはすべてのUIの活動を停止し、間違いなくANR強制されるよう(上記のリンクを参照してください、アプリケーションが応答しないと!)
  • 次に、別のテキストを設定します。これは、onCreate()メソッドが終了し、他のいくつかのアクティビティライフサイクルメソッドが処理されるとすぐに表示されます。

ソリューション:

  1. テキストを一度だけ設定しますonCreate()-これは、表示される最初のテキストでなければなりません。

  2. a Runnableとaを作成するHandler

    private final Runnable mUpdateUITimerTask = new Runnable() {
        public void run() {
            // do whatever you want to change here, like:
            t.setText("Second text to display!");
        }
    };
    private final Handler mHandler = new Handler();
    
  3. この実行可能ファイルをハンドラーとしてインストールしますonCreate()(以下のアドバイスを読んでください)。

    // run the mUpdateUITimerTask's run() method in 10 seconds from now
    mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);
    

アドバイス:Activityのライフサイクルを必ず知っておいてください!あなたがそのようなことをonCreate()すると、これはあなたActivity最初に作成されたときにのみ起こります!AndroidはActivity、たとえ表示されていなくても、おそらくより長く生き続けるでしょう。ユーザーがもう一度「開始」すると、それがまだ存在している場合は、最初のテキストが表示されなくなります。


=>にハンドラを常にインストールしonResume()て無効にしてonPause()ください!それ以外の場合は、あなたActivityがまったく表示されないときに「更新」を取得します!あなたの場合、最初のテキストが再びアクティブになったときにもう一度表示したい場合はonResume()、ではなく、で設定する必要がありますonCreate()


14

新しいテキストビューの最初の行は不要です

t=new TextView(this); 

あなたはこれを行うことができます

TextView t = (TextView)findViewById(R.id.TextView01);

ここでスリープしているバックグラウンドスレッドまでは一例ですが、これにはより良いタイマーがあると思います。代わりにタイマーを使用した良い例へのリンクがあります http://android-developers.blogspot.com/2007/11/stitch-in-time.html

    Thread thr = new Thread(mTask);
    thr.start();
}

Runnable mTask = new Runnable() {
    public void run() {
        // just sleep for 30 seconds.
                    try {
                        Thread.sleep(3000);
                        runOnUiThread(done);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
        }
    };

    Runnable done = new Runnable() {
        public void run() {
                   // t.setText("done");
            }
        };

6

@ user264892

文字列変数を使用する場合、文字列に ""をプレフィックスとして付けるか、明示的にCharSequenceにキャストする必要があることがわかりました。

だから代わりに:

String Status = "Asking Server...";
txtStatus.setText(Status);

試してください:

String Status = "Asking Server...";
txtStatus.setText((CharSequence) Status);

または:

String Status = "Asking Server...";    
txtStatus.setText("" + Status);

または、文字列は動的ではないため、さらに優れています。

txtStatus.setText("AskingServer...");

3

あなたのアドバイスに従って、私はハンドルとランナブルを使用して、「タイマー」を使用してTextViewのコンテンツを切り替え/変更しています。なんらかの理由で、実行中、アプリは常に2番目のステップ(「ステップ2:卵焼き」)をスキップし、最後(3番目)のステップ(「ステップ3:卵料理」)のみを表示します。

TextView t; 
private String sText;

private Handler mHandler = new Handler();

private Runnable mWaitRunnable = new Runnable() {
    public void run() {
        t.setText(sText);
    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    mMonster = BitmapFactory.decodeResource(getResources(),
            R.drawable.monster1);

    t=new TextView(this); 
    t=(TextView)findViewById(R.id.TextView01); 

    sText = "Step One: unpack egg";
    t.setText(sText);

    sText = "Step Two: fry egg";        
    mHandler.postDelayed(mWaitRunnable, 3000);

    sText = "Step three: serve egg";
    mHandler.postDelayed(mWaitRunnable, 4000);      
    ...
}

1
これは機能しません!ハンドラは1つしかありません。既存のmWaitRunnableランナーに、sTextが一度「ステップ2」に設定され、次に「ステップ3」に設定されたことをどのように「認識」させますか?最初に呼び出されたとき(3秒後)-sTextの値は単に「ステップ3」です!Androidプログラミングを試す前に、Javaの基本的なスキルに慣れる必要があります。:-)
Zordid 2010

実際に私が最後に行ったのは、ランナブル内にカウンターが追加されました。カウンターが1の場合、テキストはこれになります。2の場合、テキストはこれになります、など
user270811

0

:)スレッドを間違った方法で使用しています。次のようにしてください:

private void runthread()
{

splashTread = new Thread() {
            @Override
            public void run() {
                try {
                    synchronized(this){

                        //wait 5 sec
                        wait(_splashTime);
                    }

                } catch(InterruptedException e) {}
                finally {
                    //call the handler to set the text
                }
            }
        };

        splashTread.start(); 
}

それでおしまい。


0

テキストをsam textviewに2回設定すると、最初に書かれたテキストが上書きされます。したがって、2回目にsettextを使用するときは、次のような新しい文字列を追加するだけです。

textview.append("Step Two: fry egg");

0

@Zordid @Iambdaの回答は素晴らしいですが、

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

run()メソッドと

mHandler.postDelayed(mUpdateUITimerTask, 0);

onCreateメソッドで、更新を続けます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.