I want to draw black dots when I touch the screen and its work, but when I start the activity for the first time the screen is black and after the touch is going white.I want to be white from the beggining. How can I fix it? Here is my code:
package com.inveitix.android.clue.ui.views;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.Display;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
/**
* Created by Tito on 3.2.2016 г..
*/
public class DrawingView extends SurfaceView {
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Canvas canvas;
int width;
int height;
private SurfaceHolder surfaceHolder;
private WindowManager wm;
public DrawingView(Context context) {
super(context);
init();
}
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DrawingView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
surfaceHolder = getHolder();
wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
getScreenSize();
}
private void getScreenSize() {
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
width = size.x;
height = size.y;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (surfaceHolder.getSurface().isValid()) {
canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.WHITE);
canvas.drawCircle(event.getX(), event.getY(), 10, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
return false;
}
}
In your init method add:
holder.addCallback(new SurfaceHolder.Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceCreated(SurfaceHolder holder) {
canvas = holder.lockCanvas();
canvas.drawColor(Color.WHITE);
holder.unlockCanvasAndPost(canvas);
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
});
change this
paint.setColor(Color.BLACK);
to
paint.setColor(Color.WHITE);
in your init() put this
paint.setColor(Color.WHITE);
Related
I figured out that the width of the RectF is 0.0 so thats why it is always false. So can I set the width of the RectF width the StrokeWidth?
I have a path. And I want to handle clicks on it.
So I found out I can check that with an onTouchEvent.
So in the OnDraw() Method I draw a path and add the bounds to a rectF where I can get the left, right, top, bottom in the onTouchEvent correctly I guess.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class PathTest extends View {
Paint paint;
Path path;
RectF rectF = new RectF();
public PathTest(Context context) {
super(context);
init();
}
public PathTest(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public PathTest(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
path.moveTo((float)getWidth()/2,getHeight()-20);
path.lineTo((float)getWidth()/2,20);
path.close();
path.computeBounds(rectF,true);
canvas.drawPath(path,paint);
}
private void init(){
paint = new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(100);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
path = new Path();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
setMeasuredDimension(width,height/2);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
if(rectF.contains(event.getX(),event.getY())){
Log.d("HALLO","HI");
}else{
Log.d("HALLO","left"+rectF.left+" top"+rectF.top+" right"+rectF.right+" bottom"+rectF.bottom + " x->"+event.getX()+" y->"+event.getY());
}
}
return super.onTouchEvent(event);
}
}
It is always the else. I don't know why.
So I log the rectF Coordinates and the MotionEvent.ACTION_DOWN event.
D/HALLO: left540.0 top20.0 right540.0 bottom2240.0 x->528.0 y->490.0
D/HALLO: left540.0 top20.0 right540.0 bottom2240.0 x->1047.0 y->1021.0
D/HALLO: left540.0 top20.0 right540.0 bottom2240.0 x->1016.0 y->961.0
D/HALLO: left540.0 top20.0 right540.0 bottom2240.0 x->1059.0 y->1062.0```
I'm trying to make a custom imageview which cuts the image like below.
I checked many solutions but the nearest answer I saw is this link. But its slanting to opposite side and that too from corner. How can I cut the image with other side slanting and starting a little below.
// Custom View
public class SlantView extends View {
private Context mContext;
Paint paint ;
Path path;
public SlantView(Context ctx, AttributeSet attrs) {
super(ctx, attrs);
mContext = ctx;
setWillNotDraw(false);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
#Override
protected void onDraw(Canvas canvas) {
int w = getWidth(), h = getHeight();
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setAntiAlias(true);
path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(0,0);
path.lineTo(0,h);
path.lineTo(w,h);
path.close();
canvas.drawPath(path, paint);
}
}
Here i extended the RelativeLayout. (create a java file named cutLayout)
package com.blin.sharedelementtransition;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Xfermode;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
/**
* Created by wituser on 12/12/16.
*/
public class cutLayout extends RelativeLayout {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Xfermode pdMode = new PorterDuffXfermode(PorterDuff.Mode.CLEAR);
private Path path = new Path();
public cutLayout(Context context) {
super(context);
}
public cutLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public cutLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public cutLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
protected void dispatchDraw(Canvas canvas) {
int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
super.dispatchDraw(canvas);
paint.setXfermode(pdMode);
path.reset();
// path.moveTo(0, getHeight() - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()));
path.moveTo(0, getHeight());
path.lineTo(getWidth(), getHeight());
path.lineTo(getWidth(), getHeight() - TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, getResources().getDisplayMetrics()));
// change value (50) to change the the slope.50 means 50dp.
// path.lineTo(getWidth()/2, getHeight());
// path.moveTo(0,0); // (0,0)
// path.lineTo(getPx(50),0); // (50,0)
// path.lineTo(0,getPx(50)); // (0,50)
//
// path.lineTo(0,getHeight()-getPx(50)); // (0,H-50)
// path.lineTo(getPx(50),getHeight()); // (50,H)
// path.lineTo(0,getHeight()); // (0,H)
//
// path.lineTo(0,0); // (0,0)
// path.lineTo(getWidth()-getPx(50),0); // (W-50,0)
// path.lineTo(getWidth(),getPx(50)); // (W,50)
// path.lineTo(getWidth(),0); // (W,0)
//
// path.lineTo(getWidth(),getHeight()-getPx(50)); // (W,H-50)
// path.lineTo(getWidth()-getPx(50),getHeight()); // (W-50,H)
// path.lineTo(getWidth(),getHeight()); // (W,H)
// path.lineTo(getWidth(),0); // (W,0)
path.close();
canvas.drawPath(path, paint);
canvas.restoreToCount(saveCount);
paint.setXfermode(null);
}
private float getPx(int i) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, i, getResources().getDisplayMetrics());
}
}
and in xml, <your.package.name.cutLayout . cutLayout is the name of the javafile.
<com.blin.sharedelementtransition.cutLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_margin="8dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/bg2"
android:layout_marginBottom="0.5dp"/>
</com.blin.sharedelementtransition.cutLayout>
In my app I have a simple animation where a small bitmap moves across the screen. I have used a surface view to achieve this, but the bitmap moves very laggily, or not at all on some of the emulated devices.From my understanding , this could be because of everything running on the UI thread, but after following an example, I believe I'm using two threads (not 100% sure) I have tried looking into Asynctasks to fix this, but can't seem to figure out how to apply it to what I have.
Here is my code:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
public class MySurface extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = true;
Bitmap background;
Bitmap clouda;
float cloudax;
public MySurface(Context context) {
super(context);
init(context);
}
public MySurface(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MySurface(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
// do stuff that was in your original constructor...
ourHolder = getHolder();
ourThread = new Thread(this);
ourThread.start();
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
int screenHeight = metrics.heightPixels;
int screenWidth = metrics.widthPixels;
background = BitmapFactory.decodeResource(getResources(), R.drawable.island);
clouda = BitmapFactory.decodeResource(getResources(), R.drawable.clouda);
cloudax = screenWidth;
}
public void pause(){
isRunning = false;
ourThread.interrupt();
ourThread = null;
}
public void resume(){
isRunning = true;
}
public void run() {
// TODO Auto-generated method stub
while(isRunning){
if (!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
Rect drawableRect = new Rect(0, 0, background.getWidth(), background.getHeight());
RectF viewRect = new RectF(0, 0, getWidth(), getHeight());
canvas.drawBitmap(background, drawableRect, viewRect, null);
canvas.drawBitmap(clouda, cloudax, (getWidth()/2), null);
if (cloudax > -276) {
cloudax -= 10;
}else{
cloudax = getWidth();
}
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
I would like to set up a background image in my SurfaceView, but I can't get it to scale to the size of the screen. How can I set that up?
My Current Code:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurface extends SurfaceView implements Runnable {
SurfaceHolder ourHolder;
Thread ourThread = null;
boolean isRunning = true;
Bitmap Background;
Bitmap clouda;
public MySurface(Context context) {
super(context);
init(context);
}
public MySurface(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public MySurface(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(Context context) {
// do stuff that was in your original constructor...
ourHolder = getHolder();
ourThread = new Thread(this);
ourThread.start();
Background = BitmapFactory.decodeResource(getResources(), R.drawable.island);
clouda = BitmapFactory.decodeResource(getResources(), R.drawable.clouda);
}
public void pause(){
}
public void resume(){
}
#Override
public void run() {
// TODO Auto-generated method stub
while(isRunning){
if (!ourHolder.getSurface().isValid())
continue;
Canvas canvas = ourHolder.lockCanvas();
canvas.drawBitmap(Background, 0, 0, null);
canvas.drawBitmap(clouda, 0, 0, null);
ourHolder.unlockCanvasAndPost(canvas);
}
}
}
I have tried to apply the top answer of this, but can't seem to figure out how to use the matrix.
To scale the bitmap to the size of the SurfaceView
//The following two are just for viewing sake, they should be defined somewhere
SurfaceView targetSurfaceView;
Bitmap mySourceBitmap;
Bitmap scaledBitmap = Bitmap.createScaledBitmap(mySourceBitmap,
targetSurfaceView.getWidth(),
targetSurfaceView.getHeight(),
true);
Then in the method you use to draw:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
canvas.drawBitmap(scaledBitmap, 0, 0, paint);
}
Hope this helps
I am new to 2d graphics..
I create a text using drawText method.
I have to paint over the drawtext area..
how can i clip the area of the text and paint over the surface
package com.example.testingcanvas;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class MainActivity extends Activity {
class MyCustomView extends View {
private float x = 0, y = 0;
Path path = new Path();
Paint paint = new Paint();
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.ii);
private Rect m_ImageRect;
private Rect m_TextRect;
Context m_Context;
// you need these constructor
// you can init paint object or anything on them
public MyCustomView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
m_Context = context;
}
public MyCustomView(Context context, AttributeSet attrs) {
super(context, attrs);
m_Context = context;
}
public MyCustomView(Context context) {
super(context);
m_Context = context;
}
// then override on draw method
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(3);
paint.setTextSize(100);
// here frist create two rectangle
// one for your image and two for text you want draw on it
m_ImageRect = canvas.getClipBounds();
m_TextRect = canvas.getClipBounds();
// it gives you an area that can draw on it,
// the width and height of your rect depend on your screen size
// device
canvas.save();
canvas.drawBitmap(bm, null, m_ImageRect, paint);
canvas.drawPath(path, paint);
canvas.restore();
canvas.save();
canvas.clipRect(m_TextRect);
canvas.drawText("A", 100, 300, paint);
// canvas.drawText("A", 20, 20,50,50, paint);
// canvas.restore();
}
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_MOVE:
x = event.getX();
y = event.getY();
path.lineTo(x, y);
break;
case MotionEvent.ACTION_DOWN:
x = event.getX();
y = event.getY();
path.moveTo(x, y);
break;
case MotionEvent.ACTION_UP: {
}
default:
}
invalidate();
return true;
}
}
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyCustomView(this));
}
public void onBackPressed() {
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
finish();
onDestroy();
}
}
i am trying to draw over the text area.but i cant get it.