Droid
Droid

Reputation: 569

Canvas SurfaceView

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

Upvotes: 0

Views: 977

Answers (1)

Zach H
Zach H

Reputation: 257

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?

Upvotes: 1

Related Questions