这是我在stackoverflow上的第一篇文章。作为android编程的初学者,我在使用带有内部线程类的SurfaceView时遇到了一些问题。我的目标是使用以下布局中的一些参数(通过EditText输入)实现简单摆的运动可视化:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
... >
<com.vitorlara.pendulosimples2.TestView
android:layout_gravity="left"
android:layout_width="0dp"
android:layout_weight="8"
android:layout_height="match_parent"
android:background="@android:color/white"
android:id="@+id/pendulumView">
</com.vitorlara.pendulosimples2.TestView>
<LinearLayout
... >
<Button
... >
</Button>
<Button
... >
</Button>
<EditText
... >
</EditText>
<EditText
... >
</EditText>
<EditText
...>
</EditText>
</LinearLayout>
当主布局中只有SurfaceView时,我可以在一个简单的版本中执行此操作。然而,当我试图在上面描绘的布局中做同样的事情时,没有任何事情发生,无论我尝试过什么。 MainTest和TestView类最重要的部分如下:
public class TestMain extends Activity{
public boolean isPlaying = false;
public boolean isErased = true;
public TestView testView;
public Button playButton;
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playButton = (Button) findViewById(R.id.playButton);
isErased = true;
testView = (TestView) findViewById(R.id.pendulumView);
}
// Play Button Listener
public void onPlayButtonClicked(View v){
...
if(isErased == true){
testView.startPendulum();
isPlaying = true;
isErased = false;
}
else{
if(isPlaying){
testView.pendulumThread.threadIsRunning = false;
isPlaying = false;
}
else{
testView.pendulumThread.start();
isPlaying = true;
}
}
}
// Reset Button Listener
public void onResetButtonClicked(View v){
testView.pendulumThread.threadIsRunning = false;
isPlaying = false;
isErased = true;
}
和TestView类:
public class TestView extends SurfaceView implements SurfaceHolder.Callback{
public PendulumThread pendulumThread;
...
private Paint ballPaint;
private Paint linePaint;
private Paint backgroundPaint;
// PendulumView's Constructor
public TestView(Context context, AttributeSet attrs){
super(context, attrs);
// listener from SurfaceHolder.Callback
getHolder().addCallback(this);
ballPaint = new Paint();
linePaint = new Paint();
backgroundPaint = new Paint();
}
public void pauseAnim(){
pendulumThread.setRunning(false);
}
public void startPendulum(){
...
pendulumThread = new PendulumThread(getHolder());
pendulumThread.start();
}
// Drawing the elements
public void drawPendulum(Canvas canvas, double elapsedTime){
// Cleaning the background
if(canvas!=null){
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), backgroundPaint);
oldOmega = omega;
omega = (float) (oldOmega + (gravity / length) * Math.sin(angle) * elapsedTime);
oldAngle = angle;
angle = (float) (oldAngle + omega * elapsedTime);
Ax = (float) (Ox - length * Math.sin(angle));
Ay = (float) (Oy - length * Math.cos(angle));
// Drawing the ball
canvas.drawCircle(Ax, Ay, ballRadius, ballPaint);
// Drawing pendulum line
canvas.drawLine(Ox, Oy, Ax, Ay, linePaint);
}
} // End of method drawPendulum
// called when surface is first created
@Override
public void surfaceCreated(SurfaceHolder holder){
pendulumThread = new PendulumThread(holder);
pendulumThread.setRunning(true);
pendulumThread.start(); // start the game loop thread
} // end method surfaceCreated
// called when the surface is destroyed
@Override
public void surfaceDestroyed(SurfaceHolder holder){
// ensure that thread terminates properly
boolean retry = true;
pendulumThread.setRunning(false);
while (retry){
try{
pendulumThread.join();
retry = false;
} // end try
catch (InterruptedException e){
} // end catch
} // end while
} // end method surfaceDestroyed
// Thread subclass to control the game loop
class PendulumThread extends Thread{
private SurfaceHolder surfaceHolder; // for manipulating canvas
public boolean threadIsRunning = true; // running by default
// initializes the surface holder
public PendulumThread(SurfaceHolder holder){
this.surfaceHolder = holder;
} // end constructor
// changes running state
public void setRunning(boolean running){
this.threadIsRunning = running;
} // end method setRunning
// controls the game loop
@Override
public void run()
{
Canvas canvas = null; // used for drawing
long previousFrameTime = System.currentTimeMillis();
while (this.threadIsRunning)
{
try
{
canvas = this.surfaceHolder.lockCanvas(null);
// lock the surfaceHolder for drawing
synchronized(this.surfaceHolder)
{
long currentTime = System.currentTimeMillis();
double elapsedTimeMS = currentTime - previousFrameTime;
drawPendulum(canvas, elapsedTimeMS/1000.00); // draw
previousFrameTime = currentTime; // update previous time
} // end synchronized block
} // end try
finally
{
if (canvas != null)
surfaceHolder.unlockCanvasAndPost(canvas);
} // end finally
} // end while
} // end method run
} // end nested class CannonThread
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height)
{
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
backgroundPaint.setColor(android.graphics.Color.WHITE); // set background color
startPendulum();
} // end method onSizeChanged
}
LogCat表示该线程已启动,但没有任何反应。有什么帮助吗?