Reputation: 385
i've got a big problem since a few days: When I try to bind the surfaceview on the layout and my custom surfaceview, i get a ClassCastException from my custom surfaceview.
here is my code:
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);
}
}
}
}
}
When I replace:
setContentView(R.layout.main);
with this:
setContentView(new WaveFormView (this));
...it works perfectly ! But, I need to have buttons besides.
here is the layout:
<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>
If someone have the solution it would me a lot !
Upvotes: 1
Views: 1966
Reputation: 137332
Maybe R.id.surfaceView1
is not declared as WaveFormView
but as SurfaceView
? Try declare it specifically, otherwise this is illegal casting indeed.
WaveFormView
is a SurfaceView
, but a SurfaceView
is not necessarily a WaveFormView
.
You can use your own view in the layout xml, by specifying the class name (<path.to.WaveFormView
instead of <SurfaceView...
)
For example:
<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"
/>
If this class is an inner class, as seemed from your question, then use:
<com.mypath.OUTERCLASSNAME$WaveFormView
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.:
public static class WaveFormView extends SurfaceView implements SurfaceHolder.Callback
Upvotes: 7