2010-02-19 51 views
88

tôi đã cố gắng để làm điều nàylàm thế nào để thay đổi văn bản trong Android TextView

@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 đối với một số lý do, chỉ có văn bản thứ hai xuất hiện khi tôi chạy nó. Tôi nghĩ rằng nó có thể có một cái gì đó để làm với các phương pháp chặn Thread.sleep(). 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ộ"?

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 bạn yêu cầu nó đặt; BAO GỒM văn bản mà bạn đã đặt ở đó. – georgiaboy82

Trả lời

43

Tôi chỉ đăng tải câu trả lời này trong nhóm google android-thảo luận

Nếu bạn đang cố gắng để thêm văn bản vào khung nhìn sao cho nó sẽ hiển thị "Bước Một: vụ nổ trứng Bước Hai: chiên trứng" Sau đó xem xét 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 TextView để nó nói "Bước Một: vụ nổ trứng" khi khởi động và sau đó nó nói "Bước hai: fry e gg" sau một thời gian bạn luôn có thể sử dụng một

Runnable dụ sadboy đã

Chúc may mắn

14

Dòng đầu tiên của 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 được điều này

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

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

mỗi lời khuyên của bạn, tôi đang sử dụng tay cầm và Runnables chuyển/thay đổi nội dung của TextView sử dụng một "hẹn giờ". vì một số lý do, khi chạy, ứng dụng luôn bỏ qua bước thứ hai ("Bước hai: trứng chiên") 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 xử lý - làm thế nào để bạn muốn Á hậu mWaitRunnable hiện tại của bạn để "biết" rằng sText đã từng được thiết lập để "Bước hai" và sau đó đến "Bước ba" !! ?? Bởi thời gian nó được gọi là lần đầu tiên (sau 3 giây) - giá trị của sText đơn giản là "Bước ba"! Bạn nên tự làm quen với các kỹ năng Java cơ bản trước khi thử lập trình Android! :-) – Zordid

+0

thực sự những gì tôi cuối cùng đã làm được thêm một truy cập bên trong runnable, nếu nó 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

145

phương pháp onCreate() của bạn có nhiều lỗ hổng khổng lồ:

1) onCreatechuẩn bị Hoạt động của bạn - vì vậy không có gì mà bạn làm ở đây sẽ được thực hiện nhìn thấy cho người sử 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 văn bản của TextView tại đây hơn ONE thời gian vì chỉ thay đổi cuối cùng mới được hiển thị và do đó hiển thị với 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 ONE chỉ! Do đó: không bao giờ sử dụng Thread.sleep() hoặc Thread.wait() trong chuỗi chính của bạn chịu trách nhiệm về giao diện người dùng của bạn! (đọc "Keep your App Responsive" để biết thêm thông tin!)

khởi tạo của bạn của hoạt động của bạn làm là:

  • không có lý do bạn tạo một đối tượng mới TextViewt!
  • bạn chọn bố cục TextView trong biến số t sau đó.
  • bạn thiết lập các nội dung của t (nhưng lưu ý: nó sẽ được hiển thị chỉ sauonCreate() 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 chờ đợi cho 10 giây trong phương pháp onCreate của bạn - không bao giờ được thực hiện vì nó dừng tất cả hoạt động 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 phương pháp onCreate() của bạn kết thúc và một số phương pháp khác Activity lifecycle vi đã xử lý!

Giải pháp:

  1. Set văn bản chỉ một lần trong onCreate() - điều này phải là văn bản đầu tiên mà nên được hiển thị.

  2. Tạo một RunnableHandler

    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 handler, có thể trong onCreate() (nhưng đọc lời khuyên của tôi dưới đây):

    // 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 bạn biết vòng đời của Activity! Nếu bạn làm những việc như vậy trong onCreate(), điều này sẽ chỉ xảy ra khi Activity của bạn được tạo lần đầu tiên thời gian! Android có thể giữ cho số Activity của bạn hoạt động trong một khoảng thời gian dài hơn, ngay cả khi nó không hiển thị! Khi người dùng "bắt đầu" lại - 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 xử lý trong onResume() và vô hiệu hóa chúng trong onPause()! Nếu không, bạn sẽ nhận được "cập nhật" khi Activity của bạn hoàn toàn khô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 khi nó được kích hoạt lại, bạn phải đặt nó trong onResume(), chứ không phải onCreate()!

6

@ user264892

tôi thấy rằng khi sử dụng một biến String tôi cần một trong hai tiền tố với một chuỗi các "" hoặc một cách rõ ràng đúc để CharSequence.

Vì vậy, thay vì:

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

thử:

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

hay:

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

hay, kể từ chuỗi của bạn không năng động, thậm chí tốt hơn:

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

:) Bạn đang sử dụng sợi chỉ sai. Chỉ cần thực hiện 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(); 
} 

Vậy đó.

0

đặt văn bản thành văn bản sam hai lần sẽ ghi đè văn bản 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ỉ phụ thêm chuỗi mới như

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

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

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 

trong run() phương pháp và

mHandler.postDelayed(mUpdateUITimerTask, 0); 

trong phương pháp onCreate làm cho mọi thứ tiếp tục cập nhật.

Các vấn đề liên quan