android - 自定义 SurfaceView 上的 ClassCastException

标签 android surfaceview classcastexception

几天以来我遇到了一个大问题: 当我尝试将 surfaceview 绑定(bind)到布局和我的自定义 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>

如果有人有解决方案,我会很高兴!

最佳答案

也许 R.id.surfaceView1未声明为 WaveFormView但作为SurfaceView ?尝试明确声明它,否则这确实是非法转换。

WaveFormViewSurfaceView ,而是一个 SurfaceView不一定是 WaveFormView .

您可以在布局 xml 中使用自己的 View ,方法是指定类名( <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"
/>

<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

关于android - 自定义 SurfaceView 上的 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5924031/

相关文章:

android - 如何在图表引擎中的 x 轴标签中设置值

android - 无法更改 TabLayout 中的选项卡

java - Surface View 中的语音识别 [android]

Android - Canvas是如何使用的

尝试迭代列表时抛出 Java ClassCastException

android - 如何在 kotlin android 中共享 .txt 文件

Android SurfaceView 在视频后显示图像(清晰表面)

java - 使用 setContentView 加载布局时应用程序停止工作

java - 简单选择上的 lambdaJ 和 ClassCastException

android - 布局底部和屏幕的其余部分