几天后我遇到了一个大问题: 当我尝试在布局和我的自定义surfaceview上绑定surfaceview时,我从自定义surfaceview获得了ClassCastException。
这是我的代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
waveform =(WaveFormView) findViewById(R.id.surfaceView1);
}
class WaveFormView extends SurfaceView implements SurfaceHolder.Callback {
public WaveFormView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
_dthread = new DrawingThread(getHolder(), this);
setFocusable(true);
paintP.setStyle(Paint.Style.STROKE);
paintP.setStrokeWidth(1);
paintP.setColor(Color.WHITE);
paintT.setStyle(Paint.Style.STROKE);
paintT.setStrokeWidth(1);
paintT.setColor(Color.WHITE);
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
for (int i=0;i<_athread.buffer.length-pas;i+=pas){
canvas.drawLine(i, 150-_athread.buffer[i], i+pas, 150-_athread.buffer[i+pas], paintP);
}
canvas.drawText("FPS: " + String.valueOf(FPS), 0, 10, paintT);
//canvas.drawText("tmp: " + tmp, 0, 20, paintT);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
_dthread.setRunning(true);
_dthread.start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
_dthread.setRunning(false);
while (retry) {
try {
_dthread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class DrawingThread extends Thread {
private SurfaceHolder _surfaceHolder;
private WaveFormView _waveformview;
private boolean _run = false;
public DrawingThread(SurfaceHolder surfaceHolder, WaveFormView waveformview) {
_surfaceHolder = surfaceHolder;
_waveformview = waveformview;
}
public void setRunning(boolean run) {
_run = run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
@Override
public void run() {
Canvas c;
long startMs=System.currentTimeMillis();
int frameCounter=0;
while (_run) {
c = null;
frameCounter++;
if (System.currentTimeMillis()-startMs>1000){
startMs = System.currentTimeMillis();
FPS = frameCounter;
frameCounter=0;
}
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_waveformview.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
当我替换:
的setContentView(R.layout.main);
用这个:
setContentView(new WaveFormView(this));
......它完美无缺! 但是,我需要有按钮。
这是布局:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
<LinearLayout android:layout_weight="1" android:padding="0dip" android:layout_height="match_parent" android:layout_width="match_parent" android:orientation="vertical" android:id="@+id/content">
<TextView android:layout_height="wrap_content" android:id="@+id/tvdebug" android:text="Debug" android:layout_width="wrap_content"></TextView>
<SurfaceView android:id="@+id/surfaceView1" android:layout_height="fill_parent" android:layout_width="fill_parent"></SurfaceView>
</LinearLayout>
如果有人有解决方案,我会帮助很多!
答案 0 :(得分:7)
可能R.id.surfaceView1
未声明为WaveFormView
,而是SurfaceView
?尝试专门声明它,否则这是非法的投射。
WaveFormView
是SurfaceView
,但SurfaceView
不一定是WaveFormView
。
您可以在布局xml中使用自己的视图,方法是指定类名(<path.to.WaveFormView
而不是<SurfaceView...
)
例如:
<view class = "com.mypath.WaveFormView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/surfaceView1"
android:layout_above="@id/auto_scrollview"
/>
OR
<com.mypath.WaveFormView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/surfaceView1"
android:layout_above="@id/auto_scrollview"
/>
如果这个类是一个内部类,如你的问题所示,那么使用:
<com.mypath.OUTERCLASSNAME$WaveFormView
由于需要从类外部显示此类,并且不是从实例加载而是静态加载,因此需要public static
声明它,例如:
public static class WaveFormView extends SurfaceView implements SurfaceHolder.Callback