Android TextView'da metin nasıl değiştirilir


92

Bunu yapmaya çalıştım

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

ancak bazı nedenlerden dolayı, çalıştırdığımda yalnızca ikinci metin görünüyor. Thread.sleep()Yöntem engelleme ile bir ilgisi olabileceğini düşünüyorum . Birisi bana bir zamanlayıcıyı "eşzamansız olarak" nasıl uygulayacağımı gösterebilir mi?

Teşekkürler.


2
Yalnızca ikinci satırı göstermesinin nedeni .setText(), tüm "parçacığı" ayarlamasını söylediğiniz metinle değiştirmesidir; Zaten oraya koyduğunuz metin DAHİL.
georgiaboy82

Yanıtlar:


46

Bu cevabı az önce android-talk google grubunda yayınladım

Görünüme sadece "Birinci Adım: yumurta patlatın İkinci Adım: yumurtayı kızartın" ifadesini görüntüleyecek şekilde metin eklemeye çalışıyorsanız, t.appendText("Step Two: fry egg"); bunun yerine kullanmayı düşününt.setText("Step Two: fry egg");

TextViewBaşlangıçta "Birinci Adım: yumurtayı patlat" yazacak şekilde ve daha sonra "İkinci Adım: yumurtayı kızart" yazacak şekilde içindekileri tamamen değiştirmek istiyorsanız, her zaman bir

Runnable örnek sadboy verdi

İyi şanslar


146

Kişisel onCreate()yöntem birçok büyük kusuru vardır:

1) Etkinliğinizi onCreate hazırlar - böylece burada yaptığınız hiçbir şey, bu yöntem bitene kadar kullanıcı tarafından görülebilir hale getirilmez! Örneğin - TextViewburada bir metnini asla BİR defadan fazla değiştiremezsiniz, çünkü yalnızca son değişiklik çizilir ve böylece kullanıcı tarafından görülebilir!

2) Bir Android programının varsayılan olarak yalnızca BİR iş parçacığında çalışacağını unutmayın ! Böylece: asla kullanmayın Thread.sleep()veya Thread.wait()ana iş parçacığı içinde UI sorumlu olan! ( Daha fazla bilgi için "Uygulamanızı Duyarlı Tutun" bölümünü okuyun !)

Ne başlatma sizin Faaliyet yapmasıdır:

  • sebepsiz yere yeni bir TextViewnesne yaratırsınız t!
  • Daha sonra TextViewdeğişkendeki düzeninizi seçersiniz t.
  • metnini ayarlarsınız t(ancak unutmayın: yalnızca tamamlandıktan ve uygulamanızın ana olay döngüsü çalıştıktan sonra görüntülenecektir onCreate()!)
  • Eğer beklemek 10 saniye sizin içinde onCreateyöntemiyle - Bu yapılması asla tüm UI aktivitesini durdurur ve kesinlikle bir ANR zorlar olarak (yukarıdaki bağlantıya bakın, Uygulama Yanıt Vermiyor!)
  • sonra başka bir metin belirlersiniz - bu, onCreate()yönteminiz biter bitmez görüntülenecektir ve diğer birkaç Etkinlik yaşam döngüsü yöntemi işlenir!

Çözüm:

  1. Metni yalnızca bir kez ayarlayın onCreate()- bu, görünür olması gereken ilk metin olmalıdır.

  2. Bir Runnableve bir oluşturHandler

    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. bu çalıştırılabilirliği bir işleyici olarak kurun, mümkün onCreate()(ancak aşağıdaki tavsiyemi okuyun):

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

Tavsiye: Bir Activityyaşam döngüsünü bildiğinizden emin olun ! Böyle şeyler yaparsanız, onCreate()bu sadece sizin ilkActivity yaratıldığında gerçekleşir ! Android, görünür olmasa bile muhtemelen sizi daha uzun süre hayatta tutacaktır ! Bir kullanıcı onu tekrar "başlattığında" - ve hala mevcutsa - artık ilk metninizi görmeyeceksiniz!Activity


=> İşleyicileri her zaman içine kurun onResume()ve onları devre dışı bırakın onPause()! Aksi takdirde Activity, hiç görünmediğinizde "güncellemeler" alacaksınız ! Sizin durumunuzda, yeniden etkinleştirildiğinde ilk metninizi tekrar görmek istiyorsanız, onu ayarlamalısınız onResume(), değil onCreate()!


14

Yeni metin görünümünün ilk satırı gereksizdir

t=new TextView(this); 

bunu sadece yapabilirsin

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

Burada uyuyan bir arka plan iş parçacığına göre bir örnek, ancak bunun için daha iyi bir zamanlayıcı olduğunu düşünüyorum. http://android-developers.blogspot.com/2007/11/stitch-in-time.html yerine bir zamanlayıcı kullanan iyi bir örneğe bağlantı burada

    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

@kendinelaik

Bir String değişkeni kullanırken ya "" String ile önek almam ya da açıkça CharSequence'a dönüştürmem gerektiğini buldum.

Yani bunun yerine:

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

Deneyin:

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

veya:

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

veya dizeniz dinamik olmadığı için daha da iyi:

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

3

Tavsiyenize göre, bir "zamanlayıcı" kullanarak TextView içeriğini değiştirmek / değiştirmek için handle ve runnables kullanıyorum. Bazı nedenlerden dolayı, uygulama çalışırken her zaman ikinci adımı atlar ("İkinci Adım: yumurtayı kızartın") ve yalnızca son (üçüncü) adımı gösterir ("Üçüncü adım: yumurtayı servis et").

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
Bu işe yaramaz! Sadece BİR işleyici var - mevcut tek mWaitRunnable koşucunuzun sText'in bir zamanlar "İkinci Adım" ve ardından "Üçüncü Adım" olarak ayarlandığını "bilmesini" nasıl istersiniz !! ?? İlk kez çağrıldığı zaman (3 saniye sonra) - sText'in değeri "Üçüncü Adım" dır! Android programlamayı denemeden önce temel Java becerilerini öğrenmelisiniz! :-)
Zordid

aslında nihayet yaptığım şey runnable'ın içine bir sayaç eklemek oldu, eğer 1 ise, metin bu olacak, eğer 2 ise, metin bu olacak, vb.
user270811

0

:) İpliği yanlış kullanıyorsunuz. Sadece aşağıdakileri yapın:

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

Bu kadar.


0

metni aynı metin görünümüne iki kez ayarlamak, ilk yazılı metnin üzerine yazmaktır. Böylece settext'i ikinci kez kullandığımızda, yeni dizeyi şöyle ekleriz:

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

0

@Zordid @Iambda cevabı harika, ama şunu koyarsam buldum

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

run () yönteminde ve

mHandler.postDelayed(mUpdateUITimerTask, 0);

onCreate yönteminde, şeyin güncellenmeye devam etmesini sağlayın.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.