cách thay đổi văn bản trong Android TextView


91

Tôi đã cố gắng làm điều này

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

nhưng vì một số lý do, chỉ có văn bản thứ hai hiển thị khi tôi chạy nó. Tôi nghĩ rằng nó có thể liên quan đến Thread.sleep()phương pháp chặn. Vì vậy, ai đó có thể chỉ cho tôi cách thực hiện một bộ đếm thời gian "không đồng bộ" không?

Cảm ơn.


2
Lý do nó chỉ hiển thị dòng thứ hai là vì .setText()thay thế toàn bộ "widget" bằng văn bản mà bạn yêu cầu nó đặt; BAO GỒM văn bản mà bạn đã đặt ở đó.
georgiaboy82

Câu trả lời:


45

Tôi vừa đăng câu trả lời này trong nhóm google thảo luận về android

Nếu bạn chỉ đang cố gắng thêm văn bản vào chế độ xem để nó hiển thị "Bước một: thổi trứng Bước hai: chiên trứng" thì hãy cân nhắc sử dụng t.appendText("Step Two: fry egg"); thay vìt.setText("Step Two: fry egg");

Nếu bạn muốn thay đổi hoàn toàn những gì có trong dòng TextViewchữ "Step One: blast egg" khi khởi động và sau đó có dòng chữ "Step Two: rán trứng", bạn luôn có thể sử dụng

Ví dụ Runnable mà Sadboy đưa ra

Chúc may mắn


146

onCreate()Phương pháp của bạn có một số sai sót lớn:

1) onCreate chuẩn bị Hoạt động của bạn - vì vậy không có gì bạn làm ở đây sẽ được hiển thị cho người dùng cho đến khi phương pháp này kết thúc! Ví dụ: bạn sẽ không bao giờ có thể thay đổi TextViewvăn bản của một văn bản ở đây nhiều hơn MỘT lần vì chỉ có thay đổi cuối cùng sẽ được vẽ và do đó hiển thị cho người dùng!

2) Hãy nhớ rằng một chương trình Android sẽ - theo mặc định - chỉ chạy trong MỘT chuỗi! Do đó: không bao giờ sử dụng Thread.sleep()hoặc Thread.wait()trong chuỗi chính của bạn, vốn chịu trách nhiệm về giao diện người dùng của bạn! (đọc "Giữ cho ứng dụng của bạn luôn phản hồi" để biết thêm thông tin!)

Những gì bạn khởi tạo Hoạt động của bạn là:

  • không có lý do gì bạn tạo một TextViewđối tượng mới t!
  • bạn chọn bố cục của mình TextViewtrong biến tsau đó.
  • bạn đặt văn bản của t(nhưng lưu ý: nó sẽ chỉ được hiển thị sau khi onCreate() kết thúc và vòng lặp sự kiện chính của ứng dụng của bạn chạy!)
  • bạn đợi 10 giây trong onCreatephương pháp của mình - điều này không bao giờ được thực hiện vì nó dừng tất cả hoạt động của giao diện người dùng và chắc chắn sẽ buộc ANR (Ứng dụng không phản hồi, xem liên kết ở trên!)
  • sau đó bạn đặt một văn bản khác - văn bản này sẽ được hiển thị ngay sau khi onCreate()phương thức của bạn kết thúc và một số phương thức vòng đời Hoạt động khác đã được xử lý!

Giải pháp:

  1. Đặt văn bản chỉ một lần trong onCreate()- đây phải là văn bản đầu tiên hiển thị.

  2. Tạo một Runnablevà mộtHandler

    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. cài đặt runnable này như một trình xử lý, có thể trong onCreate()(nhưng hãy đọc lời khuyên của tôi bên dưới):

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

Lời khuyên: hãy chắc chắn rằng bạn biết Activityvòng đời của nó! Nếu bạn làm những thứ như vậy trong onCreate()điều này sẽ chỉ xảy ra khi của bạn Activityđược tạo lần đầu tiên ! Android có thể sẽ giữ cho bạn Activitytồn tại trong một thời gian dài hơn, ngay cả khi nó không hiển thị! Khi người dùng "khởi động" lại nó - và nó vẫn tồn tại - bạn sẽ không thấy văn bản đầu tiên của mình nữa!


=> Luôn cài đặt trình xử lý trong onResume()và tắt chúng trong onPause()! Nếu không, bạn sẽ nhận được "cập nhật" khi của bạn hoàn toàn Activitykhông hiển thị! Trong trường hợp của bạn, nếu bạn muốn xem lại văn bản đầu tiên của mình khi nó được kích hoạt lại, bạn phải thiết lập nó onResume(), không phải onCreate()!


14

Dòng đầu tiên của chế độ xem văn bản mới là không cần thiết

t=new TextView(this); 

bạn chỉ có thể làm điều này

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

xa như một chuỗi nền ngủ ở đây là một ví dụ, nhưng tôi nghĩ rằng có một bộ đếm thời gian sẽ tốt hơn cho việc này. đây là liên kết đến một ví dụ điển hình bằng cách sử dụng bộ hẹn giờ thay vì 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

@ người dùng264892

Tôi nhận thấy rằng khi sử dụng biến Chuỗi, tôi cần đặt tiền tố bằng Chuỗi "" hoặc truyền rõ ràng sang CharSequence.

Vì vậy, thay vì:

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

thử:

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

hoặc là:

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

hoặc vì chuỗi của bạn không động, thậm chí tốt hơn:

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

3

Theo lời khuyên của bạn, tôi đang sử dụng tay cầm và khả năng chuyển đổi / thay đổi nội dung của TextView bằng cách sử dụng "bộ đếm thời gian". vì một số lý do, khi chạy, ứng dụng luôn bỏ qua bước thứ hai ("Bước hai: chiên trứng") và chỉ hiển thị bước cuối cùng (thứ ba) ("Bước ba: phục vụ trứng").

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
Điều này không thể hoạt động! Chỉ có MỘT trình xử lý - làm thế nào để bạn muốn trình chạy mWaitRunnable duy nhất hiện có của mình "biết" rằng sText đã từng được đặt thành "Bước hai" và sau đó là "Bước ba" !! ?? Vào thời điểm nó được gọi là lần đầu tiên (sau 3 giây) - giá trị của sText chỉ đơn giản là "Bước ba"! Bạn nên làm quen với các kỹ năng Java cơ bản trước khi thử lập trình Android! :-)
Zordid

thực sự những gì tôi cuối cùng cũng đã được bổ sung một bộ đếm bên trong Runnable, nếu đó là 1, văn bản sẽ được điều này, nếu nó là 2, văn bản sẽ được điều này, vv
user270811

0

:) Bạn đang sử dụng chủ đề sai cách. Chỉ cần làm như sau:

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

Đó là nó.


0

đặt văn bản thành sam textview hai lần là ghi đè văn bản được viết đầu tiên. Vì vậy, lần thứ hai khi chúng tôi sử dụng settext, chúng tôi chỉ cần nối thêm chuỗi mới như

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

0

@Zordid @Iambda câu trả lời là tuyệt vời, nhưng tôi thấy rằng nếu tôi đặt

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

trong phương thức run () và

mHandler.postDelayed(mUpdateUITimerTask, 0);

trong phương thức onCreate, hãy cập nhật mọi thứ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.