I am trying an example having SurfaceView. I have inherited my class from SurfaceView and using as follows:
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
Context context;
MySurfaceViewThread mThread;
SurfaceHolder holder;
Paint paint;
int x = 20, y = 20, r = 10;
public void init() {
holder = getHolder();
holder.addCallback(this);
mThread = new MySurfaceViewThread(getHolder(), this);
paint = new Paint();
paint.setStyle(Style.STROKE);
paint.setStrokeCap(Cap.ROUND);
paint.setStrokeWidth(1);
paint.setColor(Color.rgb(255, 255, 255));
}
public MySurfaceView(Context context) {
super(context);
// TODO Auto-generated constructor stub
this.context = context;
init();
}
public MySurfaceView(Context context, AttributeSet attr) {
super(context,attr);
this.context = context;
init();
}
public MySurfaceView(Context context, AttributeSet attr, int defStyle) {
super(context, attr, defStyle);
this.context = context;
init();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mThread.isRunning = false;
while (true) {
try {
mThread.join();
break;
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onDraw(Canvas canvas) {
// super.onDraw(canvas);
// canvas.drawColor(0, Mode.CLEAR);
x += 2;
y += 2;
r += 3;
canvas.drawColor(Color.rgb(x%255, y%255, (x+y)%255));
canvas.drawCircle(x, y, r, paint);
canvas.drawText("x:"+x, 100, 100, paint);
Log.d("onDraw","onDraw()"+"x:"+x + ",y:"+y+",r:"+r);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
Log.d("surfaceCreated", "surfaceCreated()");
mThread.isRunning = true;
mThread.start();
}
}
I am updating my Canvas from a Thread which is:
public class MySurfaceViewThread extends Thread {
SurfaceHolder holder;
MySurfaceView surfaceView;
boolean isRunning = false;
public MySurfaceViewThread(SurfaceHolder holder, MySurfaceView surfaceView) {
Log.d("thread","thread constructor");
this.holder = holder;
this.surfaceView = surfaceView;
}
#Override
public void run() {
Log.d("run","run()");
while(isRunning) {
Canvas canvas = null;
try {
canvas = holder.lockCanvas();
synchronized(holder) {
surfaceView.onDraw(canvas);
}
sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
holder.unlockCanvasAndPost(canvas);
Log.d("canvas status", "canvas unlocaked...");
}
}
}
}
When application starts and its onDraw() is called, it draws circle and text as well but on further calls to onDraw() it draws nothing. Means nothing changed on screen after first update. Any idea where I am getting wrong? I am new to android and slow learner as well.
I got the answer. Its very strange. I don't know why this worked.
I commented the following line from my activity and it runs.
surfaceView.setBackgroundColor(Color.rgb(0, 255, 0));
the activity code is:
public class SurfaceViewTutorialActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MySurfaceView surfaceView = new MySurfaceView(this);
// surfaceView.setBackgroundColor(Color.rgb(0, 255, 0));
surfaceView.setBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
setContentView(surfaceView);
}
}
If any one knows about this, kindly guide me to the right direction.
Related
I just get green Pixels at the border of my drawn bitmap if I set the alpha of the paint to 200.
The problem does not appear if I set the alpha to 100 or 255.
How can I fix this?
public class GameView extends SurfaceView implements SurfaceHolder.Callback {
private DrawThread drawThread;
private boolean surfaceCreated;
Paint paint = new Paint();
private Bitmap bitmap;
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.circleyellow);
paint.setAlpha(200);
}
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bitmap, 200, 200, paint);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
setSurfaceCreated(true);
createDrawThread();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
setSurfaceCreated(false);
}
public void setSurfaceCreated(boolean surfaceCreated) {
this.surfaceCreated = surfaceCreated;
}
public boolean getSurfaceCreated() {
return surfaceCreated;
}
public void createDrawThread(){
if (drawThread != null) {
drawThread.destroy();
}
drawThread = new DrawThread(getHolder(), this);
drawThread.setRunning(true);
drawThread.start();
}
public DrawThread getDrawThread(){
return drawThread;
}
I think I have solved the problem. A friend has told me this solution:
public GameView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
getHolder().setFormat(PixelFormat.TRANSLUCENT);
bitmap = BitmapFactory.decodeResource(
getResources(),
R.drawable.circleyellow
);
paint.setAlpha(200);
}
I have created a class from SurfaceView.I wanted it that when i touch on the screen then the screen will be refreshed by calling invalidate() function. But in my implementation invalidate () is not called when i touched on the screen.
Here is my code.
public class GameBoard extends SurfaceView implements Callback {
private SurfaceHolder holder;
int clicked =0;
public GameBoard(Context context)
{
super(context);
holder = getHolder();
holder.addCallback(this);
setFocusable(true);
requestFocus();
}
#Override
public void surfaceCreated(SurfaceHolder holder)
{
Canvas c = holder.lockCanvas(null);
onDraw(c);
holder.unlockCanvasAndPost(c);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
// TODO Auto-generated method stub
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
}
public boolean onTouchEvent(MotionEvent event)
{
int action = event.getAction();
if (action==MotionEvent.ACTION_UP)
{
clicked++;
// Canvas c = holder.lockCanvas(null);
// onDraw(c);
// holder.unlockCanvasAndPost(c);
invalidate();
}
return true;
}
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawColor(0xFF00ff00);
Paint p = new Paint();
p.setTextSize(20);
p.setColor( Color.RED );
p.setAntiAlias(true);
canvas.drawText(""+clicked, 100, 500, p);
}
}
I have an android application showing coverflow animation.I want to use view extending surfaceview inside coverflow.But this code did not show anything.
public class CoverFlowView extends SurfaceView implements Callback {
public CoverFlowView(Context context) {
super(context);
}
public CoverFlowView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CoverFlowView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
public void surfaceCreated(SurfaceHolder holder) {
MyThread myThread = new MyThread(holder);
myThread.setFlag(true);
myThread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint borderPaint = new Paint();
borderPaint.setARGB(255, 255, 128, 0);
borderPaint.setStyle(Paint.Style.STROKE);
borderPaint.setStrokeWidth(4);
canvas.drawRect(0, 0, getWidth() - 1, getHeight() - 1, borderPaint);
}
class MyThread extends Thread {
boolean flag;
SurfaceHolder myHolder;
public MyThread(SurfaceHolder holder) {
myHolder = holder;
}
public void setFlag(boolean myFlag) {
flag = myFlag;
}
public void run() {
Canvas canvas = null;
while (flag) {
try {
canvas = myHolder.lockCanvas();
synchronized (myHolder) {
invalidate();
}
} finally {
if (canvas != null) {
myHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
}
What is the problem here?I am new with Surfaceview.
Thanks in advance.
Rewrite your code like this , then it will work fine, i have checked it
public class CoverFlowView extends SurfaceView implements SurfaceHolder.Callback {
then change your constructor to
public CoverFlowView(Context context) {
super(context);
getHolder().addCallback(this);
}
Hi i draw a canvas for my application
here is the code my canvas
public class Canvas1 extends View{
int i;
int k;
float l,m;
public Canvas1(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public Canvas1 (Context context, AttributeSet attrs) {
super(context, attrs);
}
public Canvas1 (Context context, AttributeSet ats, int ds) {
super(context, ats, ds);
}
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.drawRGB(255, 255, 255);
Paint paint1=new Paint(Color.BLACK);
Paint paint=new Paint(200);
paint.setStrokeWidth((float)0.5);
canvas.drawLine(0,0,0,getMeasuredHeight(), paint1);
canvas.drawLine(0,0, getMeasuredWidth(), 0, paint1);
canvas.drawLine(0,getMeasuredHeight(), getMeasuredWidth(),getMeasuredHeight(), paint1);
canvas.drawLine(getMeasuredWidth(),getMeasuredHeight(), getMeasuredWidth(), 0, paint1);
//canvas.drawLine(0, 0, ((float)getMeasuredWidth()), ((float)getMeasuredHeight()), paint);
if(l!=0||m!=0)
{
canvas.drawLine(getMeasuredWidth()/2,getMeasuredHeight()/2,getMeasuredWidth()/2,getMeasuredHeight(),paint);
canvas.drawLine(0,0,getMeasuredWidth()/2,getMeasuredHeight()/2,paint);
}
for(int i=1;i<5;i++)
canvas.drawLine(((float)getMeasuredWidth())/5*i, 0, ((float)getMeasuredWidth()/5*i),getMeasuredHeight(), paint);
for(int i=0;i<5;i++)
canvas.drawLine(0, getMeasuredHeight()/5*i, getMeasuredWidth(), getMeasuredHeight()/5*i, paint);
canvas.save();
}
public Boolean setline(float d,float e){
l=d;
m=e;
Log.i("Hello Canvas",l+" "+m+" ");
return true;
}
}
now i am trying to call the function setline() from my main activity in this activity there is an array of canvas . here is the code of my activity
public class HelloCanvasActivity extends Activity {
/** Called when the activity is first created. */
Integer[] in={R.id.can1,R.id.can2,R.id.can3,R.id.can4,R.id.can5,R.id.can6,R.id.can7,R.id.can8};
float x,y;
int j=0;
Canvas1[] can=new Canvas1[8];
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
for(int i=0;i<8;i++)
{
can[i]=(Canvas1)findViewById(in[i]);
}
can[0].setline((float)0.5,(float) 0.5);
new Thread(new Runnable(){
public void run(){
for(int i=0;i<8;i++){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
can[i].setline((float)0.5,(float)0.5);
}
}
}).start();
}
}
when i omit Thread.sleep(1000) from my code lines are drawing but when i put Thread.sleep(1000) setline is calling after 1 second i am getting log in my log table of Hello World,but no line is drawing on canvas please help me in finding where i am wrong.
In your setline method, call invalidate()
I am trying to draw on a surface view, but I get a black screen. My xml layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.example.surfaceview.MySurface android:id="#+id/padview"
android:layout_width="match_parent" android:layout_height="match_parent" />
</FrameLayout>
Important parts of my code: MySurface.java
public class MySurface extends SurfaceView implements SurfaceHolder.Callback {
public DrawingThread thread;
public MySurface(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder surfaceholder = getHolder();
surfaceholder.addCallback(this);
thread = new DrawingThread(surfaceholder, context, new Handler() {
#Override
public void handleMessage(Message m) {
// Do some handle thing
}
});
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder tholder, int format, int width, int height) {
thread.setSurfaceSize(width, height);
thread.holder = tholder;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.running = true;
thread.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
thread.running = false;
while(retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
public Thread getThread() {
return thread;
}
public class DrawingThread extends Thread {
private SurfaceHolder holder;
private Context context;
private Handler handle;
private Paint background;
private Rect blank;
public boolean running;
public boolean created;
public int canvasheight;
public int canvaswidth;
public PadThread(SurfaceHolder tholder, Context tcontext, Handler thandler) {
holder = tholder;
context = tcontext;
handle = thandler;
// Temporary canvas dimentions
canvaswidth = 1;
canvasheight = 1;
running = false;
created = false;
background = new Paint();
background.setColor(R.color.white);
blank = new Rect(0, 0, canvaswidth, canvasheight);
}
#Override
public void run() {
Log.d("SurfaceView Test", "Drawing thread run");
while(running) {
Canvas canvas = null;
try {
canvas = holder.lockCanvas();
synchronized(holder) {
// update object states
// get user input gestures
drawing(canvas);
}
} finally {
if(canvas != null) {
holder.unlockCanvasAndPost(canvas);
}
}
}
}
private void drawing(Canvas canvas) {
// Clear screen
canvas.drawRect(blank, background);
// Draw Things
}
public void setSurfaceSize(int width, int height) {
synchronized(holder) {
canvaswidth = width;
canvasheight = height;
// New background rect
blank.set(0, 0, canvaswidth, canvasheight);
}
}
}
}
The code is based off of Google's Lunar Landar SurfaceView example at http://developer.android.com/resources/samples/LunarLander/index.html
I know that all of the code is being reached through logging.
change drawing function
background.setColor(Color.RED);
canvas.drawRect(new Rect(10, 10, 100, 100), background);
(There are test values for colors and rect)