自定义 SurfaceView 上的 ClassCastException
几天来我遇到了一个大问题: 当我尝试在布局和自定义 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>
如果有人有解决方案,我会很高兴!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也许
R.id.surfaceView1
没有声明为WaveFormView
而是声明为SurfaceView
?尝试明确声明它,否则这确实是非法铸造。WaveFormView
是一个SurfaceView
,但SurfaceView
不一定是WaveFormView
。您可以通过指定类名称( 而不是 )在布局 xml 中使用自己的视图,
例如:
或者
如果这个类是一个内部类,正如您的问题所示,则使用:
编辑
由于需要从类外部显示该类,并且不是从实例加载而是静态加载,所以您需要
public static< /code> 到其声明,例如:
Maybe
R.id.surfaceView1
is not declared asWaveFormView
but asSurfaceView
? Try declare it specifically, otherwise this is illegal casting indeed.WaveFormView
is aSurfaceView
, but aSurfaceView
is not necessarily aWaveFormView
.You can use your own view in the layout xml, by specifying the class name (
<path.to.WaveFormView
instead of<SurfaceView...
)For example:
OR
If this class is an inner class, as seemed from your question, then use:
EDIT
Since this class is needed to be shown from outside your class, and be loaded not from instance but statically, you need to
public static
to its declaration, e.g.: