2014-03-06 61 views
0

我想單擊按鈕時啓動線程。該線程每秒鐘都會移動一個View,但它不起作用。下面的代碼:使視圖移動線程

public class MainActivity extends Activity { 

private boolean juegoEmpezado = false; 
private int clicks = 0; 
private int margenTop = 20; 
private int crecimientoMargen = 10; 
private int velocidadDeCrecimiento = 1000; 
private LayoutParams parametrosLayout; 
private TextView item; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    item = (TextView)findViewById(R.id.textView1); 
    item.setText("asasas"); 
    parametrosLayout = (LayoutParams) item.getLayoutParams(); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 
} 

public void empezarJuego(View v) { 

    juegoEmpezado = true; 
    empezar(); 
} 

public void empezar() { 
    runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      while(juegoEmpezado) { 
       try { 
        Thread.sleep(velocidadDeCrecimiento); 
        parametrosLayout.topMargin = margenTop; 
        margenTop += crecimientoMargen; 
        item.setLayoutParams(parametrosLayout); 

       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
     } 
    } 
}); 
} 
} 

empezar()方法是,當我點擊按鈕觸發該方法。

它不起作用。我看到這個問題:Android "Only the original thread that created a view hierarchy can touch its views."

但它不能幫助我。你能告訴我問題在哪裏嗎?

回答

2

的問題是你在這裏停止主線程:

while(juegoEmpezado) { 
    try { 
     Thread.sleep(velocidadDeCrecimiento); 

由於此調用你實際上是停止它在主線程上運行,並且它不會刷新您的任何意見,你可以什麼做是這樣的:

new Thread(new Runnable() { 
      @Override 
      public void run() { 
       while(true){ 
        empezar(); 
        try{Thread.sleep(1000);}catch(InterruptedException ie){ie.toString();} 
       } 
      } 
     }).start(); 

它會調用empezar(它必須使用runOnUIThread來更新視圖)。 這實際上是一個非常骯髒的方式來做到這一點,也許一個處理程序將是一個更好的方法來解決您的問題。

商祺!

+0

它的工作原理,謝謝! –

1

只能在主線程上修改UI元素。沒有必要爲此創建一個新線程。相反,你會做的是創建一個內部類,擴展Runnable並做你的調整。然後使用View#postDelayed()方法每運行x毫秒。

public class CustomView extends View { 

    private AnimRunnable animRunnable = new AnimRunnable(); 

    @Override 
    protected void onAttachedToWindow() { 
     animRunnable.start(); 
    } 

    @Override 
    protected void onDetachedFromWindow() { 
     animRunnable.stop(); 
    } 

    private class AnimRunnable implements Runnable { 
     @Override 
     public void run() { 
      // Animation code 
     } 

     public void start() { 
      postDelayed(this, 1000); 
     } 

     public void stop() { 
      removeCallbacks(this); 
     } 
    } 
} 

編輯:

我只注意到你不是做一個自定義視圖。 View#postDelayed()removeCallbacks()方法是View的公開方法,因此可以很容易地將其調整爲在視圖外部完成,因此您不必定製0​​。