Reputation: 569
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
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