I want to apply repeating pattern to my layout background, but when i start application, background is black.
I have implemented custom view from SurfaceView:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/playGroundLayout"
android:layout_height="match_parent">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/backrepeat"
android:scaleType="centerCrop">
</ImageView>
</RelativeLayout>
background tile:
<?xml version="1.0" encoding="utf-8"?>
<bitmap
xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/tile"
android:tileMode="repeat"
android:dither="true" />
surface creation:
public class PlayGroundActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_play_ground);
RelativeLayout surface = (RelativeLayout)findViewById(R.id.playGroundLayout);
surface.addView(new PlayGroundSurface(this));
}
}
surfaceView implementation:
public class PlayGroundSurface extends SurfaceView implements SurfaceHolder.Callback
{
private MainThread thread;
public PlayGroundSurface(Context context)
{
super(context);
getHolder().addCallback(this);
setFocusable(true);
setWillNotDraw(false);
}
private Bitmap scaled;
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread = new MainThread(getHolder(),this);
thread.setRunning(true);
thread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
while (retry)
{
try {
thread.join();
retry = false;
}catch (InterruptedException ex){}
}
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
return true;
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
}
public void render(Canvas canvas) {
}
}
mainThread class:
public class MainThread extends Thread
{
private final static int MAX_FPS = 50;
private final static int MAX_FRAME_SKIPS = 5;
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
private SurfaceHolder holder;
private PlayGroundSurface surface;
private boolean running = false;
public MainThread(SurfaceHolder surfaceHolder, PlayGroundSurface playGroundSurface) {
surface = playGroundSurface;
holder = surfaceHolder;
}
public void setRunning(boolean run)
{
running = run;
}
#Override
public void run()
{
Canvas canvas;
long beginTime;
long timeDiff;
int sleepTime;
int framesSkipped;
sleepTime = 0;
while(running)
{
canvas = null;
try
{
canvas = holder.lockCanvas();
synchronized (holder)
{
beginTime = System.currentTimeMillis();
framesSkipped = 0;
surface.draw(canvas);
surface.render(canvas);
timeDiff = System.currentTimeMillis() - beginTime;
sleepTime = (int)(FRAME_PERIOD - timeDiff);
if(sleepTime > 0)
{
try {
Thread.sleep(sleepTime);
}catch (InterruptedException e){ }
}
while(sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS)
{
surface.updateAllItems();
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
}
}
finally
{
if(canvas != null)
{
holder.unlockCanvasAndPost(canvas);
}
}
}
}
}
when i change layout root element from RelativeLayout to LinearLayout, it shows horizontal stripe of background. Seems like my RelativeLayout has zero dimensions.
What i am doing wrong?
I think you should try to remove the ImageView and set the background to the RelativeLayout directly
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:id="#+id/playGroundLayout"
android:layout_height="match_parent"
android:background="#drawable/backrepeat">
</RelativeLayout>
Related
I am running into an issue in my app. When my game ends (when life == 0) I am attempting to switch to a game over screen by using a different activity. When the game ends, the app simply crashes. I have included the XML for the activity I am trying to switch from as well as indicating where the app crashes. If anyone could help out, that would be great! Thanks.
activity_game.XML:
SurfaceView I am trying to switch from once game ends:
public class SVGameView extends SurfaceView implements Runnable {
private SurfaceHolder holder;
Thread thread = null;
volatile boolean running = false;
static final long FPS = 30;
private Sprite sprite;
private long lastClick;
private Bitmap ball, gameOver;
//private int x = 200, y = 200;
private int scorePosX = 100;
private int scorePosY = 100;
private int countScore = 0;
private int life = 1;
public SVGameView(Context context) {
super(context);
thread = new Thread(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
running = false;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
running = true;
thread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
ball = BitmapFactory.decodeResource(getResources(), R.drawable.ball2);
gameOver = BitmapFactory.decodeResource(getResources(),R.drawable.endscreen);
sprite = new Sprite(this, ball);
}
#Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while (running) {
Canvas c = null;
startTime = System.currentTimeMillis();
try {
c = getHolder().lockCanvas();
synchronized (getHolder()) {
update();
draw(c);
}
} finally {
if (c != null) {
getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
try {
if (sleepTime > 0)
thread.sleep(sleepTime);
else
thread.sleep(10);
} catch (Exception e) {}
}
}
private void update(){
sprite.update();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
Paint paint = new Paint();
canvas.drawPaint(paint);
paint.setColor(Color.WHITE);
paint.setTextSize(48);
canvas.drawText("Score: " + countScore, scorePosX, scorePosY, paint);
canvas.drawText("Lives: " + life, 500, 100, paint);
sprite.onDraw(canvas);
//Crashes here
if(life == 0) {
getContext().startActivity(new Intent(getContext(), SVGameOver.class));
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(System.currentTimeMillis()-lastClick > 300){
lastClick = System.currentTimeMillis();
}
synchronized (getHolder()){
if(sprite.isHit(event.getX(), event.getY())){
countScore += 1;
sprite.increase();
}else{
life --;
}
}
return super.onTouchEvent(event);
}
}
Activity I am trying to reach once the game ends:
public class SVGameOver extends Activity {
private Bitmap gameOverScreen;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
gameOverScreen = BitmapFactory.decodeResource(getResources(), R.drawable.endscreen);
}
protected void onDraw(Canvas canvas){
canvas.drawBitmap(gameOverScreen, 0,0,null);
}
}
I think logcat is asking you the right question: "have you declared this activity in your AndroidManifest.xml" ?
If you think you did it, It's highly probable you did it in a wrong way, most of the times that you think you added an Activity to the manifest but you are receiving this kind of crash, 99,9% of the time you declared it with a wrong namespace
Declare SVGameOver activity in your AndroidManifest.xml:
<activity
android:name="com.example.welcome.assignment2.SVGameOver">
...
</activity>
I have custom SurfaceView, setting a background in onDraw method, then drawing canvas, but see only background. How can I draw with canvas on a background?
Tried to add a background with canvas, it works, but at top left 2-3dp was deleted, and redrawing every time background will eat a lot of memory.
So can it be done with 1st method or 2nd without empty spaces on top left?
Edit...
GameView.java
public class GameView extends SurfaceView {
private Bitmap background;
private SurfaceHolder holder;
private GameManager gameLoopThread;
public GameView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
setWillNotDraw(false);
gameLoopThread = new GameManager(this);
holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameLoopThread.setRunning(false);
while (retry) {
try {
gameLoopThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
background = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
}
public void onDraw(Canvas canvas) {
canvas.drawBitmap(background, 0, 0, null);
}
public void drawCanvas(Canvas canvas) {
if (x < getWidth() - 10) {
x += 10;
} else {
gameLoopThread.setRunning(false);
}
canvas.drawLine(0, 200, x, 200, paint);
}
}
GameManager.java
public class GameManager extends Thread {
private GameView view;
private boolean running = false;
public GameManager(GameView view) {
this.view = view;
}
public void setRunning(boolean run) {
running = run;
}
#Override
public void run() {
while (running) {
Canvas c = null;
try {
c = view.getHolder().lockCanvas();
synchronized (view.getHolder()) {
view.drawCanvas(c);
}
} finally {
if (c != null) {
view.getHolder().unlockCanvasAndPost(c);
}
}
}
}
}
MainActivity.java
public class MainActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout ll = (LinearLayout) findViewById(R.id.main);
ll.setLayoutParams(new LinearLayout.LayoutParams(640, 400));
}
}
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:gravity="center_horizontal|top">
<LinearLayout
android:id="#+id/main"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<com.android.GameView
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
The result is http://oi57.tinypic.com/15znrpy.jpg
If I comment GameView onDraw method and add canvas.drawBitmap(background, 0, 0, null); to drawCanvas the result will be
http://oi60.tinypic.com/t0g802.jpg
There's not really a specific way to set a SurfaceView's background.
If you set a background in onDraw then draw to the canvas somewhere outside of onDraw, it's going to call onDraw and draw the background over whatever was just drawn.
Redrawing the background every time will not eat a significant amount of memory, assuming you're not trying to do it on the UI thread.
Also, I'm not quite sure what you mean by "at top left 2-3dp was deleted" and "empty spaces on top left". Can you post an image of this, along with the code you've tried?
I'm working on a Android game using SurfaceView, the game works fine, so I want to pause it when the user hits HOME key but when getting back the SurfaceView disappears(black background Edit: sometimes the drawing appears) and buttons are inactive in both cases then I get ANR.
public class MainActivity extends Activity {
private Game game;
MainPanel mp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
game = new Game();
LoadLevel();
Init();
setContentView(R.layout.main);//contains surfaceview and buttons
mp = (MainPanel) findViewById(R.id.SurfaceView01);
mp.Init(game,this);
Button btnTop = (Button) findViewById(R.id.buttonTop);
Button btnBottom = (Button) findViewById(R.id.buttonBottom);
Button btnLeft = (Button) findViewById(R.id.buttonLeft);
Button btnRight = (Button) findViewById(R.id.buttonRight);
btnTop.setOnClickListener...
}
private void Init() {
...
}
public void LoadLevel() {
...
}
#Override
protected void onResume() {
super.onResume();
Log.d("Tag","Resume");
}
#Override
protected void onPause() {
super.onPause();
Log.d("Tag","Pause");
}
}
public class MainPanel extends SurfaceView implements SurfaceHolder.Callback {
private MainThread thread;
private Game game;
private MainActivity act;
public MainPanel(Context context, AttributeSet attrs) {
super(context,attrs);
getHolder().addCallback(this);
}
public MainThread getThread() {
return thread;
}
public void Init(Game game, MainActivity act){
this.game = game;
this.act = act;
}
public void Move(int dir) {
...
}
public void update() {
...
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (thread == null) {
thread = new MainThread(getHolder(), this);
thread.Start();
thread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.Stop();
boolean retry = true;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {}
}
thread = null;
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
//drawing...
}
}
public class MainThread extends Thread {
private final static int MAX_FPS = 30;
private final static int MAX_FRAME_SKIPS = 3;
private final static int FRAME_PERIOD = 1000 / MAX_FPS;
private SurfaceHolder surfaceHolder;
private MainPanel gamePanel;
private boolean run = false;
private boolean start = false;
public MainThread(SurfaceHolder surfaceHolder, MainPanel gamePanel) {
super();
this.surfaceHolder = surfaceHolder;
this.gamePanel = gamePanel;
}
public void Start() {
this.run = true;
this.start = true;
}
public void Pause() {
this.start = false;
}
public void Resume() {
this.start = true;
}
public void Stop() {
this.run = false;
}
#Override
public void run() {
Canvas c = null;
long beginTime; // the time when the cycle begun
long timeDiff; // the time it took for the cycle to execute
int sleepTime; // ms to sleep (<0 if we're behind)
int framesSkipped; // number of frames being skipped
while(run) {
while(start) {
try {
c = surfaceHolder.lockCanvas(null);
synchronized (surfaceHolder) {
beginTime = System.currentTimeMillis();
framesSkipped = 0; // resetting the frames skipped
// update game state
gamePanel.update();
// render state to the screen draws the canvas on the panel
if(c!=null) gamePanel.onDraw(c);
// calculate how long did the cycle take
timeDiff = System.currentTimeMillis() - beginTime;
// calculate sleep time
sleepTime = (int)(FRAME_PERIOD - timeDiff);
if (sleepTime > 0) {
// if sleepTime > 0 we're OK
try {
// send the thread to sleep for a short period very useful for battery saving
Thread.sleep(sleepTime);
} catch (InterruptedException e) {}
}
while (sleepTime < 0 && framesSkipped < MAX_FRAME_SKIPS) {
// we need to catch up update without rendering
gamePanel.update();
// add frame period to check if in next frame
sleepTime += FRAME_PERIOD;
framesSkipped++;
}
}
} finally {
if (c != null) surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
Thx to this post why is my runnable giving ANR? I could solve the problem, I isolated the MainThread from the UI thread for further details check the best answer.
I am new to Android and I am trying to add start and reset buttons with a custom surface view. I am able to draw canvas with a circle which is moving with touch.
Now my problem is that when I click the start button, the circle must take its initial position (10,10).
My activity class
public class OpenGlActivity extends Activity implements OnClickListener {
GameView GameView;
FrameLayout Frame;
LinearLayout canvas;
Button btnStart, btnReset;
TutorialThread GameThread;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
GameView = new GameView(this);
btnStart = (Button) findViewById(R.id.btnStart);
btnStart.setOnClickListener(this);
btnReset = (Button) findViewById(R.id.btnReset);
btnReset.setOnClickListener(this);
GameView.setOnTouchListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnStart:
Log.i("openGl", "play called");
GameView.setState();
// drawView.invalidate();
break;
case R.id.btnReset:
// GameView.play=true;
// GameView.reset();
Log.i("openGl", "RESETcalled");
// drawView.invalidate();
break;
}
}
}
Custom surfaceview class and thread class
class GameView extends SurfaceView implements SurfaceHolder.Callback {
String TAG = "GameView";
private TutorialThread _thread;
Paint paint = new Paint();
Paint red = new Paint();
Paint black = new Paint();
int x = 20;
int y = 20;
public GameView(Context context) {
super(context);
// TODO Auto-generated constructor stub
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
// TODO Auto-generated constructor stub
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
red.setColor(Color.RED);
red.setAntiAlias(true);
black.setColor(Color.BLACK);
black.setAntiAlias(true);
setFocusable(true);
}
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
// TODO Auto-generated constructor stub
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
red.setColor(Color.RED);
red.setAntiAlias(true);
black.setColor(Color.BLACK);
black.setAntiAlias(true);
setFocusable(true);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
return true;
}
public void setState() {
Log.i(TAG, "in setState");
_thread.play();
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawCircle(x, y, 10, red);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
_thread.setRunning(true);
_thread.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;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class TutorialThread extends Thread {
String TAG = "TutorialThread";
private SurfaceHolder _surfaceHolder;
private GameView _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, GameView panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.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);
}
}
}
}
public void play() {
synchronized (_surfaceHolder) {
_panel.x = 10;
_panel.y = 10;
Log.i(TAG, "in Play");
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.example.opengl.GameView
android:id="#+id/gameView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:id="#+id/btnStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
<Button
android:id="#+id/btnReset"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Reset" />
</LinearLayout>
</FrameLayout>
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 !
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
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.:
public static class WaveFormView extends SurfaceView implements SurfaceHolder.Callback