Foreground Surfaceview In Android

In previous posts, we have created a custom SurfaceView with background thread. Now we are going to create another ForegroundSurface class by extending our GameSurface, with overriding code.

Algorithm:

1.) Create a new project by File-> New -> Android Project name it ForegroundSurfaceView.

2.) Write following into 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" >

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello" />
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.example.foregroundsurfaceview.GameSurface
android:id="@+id/myview1"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<com.example.foregroundsurfaceview.ForegroundSurface
android:id="@+id/myforeground"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</FrameLayout>
</LinearLayout>

 

 

3.) Create and write following into GameThread.java:

 

package com.example.foregroundsurfaceview;

public class GameThread extends Thread {

volatile boolean running = false;

GameSurface parent;
long sleepTime;

GameThread(GameSurface sv, long st){
super();
parent = sv;
sleepTime = st;
}

public void setRunning(boolean r){
running = r;
}

@Override
public void run() {
// TODO Auto-generated method stub
while(running){

try {
sleep(sleepTime);
parent.updateSurfaceView();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
}

 

 

4.) Create and write following into GameSurface.java:

 

package com.example.foregroundsurfaceview;

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameSurface extends SurfaceView implements SurfaceHolder.Callback{

SurfaceHolder surfaceHolder;

GameThread myGameThread = null;

int myCanvas_w, myCanvas_h;
Bitmap myCanvasBitmap = null;
Canvas myCanvas = null;
Matrix identityMatrix;

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Random random;

public GameSurface(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

public GameSurface(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public GameSurface(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {

myCanvas_w = getWidth();
myCanvas_h = getHeight();
myCanvasBitmap = Bitmap.createBitmap(myCanvas_w, myCanvas_h, Bitmap.Config.ARGB_8888);
myCanvas = new Canvas();
myCanvas.setBitmap(myCanvasBitmap);

identityMatrix = new Matrix();
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub

}

public void MyGameSurfaceView_OnResume(){

random = new Random();
surfaceHolder = getHolder();
getHolder().addCallback(this);

//Create and start background Thread
myGameThread = new GameThread(this, 200);
myGameThread.setRunning(true);
myGameThread.start();

}

public void MyGameSurfaceView_OnPause(){
//Kill the background Thread
boolean retry = true;
myGameThread.setRunning(false);

while(retry){
try {
myGameThread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

@Override
protected void onDraw(Canvas canvas) {

paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);

//int w = myCanvas.getWidth();
//int h = myCanvas.getHeight();
int x = random.nextInt(myCanvas_w-1);
int y = random.nextInt(myCanvas_h-1);
int r = random.nextInt(255);
int g = random.nextInt(255);
int b = random.nextInt(255);

paint.setColor(0xff000000 + (r << 16) + (g << 8) + b);
myCanvas.drawPoint(x, y, paint);

canvas.drawBitmap(myCanvasBitmap, identityMatrix, null);

}

public void updateStates(){
//Dummy method() to handle the States
}

public void updateSurfaceView(){
//The function run in background thread, not ui thread.

Canvas canvas = null;

try{
canvas = surfaceHolder.lockCanvas();

synchronized (surfaceHolder) {
updateStates();
onDraw(canvas);
}
}finally{
if(canvas != null){
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}

 

 

5.) Create and write following into ForegroundSurface.java:

 

package com.example.foregroundsurfaceview;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;

public class ForegroundSurface extends GameSurface {

public ForegroundSurface(Context context) {
super(context);
// TODO Auto-generated constructor stub
}

public ForegroundSurface(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

public ForegroundSurface(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}

@Override
protected void onDraw(Canvas canvas) {
Bitmap me = BitmapFactory.decodeResource(getResources(), R.drawable.myicon);
int loc_x = canvas.getWidth()/2;
int loc_y = canvas.getHeight()/2;
canvas.drawBitmap(me, loc_x, loc_y, null);
}
}

 

 

6.) Write following permissions to your manifest

 

<activity android:name=".GameSurface" ></activity>
<activity android:name=".GameThread" ></activity>
<activity android:name=".ForegroundSurface" ></activity>

 

 

7.) Run for output.

Steps:

1.) Create a project named ForegroundSurfaceView and set the information as stated in the image.

Build Target: Android 4.4
Application Name: ForegroundSurfaceView
Package Name: com.example.ForegroundSurfaceView
Activity Name: ForegroundSurfaceViewActivity

foreground1

2.) Open ForegroundSurfaceViewActivity.java file and write following code there:

 

package com.example.foregroundsurfaceview;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.os.Bundle;

public class ForegroundSurfaceViewActivity extends Activity {

GameSurface myGameSurfaceView1;
ForegroundSurface myForeground;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myGameSurfaceView1 = (GameSurface)findViewById(R.id.myview1);
myForeground = (ForegroundSurface)findViewById(R.id.myforeground);

//Set myForeground using transparent background
myForeground.setZOrderOnTop(true);
myForeground.getHolder().setFormat(PixelFormat.TRANSPARENT);

}

@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
myGameSurfaceView1.MyGameSurfaceView_OnResume();
myForeground.MyGameSurfaceView_OnResume();

}

@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
myGameSurfaceView1.MyGameSurfaceView_OnPause();
myForeground.MyGameSurfaceView_OnPause();
}
}

 

 

3.) Compile and build the project.

Output

foreground2