我想在单击按钮时启动一个Thread。该线程每秒都会向下移动一个视图,但它不起作用。这是代码:
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()
方法是单击Button时触发的方法。
它不起作用。我看到了这个问题:Android "Only the original thread that created a view hierarchy can touch its views."
但它无法帮助我。你能告诉我问题出在哪里吗?
答案 0 :(得分: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来更新视图)。 这实际上是一种非常脏的方法,也许Handler可以更好地解决您的问题。
问候!
答案 1 :(得分: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
是公开的,因此可以轻松调整以在“视图”之外完成,因此您无需进行自定义View