วิธีเปลี่ยนข้อความใน Android TextView


92

ฉันพยายามทำสิ่งนี้

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

แต่ด้วยเหตุผลบางประการมีเพียงข้อความที่สองเท่านั้นที่ปรากฏขึ้นเมื่อฉันเรียกใช้ ฉันคิดว่ามันอาจเกี่ยวข้องกับThread.sleep()วิธีการบล็อก มีใครช่วยแสดงวิธีใช้ตัวจับเวลาแบบ "อะซิงโครนัส" ได้ไหม

ขอบคุณ.


2
เหตุผลที่แสดงเฉพาะบรรทัดที่สองเพราะ.setText()แทนที่ "วิดเจ็ต" ทั้งหมดด้วยข้อความที่คุณบอกให้ตั้งค่า รวมถึงข้อความที่คุณได้ใส่ไว้แล้ว
georgiaboy82

คำตอบ:


46

ฉันเพิ่งโพสต์คำตอบนี้ในกลุ่ม android-talk google

หากคุณกำลังพยายามเพิ่มข้อความในมุมมองเพื่อให้แสดง "ขั้นตอนที่หนึ่ง: ไข่ระเบิดขั้นตอนที่สอง: ทอดไข่" จากนั้นให้พิจารณาใช้t.appendText("Step Two: fry egg"); แทนt.setText("Step Two: fry egg");

หากคุณต้องการเปลี่ยนสิ่งที่อยู่ในนั้นโดยสิ้นเชิงTextViewให้ระบุว่า "ขั้นตอนที่หนึ่ง: ไข่ระเบิด" เมื่อเริ่มต้นระบบจากนั้นจะระบุว่า "ขั้นตอนที่สอง: ทอดไข่" ในภายหลังคุณสามารถใช้

ตัวอย่างที่เรียกใช้ได้ sadboy ให้

โชคดี


146

onCreate()วิธีการของคุณมีข้อบกพร่องมากมาย:

1) onCreate เตรียมกิจกรรมของคุณ - ดังนั้นผู้ใช้จะมองไม่เห็นสิ่งใดที่คุณทำที่นี่จนกว่าวิธีนี้จะเสร็จสิ้น! ตัวอย่างเช่นคุณจะไม่สามารถแก้ไขTextViewข้อความที่นี่ได้มากกว่าหนึ่งครั้งเนื่องจากการเปลี่ยนแปลงสุดท้ายเท่านั้นที่จะถูกดึงออกมาและทำให้ผู้ใช้มองเห็นได้!

2) โปรดทราบว่าโปรแกรม Android จะ - โดยเริ่มต้น - ทำงานในหนึ่งกระทู้เท่านั้น! ดังนั้น: ห้ามใช้Thread.sleep()หรือThread.wait()ในเธรดหลักของคุณซึ่งรับผิดชอบ UI ของคุณ! (อ่าน"ให้แอปของคุณตอบสนองต่อ"สำหรับข้อมูลเพิ่มเติม!)

การเริ่มต้นกิจกรรมของคุณคืออะไร:

  • คุณสร้างTextViewวัตถุใหม่โดยไม่มีเหตุผลt!
  • คุณเลือกเค้าโครงของคุณTextViewในตัวแปรในtภายหลัง
  • คุณตั้งค่าข้อความของt(แต่โปรดจำไว้ว่ามันจะปรากฏขึ้นหลังจาก onCreate()เสร็จสิ้นและลูปเหตุการณ์หลักของแอปพลิเคชันของคุณจะทำงาน!)
  • คุณรอ10 วินาทีภายในonCreateวิธีการของคุณ- สิ่งนี้จะต้องไม่เกิดขึ้นเนื่องจากหยุดกิจกรรม UI ทั้งหมดและจะบังคับ ANR อย่างแน่นอน (แอปพลิเคชันไม่ตอบสนองดูลิงก์ด้านบน!)
  • จากนั้นคุณตั้งค่าข้อความอื่น - ข้อความนี้จะแสดงทันทีที่onCreate()วิธีการของคุณเสร็จสิ้นและวิธีการอื่น ๆ ของวงจรชีวิตของกิจกรรมได้รับการประมวลผล!

การแก้ไขปัญหา:

  1. ตั้งค่าข้อความเพียงครั้งเดียวonCreate()- ต้องเป็นข้อความแรกที่ควรมองเห็นได้

  2. สร้างRunnableและ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. ติดตั้ง runnable นี้เป็นตัวจัดการที่เป็นไปได้ใน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

ฉันพบว่าเมื่อใช้ตัวแปร String ฉันจำเป็นต้องนำหน้าด้วยสตริงของ "" หรือส่งไปยัง 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

ตามคำแนะนำของคุณฉันใช้ที่จับและ runnables เพื่อสลับ / เปลี่ยนเนื้อหาของ TextView โดยใช้ "ตัวจับเวลา" ด้วยเหตุผลบางประการเมื่อทำงานแอปจะข้ามขั้นตอนที่สองเสมอ ("ขั้นตอนที่สอง: ทอดไข่") และแสดงเฉพาะขั้นตอน (ที่สาม) สุดท้าย ("ขั้นตอนที่สาม: เสิร์ฟไข่")

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
ไม่สามารถทำงานได้! มีตัวจัดการเพียงตัวเดียว - คุณต้องการให้นักวิ่ง mWaitRunnable ที่มีอยู่เพียงคนเดียวของคุณ "รู้" ได้อย่างไรว่า sText เคยตั้งค่าเป็น "ขั้นตอนที่สอง" จากนั้นเป็น "ขั้นตอนที่สาม" ได้อย่างไร !! ?? เมื่อเรียกครั้งแรก (หลังจาก 3 วินาที) - ค่าของ sText ก็คือ "ขั้นตอนที่สาม"! คุณควรทำความคุ้นเคยกับทักษะ Java ขั้นพื้นฐานก่อนที่จะลองเขียนโปรแกรม Android! :-)
Zordid

ในที่สุดสิ่งที่ฉันทำคือเพิ่มตัวนับภายใน runnable ถ้าเป็น 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 สองครั้งเป็นการเขียนทับข้อความแรกที่เขียน ครั้งที่สองเมื่อเราใช้ settext เราก็ต่อท้ายสตริงใหม่เช่น

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

0

@Zordid @Iambda คำตอบดีมาก แต่ฉันพบว่าถ้าฉันใส่

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000);

ในวิธีการรัน () และ

mHandler.postDelayed(mUpdateUITimerTask, 0);

ในเมธอด onCreate ทำให้สิ่งนี้อัปเดตอยู่เสมอ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.