更新
我的小陈列柜存放在Bitbucket上
https://bitbucket.org/solvapps/animationtest
我有一个带有 View 的 Activity 。 Contentview
设置为此 View 。
public class MainActivity extends AppCompatActivity {
private MyView myView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myView = new MyView(this);
setContentView(myView);
startMovie();
}
public void startMovie(){
MovieTask movieTask = new MovieTask(myView, this);
movieTask.doInBackground(null);
}
}
MovieTask是Asynctask,它会定期刷新 View 。
但是invalidate()不会刷新 View 。
public class MovieTask extends AsyncTask<String, String, String> {
MyView drawingView;
MainActivity mainActivity;
public MovieTask(MyView view, MainActivity mainActivity){
this.mainActivity = mainActivity;
this.drawingView =view;
}
@Override
protected String doInBackground(String... strings) {
for(int i=20;i<100;i++){
drawingView.myBall.goTo(i,i);
publishProgress();
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
mainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
Log.v("DEBUG_DRAW","in onProgressUpdate()");
drawingView.invalidate();
}
});
}
}
有人可以帮忙吗?
最佳答案
查看如何启动AsyncTask
: public void startMovie() { MovieTask movieTask = new MovieTask(myView, this); movieTask.doInBackground(null); }
您正在某个名为MovieTask
的类中手动调用方法,因此您正在同一线程上运行代码。显然,这并非您的 Intent ,您打算在后台线程上运行计算代码。
启动AsyncTask
的正确方法是使用 execute(Params...)
: public void startMovie() { MovieTask movieTask = new MovieTask(myView, this); movieTask.execute(""); }
现在您将获得理想的效果。
P.S.
请不要使用该代码:您无需启动后台线程即可执行此类操作。作为替代,考虑Animators API。
在setBall(int pos)
类中声明MyBall
方法: public class MyView extends View { ... public void setBall(int pos) { myBall.setX(pos); myBall.setY(pos); invalidate(); } }
然后将startMovie()
更改为以下内容: public void startMovie() { // "ball" means, that Animators API will search for `public setBall(int)` method inside MyView.java and call that method ObjectAnimator ball = ObjectAnimator.ofInt(myView, "ball", 20, 100); ball.setDuration(1000); ball.start(); }
您将获得没有讨厌代码的相同动画。