2010-02-19 23 views
88

Traté de hacer estocómo cambiar texto en 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"); 

pero por alguna razón, sólo el segundo texto aparece cuando lo ejecuto. Creo que podría tener algo que ver con el bloqueo del método Thread.sleep(). Entonces, ¿alguien me puede mostrar cómo implementar un temporizador "asincrónicamente"?

Gracias.

+2

La razón por la que solo muestra la segunda línea es porque '.setText()' reemplaza todo el "widget" con el texto que le indica que establezca; INCLUYE texto que ya has puesto ahí. – georgiaboy82

Respuesta

43

Me acaba de publicar esta respuesta en el grupo de Google Android-discutir

Si usted está tratando de añadir texto a la vista para que se muestra "Paso uno: explosión de huevo Segundo paso: freír huevos" a continuación, considere el uso de t.appendText("Step Two: fry egg"); en lugar de t.setText("Step Two: fry egg");

Si desea cambiar por completo lo que está en el TextView para que diga "Primer paso: explosión de huevo" en la puesta en marcha y luego dice "Paso dos: freír e gg" en un momento posterior se puede utilizar siempre una

ejemplo Ejecutable Sadboy dio

Buena suerte

14

La primera línea de la nueva vista de texto es innecesaria

t=new TextView(this); 

que sólo puede hacer esto

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

por lo que un subproceso de fondo que duerme aquí es un ejemplo, pero creo que hay un temporizador que sería mejor para esto. aquí hay un enlace a un buen ejemplo usando un temporizador en lugar 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

por su consejo, estoy utilizando el asa y runnables para cambiar/cambiar el contenido de la Vista de Texto utilizando una "minutero". por alguna razón, cuando se ejecuta, la aplicación omite siempre el segundo paso ("Paso dos: huevo frito"), y solo muestra el último (tercer) paso ("Paso tres: sirve huevo").

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

¡Esto no puede funcionar! Solo hay UN manejador: ¿cómo quieres que tu único corredor mWaitRunnable existente "sepa" que sText se configuró en "Paso dos" y luego en "Paso tres"? En el momento en que se llama la primera vez (después de 3 segundos), el valor de sText simplemente es "Paso tres". ¡Debes familiarizarte con las habilidades básicas de Java antes de probar la programación de Android! :-) – Zordid

+0

en realidad lo que finalmente hice fue agregar un contador dentro del ejecutable, si es 1, el texto será este, si es 2, el texto será este, etc. – user270811

145

Su método onCreate() tiene varios defectos enormes:

1) onCreateprepara su actividad - así que nada que haga aquí se harán visibles al usuario hasta que este método acabados! Por ejemplo, nunca podrá modificar el texto de TextView más de ONE vez, ya que solo se dibujará el último cambio y, por lo tanto, será visible para el usuario.

2) Tenga en cuenta que un programa de Android ejecutará, de forma predeterminada, en ONE ¡Sólo subproceso! Por lo tanto: nunca use Thread.sleep() o Thread.wait() en su hilo principal que es responsable de su UI. (lea "Keep your App Responsive" para más información!)

Lo que su inicialización de su actividad no es:

  • por ninguna razón se crea un nuevo objeto TextViewt!
  • escoge el diseño TextView en la variable t posterior.
  • se establece el texto de t (pero tenga en cuenta: que sólo se mostrará despuésonCreate() acabados y el bucle principal evento de tus ejecuta la aplicación!)
  • espera 10 segundos dentro de su método de onCreate - este nunca se debe hacer ya que se detiene toda la actividad de la interfaz de usuario y sin duda forzar una ANR
  • continuación, establece otro texto (aplicación no responde, ver enlace arriba!) - éste se mostrará tan pronto como su método de onCreate() acabados y varios otros métodos Activity lifecycle han sido ¡procesado!

La solución:

  1. Conjunto de texto sólo una vez en onCreate() - esto debe ser el primer texto que debe ser visible.

  2. Crear una Runnable y una 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. instale este ejecutable como un manipulador, posible en onCreate() (pero leer mi consejo a continuación):

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

consejo: ¡seguro que conoce el ciclo de vida de Activity! Si hace cosas así en onCreate(), esto solo ocurrirá cuando se cree Activity, el primer tiempo! Android posiblemente mantendrá su Activity con vida durante un período de tiempo más largo, ¡incluso si no está visible! Cuando un usuario "comienza" de nuevo, y todavía existe, ¡ya no verá su primer texto!


=> Siempre instale los controladores en onResume() y desactivarlos en onPause()! De lo contrario, recibirá "actualizaciones" cuando su Activity no esté visible en absoluto. En su caso, si desea volver a ver su primer texto cuando se lo vuelve a activar, debe configurarlo en onResume(), no en onCreate().

6

@ user264892

he encontrado que cuando se utiliza una variable String necesitaba ya sea prefijo con una cadena de "" o convertir explícitamente a CharSequence.

Así que en lugar de:

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

intento:

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

o:

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

o, ya que la cadena no es dinámica, aún mejor:

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

:) Estás usando el hilo de una manera incorrecta. Sólo haga lo siguiente:

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

Eso es todo.

0

configurar el texto en sam textview dos veces está sobrescribiendo el primer texto escrito. Así la segunda vez cuando usamos setText acabamos Añadir la nueva cadena como

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

@Zordid @Iambda respuesta es grande, pero he encontrado que si pongo

mHandler.postDelayed(mUpdateUITimerTask, 10 * 1000); 

en el run() método y

mHandler.postDelayed(mUpdateUITimerTask, 0); 

en el método onCreate hacen que la cosa siga actualizándose.