SurfaceView Runnable with Android location manager - java

Hi I currently have a SurfaceView Runnable public class mapsLayout extends SurfaceView implements Runnable { which draws lines based on current geolocation. My previous solution involved having a main activity which contains the Android location manager - using a FusedLocationProviderClient as recommended by the tutorials provided by Google - and then calling the SurfaceView.
mainActivity with Android location manager -> 'SurfaceView'
However this means that the SurfaceView resets every time the location changes which happens every 10000 ticks.
Is there a way for the SurfaceView to contain the Android location manager.
If it helps I have my SurfaceView Runnable code below
public class mapsActivityLayout extends SurfaceView implements Runnable {
MyThread draw = null;
boolean canDraw = false;
Bitmap map;
SurfaceHolder surfaceHolder;
Context mContext;
Paint paint;
ArrayList<String> endNodes = new ArrayList<String>();
int bitmapX;
int bitmapY;
int viewWidth;
int viewHeight;
Paint red_paintbrush_fill, blue_paintbrush_fill, green_paintbrush_fill;
Paint red_paintbrush_stroke, blue_paintbrush_stroke, green_paintbrush_stroke;
Path line;
Path circle;
public mapsActivityLayout(Context context, ArrayList<String> endNodes) {
super(context);
this.endNodes = endNodes
mContext = context;
surfaceHolder = getHolder();
paint = new Paint();
paint.setColor(Color.DKGRAY);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
viewWidth = w;
viewHeight = h;
draw = new MyThread(viewWidth, viewHeight);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = true;
options.inMutable = true;
map = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.mapimage, options);
setUpBitmap();
}
#Override
public void run() {
Canvas canvas;
prepPaintBrushes();
while (canDraw) {
//draw stuff
if (surfaceHolder.getSurface().isValid()) {
int x = draw.getX();
int y = draw.getY();
//int radius = draw.getRadius();
canvas = surfaceHolder.lockCanvas();
canvas.save();
canvas.drawBitmap(map, bitmapX, bitmapY, paint);
ArrayList<Double> currentLocation = convertGeoToPixel(currentLat, currentLon);
ArrayList<Double> destination = convertGeoToPixel(destinationLat, destinationLat);
int width = 2699;
int height = 2699;
canvas.drawCircle(currentX, currentY, 20, red_paintbrush_fill);
canvas.drawCircle(destX, destY, 20, green_paintbrush_fill);
path.rewind();
canvas.restore();
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
private void updateFrame(int newX, int newY) {
draw.update(newX, newY);
}
/**
* Calculates a randomized location for the bitmap
* and the winning bounding rectangle.
*/
private void setUpBitmap() {
bitmapX = (int) Math.floor(
Math.random() * (viewWidth - backGround.getWidth()));
bitmapY = (int) Math.floor(
Math.random() * (viewHeight - backGround.getHeight()));
}
public void pause() {
canDraw = false;
while (true) {
try {
thread.join();
break;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void resume() {
canDraw = true;
thread = new Thread(this);
thread.start();
}
private void prepPaintBrushes() {
red_paintbrush_fill = new Paint();
red_paintbrush_fill.setColor(Color.RED);
red_paintbrush_fill.setStyle(Paint.Style.FILL);
green_paintbrush_stroke = new Paint();
green_paintbrush_stroke.setColor(Color.GREEN);
green_paintbrush_stroke.setStyle(Paint.Style.STROKE);
green_paintbrush_stroke.setStrokeWidth(10);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
setUpBitmap();
updateFrame((int) x, (int) y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
updateFrame((int) x, (int) y);
invalidate();
break;
default:
}
return true;
}
}
thread code
public class MyThread extends Thread {
private int mX;
private int mY;
public MyThread(int viewWidth, int viewHeight) {
//super()
mX = viewWidth / 2;
mY = viewHeight / 2;
}
/**
* Update the coordinates of the map.
*
* #param newX Changed value for x coordinate.
* #param newY Changed value for y coordinate.
*/
public void update(int newX, int newY) {
mX = newX;
mY = newY;
}
public int getX() {
return mX;
}
public int getY() {
return mY;
}
}

Related

Drag a rectangle on Canvas Android

I'm drawing a rectangle on a Canvas in Android. How do I drag it around on the screen? I have an onTouchEvent() method in my class that listens to MotionEvent(s). How do I use this to drag my rectangle around while preserving it's size.
My code is as follows:
public class CustomSquareView3 extends View {
private Rect rect;
private Paint paint;
public static int rotation = 45;
Canvas canvas;
int x1 = 200;
int x2 = 400;
int y1 = 200;
int y2 = 400;
public CustomSquareView3(Context context){
super(context);
int x = 50;
int y = 50;
int sideLength = 200;
rect = new Rect(x1,y1, x2, y2);
paint = new Paint();
paint.setColor(Color.GRAY);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawColor(Color.WHITE);
canvas.save();
canvas.rotate(rotation, (x1+x2)/2, (y1+y2)/2);
canvas.drawRect(rect, paint);
Paint paint2 = new Paint();
paint2.setColor(Color.WHITE);
paint2.setTextSize(50);
canvas.drawText("Hi", (x1+x2)/2, (y1+y2)/2, paint2);
canvas.restore();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int motionEvent = event.getAction();
float xMove = event.getX();
float yMove = event.getY();
switch (motionEvent){
case MotionEvent.ACTION_DOWN : {
x1 = (int) event.getX();
y1 = (int) event.getY();
rect = new Rect(x1, y1, x2, y2);
break;
}
case MotionEvent.ACTION_MOVE : {
x1 = (int) event.getX();
y1 = (int) event.getY();
rect = new Rect(x1, y1, x2, y2);
break;
}
case MotionEvent.ACTION_UP : {
x1 = (int) event.getX();
y1 = (int) event.getY();
rect = new Rect(x1, y1, x2, y2);
break;
}
default:
return false;
}
invalidate();
return true;
}
}
The above code resizes the rectangle every time I touch the screen. How do I get a smooth drag gesture in the code such that the size of the rectangle is maintained when it is dragged around the screen?
See this example:
class ViewPort extends View {
List<Layer> layers = new LinkedList<Layer>();
int[] ids = {R.drawable.layer0, R.drawable.layer1, R.drawable.layer2};
public ViewPort(Context context) {
super(context);
Resources res = getResources();
for (int i = 0; i < ids.length; i++) {
Layer l = new Layer(context, this, BitmapFactory.decodeResource(res, ids[i]));
layers.add(l);
}
}
#Override
protected void onDraw(Canvas canvas) {
for (Layer l : layers) {
l.draw(canvas);
}
}
private Layer target;
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
target = null;
for (int i = layers.size() - 1; i >= 0; i--) {
Layer l = layers.get(i);
if (l.contains(event)) {
target = l;
layers.remove(l);
layers.add(l);
invalidate();
break;
}
}
}
if (target == null) {
return false;
}
return target.onTouchEvent(event);
}
}
class Layer implements MatrixGestureDetector.OnMatrixChangeListener {
Matrix matrix = new Matrix();
Matrix inverse = new Matrix();
RectF bounds;
View parent;
Bitmap bitmap;
MatrixGestureDetector mgd = new MatrixGestureDetector(matrix, this);
public Layer(Context ctx, View p, Bitmap b) {
parent = p;
bitmap = b;
bounds = new RectF(0, 0, b.getWidth(), b.getHeight());
matrix.postTranslate(50 + (float) Math.random() * 50, 50 + (float) Math.random() * 50);
}
public boolean contains(MotionEvent event) {
matrix.invert(inverse);
float[] pts = {event.getX(), event.getY()};
inverse.mapPoints(pts);
if (!bounds.contains(pts[0], pts[1])) {
return false;
}
return Color.alpha(bitmap.getPixel((int) pts[0], (int) pts[1])) != 0;
}
public boolean onTouchEvent(MotionEvent event) {
mgd.onTouchEvent(event);
return true;
}
#Override
public void onChange(Matrix matrix) {
parent.invalidate();
}
public void draw(Canvas canvas) {
canvas.drawBitmap(bitmap, matrix, null);
}
}
class MatrixGestureDetector {
private static final String TAG = "MatrixGestureDetector";
private int ptpIdx = 0;
private Matrix mTempMatrix = new Matrix();
private Matrix mMatrix;
private OnMatrixChangeListener mListener;
private float[] mSrc = new float[4];
private float[] mDst = new float[4];
private int mCount;
interface OnMatrixChangeListener {
void onChange(Matrix matrix);
}
public MatrixGestureDetector(Matrix matrix, MatrixGestureDetector.OnMatrixChangeListener listener) {
this.mMatrix = matrix;
this.mListener = listener;
}
public void onTouchEvent(MotionEvent event) {
if (event.getPointerCount() > 2) {
return;
}
int action = event.getActionMasked();
int index = event.getActionIndex();
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
int idx = index * 2;
mSrc[idx] = event.getX(index);
mSrc[idx + 1] = event.getY(index);
mCount++;
ptpIdx = 0;
break;
case MotionEvent.ACTION_MOVE:
for (int i = 0; i < mCount; i++) {
idx = ptpIdx + i * 2;
mDst[idx] = event.getX(i);
mDst[idx + 1] = event.getY(i);
}
mTempMatrix.setPolyToPoly(mSrc, ptpIdx, mDst, ptpIdx, mCount);
mMatrix.postConcat(mTempMatrix);
if(mListener != null) {
mListener.onChange(mMatrix);
}
System.arraycopy(mDst, 0, mSrc, 0, mDst.length);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerId(index) == 0) ptpIdx = 2;
mCount--;
break;
}
}
}
You have to redo it a little. Use your rectangle instead of bitmaps.

Android : moving bmp leaving a trail ( Surface View and Canvas )

I was trying to animate a sprite for an android app and i've encounter a small problem. I'm drawing on a surfaceView that i add on top of already existing layouts. On this surfaceView, i wanted to animate few sprites so they would walk along a path.
So this is the result i'm facing right now :
The walking sprite is leaving a trail. So i decided to google this problem and apparently i had to clear the canvas first before drawing on it.
This was my onDraw method before :
public void onDraw(Canvas canvas) {
update();
int srcX = currentFrame * width;
int srcY = directionX * height;
Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
Rect dst = new Rect(x, y, x + width, y + height);
canvas.drawBitmap(bmp, src, dst, null);
}
And this was my onDraw method after
public void onDraw(Canvas canvas) {
canvas.drawRGB(0, 0, 0);
update();
int srcX = currentFrame * width;
int srcY = directionX * height;
Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
Rect dst = new Rect(x, y, x + width, y + height);
canvas.drawBitmap(bmp, src, dst, null);
}
So i now have this as a result
which is great because it leaves no more trail BUT i cant see the layouts underneath. Is there anyway i can get the best of both world ? I thought clearing the canvas would work but it obviously doesnt not work as expected.
I'll post my code below
SurfaceView :
public class MonsterView extends SurfaceView {
private Bitmap monsterImg;
private SurfaceHolder holder;
private MonsterThread mainThread;
private Sprite monsterSprite;
private int x;
private int xSpeed = 1;
public MonsterView(Context context) {
super(context);
this.mainThread = new MonsterThread(this);
this.x = 0;
holder = getHolder();
holder.setFormat(PixelFormat.TRANSPARENT);
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
mainThread.setRunning(true);
mainThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
mainThread.setRunning(false);
while (retry) {
try {
mainThread.join();
retry = false;
} catch (InterruptedException e) {
}
}
}
});
setZOrderOnTop(true);
monsterImg = BitmapFactory.decodeResource(getResources(), R.drawable.fire);
monsterSprite = new Sprite(this,monsterImg);
}
#Override
public void onDraw(Canvas canvas) {
if (x == getWidth() - monsterImg.getWidth()) {
xSpeed = -1;
}
if (x == 0) {
xSpeed = 1;
}
x = x + xSpeed;
monsterSprite.onDraw(canvas);
}
Thread :
public class MonsterThread extends Thread {
private MonsterView monsterSurface;
private boolean running;
static final long FPS = 35;
public MonsterThread(MonsterView monsterSurface){
this.monsterSurface = monsterSurface;
this.running = false;
}
#Override
public void run() {
long ticksPS = 1000 / FPS;
long startTime;
long sleepTime;
while(running){
Canvas c = null;
startTime = System.currentTimeMillis();
try{
c = monsterSurface.getHolder().lockCanvas();
synchronized (monsterSurface.getHolder()){
monsterSurface.onDraw(c);
}
} finally {
if( c!= null){
monsterSurface.getHolder().unlockCanvasAndPost(c);
}
}
sleepTime = ticksPS-(System.currentTimeMillis() - startTime);
try {
if(sleepTime > 0)
sleep(sleepTime);
else
sleep(10);
} catch (Exception e){}
}
}
public MonsterView getMonsterSurface() {
return monsterSurface;
}
public void setMonsterSurface(MonsterView monsterSurface) {
this.monsterSurface = monsterSurface;
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
Sprite :
public class Sprite {
private static final int BMP_ROWS = 4;
private static final int BMP_COLUMNS = 3;
private int x = 0;
private int y = 0;
private int xSpeed = 5;
private MonsterView monsterView;
private Bitmap bmp;
private int currentFrame = 0;
private int width;
private int height;
private int directionX;
public Sprite(MonsterView monsterView, Bitmap bmp) {
this.monsterView = monsterView;
this.bmp=bmp;
this.width = bmp.getWidth() / BMP_COLUMNS;
this.height = bmp.getHeight() / BMP_ROWS;
this.directionX = 2;
}
private void update() {
if (x > monsterView.getWidth() - width - xSpeed) {
xSpeed = -5;
directionX = 1;
}
if (x + xSpeed < 0) {
xSpeed = 5;
directionX = 2;
}
x = x + xSpeed;
currentFrame = ++currentFrame % BMP_COLUMNS;
Log.d("test", ""+currentFrame);
}
public void onDraw(Canvas canvas) {
update();
int srcX = currentFrame * width;
int srcY = directionX * height;
Rect src = new Rect(srcX, srcY, srcX + width, srcY + height);
Rect dst = new Rect(x, y, x + width, y + height);
canvas.drawBitmap(bmp, src, dst, null);
}
You're using setZOrderOnTop(), which is putting the Surface part of the SurfaceView on a layer above everything else. (By default, it's a separate layer below everything else.) When you clear it with canvas.drawRGB(0, 0, 0) you're setting the entire layer to opaque black, which is going to obscure the View layer beneath it.
If instead you clear it to transparent black, with canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR), you should get the results you want.
FWIW, you shouldn't override onDraw() if you're only drawing on the Surface. The onDraw() method is called by the View hierarchy to draw on the View part of the SurfaceView. If something manages to invalidate the SurfaceView's View, your onDraw() will be called, and you'll end up with a character sprite on the View layer. (Depending on your layout this may not be visible.) Just give the method a different name.
There are a number of ways to handle this, but generally, the way to do this is by maintaining a background layer (which is just another image), and sprite layers. Instead of clearing, at each frame you blit (copy) your background onto the surface (which erases everything), then you blit your sprites.
So you're going to have to draw the background bitmap onto the surface first before drawing your sprite. Right now you're drawing black which is covering your background layouts.
Alternatively you might be able to do canvas.drawRect with a Paint with paint.setColor to Color.Transparent.

Cannot scale background image (android studio)

public class GameView extends SurfaceView {
private Bitmap bmp;
private SurfaceHolder holder;
private GameLoopThread gameLoopThread;
private int x = 0;
private int y = 0;
private int xSpeed = 1;
public static int WIDTH = 800;
public static int HEIGHT = 450;
private Background bg;
public GameView(Context context) {
super(context);
gameLoopThread = new GameLoopThread(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) {
bg = new Background(BitmapFactory.decodeResource(getResources(), R.drawable.tuo));
bg.setVector(-5);
gameLoopThread.setRunning(true);
gameLoopThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
});
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.ic);
// tutaj dorysować tło
}
#Override
protected void onDraw(Canvas canvas) {
if (x == getWidth() - bmp.getWidth()) {
xSpeed = -4;
}
if (x == 0) {
xSpeed = 4;
}
x = x + xSpeed;
final float scaleFactorX = getWidth()/WIDTH;
final float scaleFactorY = getHeight()/HEIGHT;
if(canvas!=null) {
final int savedState = canvas.save();
canvas.scale(scaleFactorX, scaleFactorY);
bg.draw(canvas);
canvas.restoreToCount(savedState);
}
canvas.drawBitmap(bmp, x , 10, null);
}
public void update()
{
bg.update();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
x=x+10;
return super.onTouchEvent(event);
}
}
I can't scale the image - it should make a scale by dividing getWidth/WIDTH (and height too) - WIDTH and HEIGHT are the image dimensions.
It just prints a left, upper corner of an image, like there is totally no scaling ;(
If someone have any idea, I would be thankful :)
u need to calc:
/*
WIDTH/getWidth() = 4; // if ur image width = 200px
scaleFactorX = 4*getwidth();
scaleFactorY = 4*getHeight();
*/
final float scaleFactorX = WIDTH/getWidth();
final float scaleFactorY = HEIGHT/getHeight();
canvas.scale(scaleFactorX*getWidth(), scaleFactorY*getHeight());
i hope they are proportionaly...
1600*900 or something like this... 400*225

Daw line between 2 points

I am trying to draw a line between 2 points. I can draw a line between 2 points like: A to B to C. But I want to draw lines between them like A to C or C to A.
Also I wanted to draw those lines on a image background. I have a background there, but when i draw a line with background my app is lagging.
Here's the code:
package com.example.grzegorz.kropy;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.drawable.*;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.graphics.BitmapFactory;
import java.util.ArrayList;
import java.util.List;
public class PaintView extends View {
private Bitmap mBitmap;
private Canvas mCanvas; // holds the "draw" calls
private Path mPath; //Create an empty path
private Paint mPaint; // the style and color information about how to draw geometries, text and bitmaps.
private static final int TOUCH_TOLERANCE_DP = 24;
private static final int BACKGROUND =0xFFCC00 ;
private List<Point> mPoints = new ArrayList<Point>();
private int mLastPointIndex = 0;
private int mTouchTolerance;
private boolean isPathStarted = false;
public PaintView(Context context) {
super(context);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(20, 20);
Point p2 = new Point(100, 100);
Point p3 = new Point(200, 250);
Point p4 = new Point(280, 400);
Point p5 = new Point(350, 600);
Point p6 = new Point(400, 500);
Point p7 = new Point(450, 500);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
mPoints.add(p7);
}
public PaintView(Context context, AttributeSet attrs) {
super(context, attrs);
mBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.polacz);
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
// TODO just test points
Point p1 = new Point(20, 20);
Point p2 = new Point(100, 100);
Point p3 = new Point(200, 250);
Point p4 = new Point(280, 400);
Point p5 = new Point(350, 600);
Point p6 = new Point(400, 500);
Point p7 = new Point(450, 500);
mPoints.add(p1);
mPoints.add(p2);
mPoints.add(p3);
mPoints.add(p4);
mPoints.add(p5);
mPoints.add(p6);
mPoints.add(p7);
}
public PaintView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
mCanvas = new Canvas();
mPath = new Path();
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(12);
mTouchTolerance = dp2px(TOUCH_TOLERANCE_DP);
}
#Override
protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
super.onSizeChanged(width, height, oldWidth, oldHeight);
clear();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas.drawColor(BACKGROUND);
Drawable d = getResources().getDrawable(R.drawable.polacz);
d.setBounds(canvas.getClipBounds());
d.draw(canvas);
// mCustomImage.setBounds(canvas.getClipBounds());
// mCustomImage.draw(canvas);
canvas.drawBitmap(mBitmap, 0, 0, null);
// canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.polacz1), 0, 0, null);
canvas.drawPath(mPath, mPaint);
// TODO remove if you dont want points to be drawn
for (Point point : mPoints) {
canvas.drawPoint(point.x, point.y, mPaint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up(x, y);
invalidate();
break;
}
return true;
}
private void touch_start(float x, float y) {
if (checkPoint(x, y, mLastPointIndex)) {
mPath.reset();
// user starts from given point so path can beis started
isPathStarted = true;
} else {
// user starts move from point which doen's belongs to mPinst list
isPathStarted = false;
}
}
private void touch_move(float x, float y) {
// draw line with finger move
if (isPathStarted) {
mPath.reset();
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
if (checkPoint(x, y, mLastPointIndex + 1)) {
p = mPoints.get(mLastPointIndex + 1);
mPath.lineTo(p.x, p.y);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
++mLastPointIndex;
} else {
mPath.lineTo(x, y);
}
}
}
/**
* Draws line.
*/
private void touch_up(float x, float y) {
mPath.reset();
if (checkPoint(x, y, mLastPointIndex + 1) && isPathStarted) {
// move finished at valid point so draw whole line
// start point
Point p = mPoints.get(mLastPointIndex);
mPath.moveTo(p.x, p.y);
// end point
p = mPoints.get(mLastPointIndex + 1);
mPath.lineTo(p.x, p.y);
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
// increment point index
++mLastPointIndex;
isPathStarted = false;
}
}
/**
* Sets paint
*
* #param paint
*/
public void setPaint(Paint paint) {
this.mPaint = paint;
}
/**
* Returns image as bitmap
*
* #return
*/
public Bitmap getBitmap() {
return mBitmap;
}
/**
* Clears canvas
*/
public void clear() {
mBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(BACKGROUND);
mCanvas.setBitmap(mBitmap);
invalidate();
}
/**
* Checks if user touch point with some tolerance
*/
private boolean checkPoint(float x, float y, int pointIndex) {
if (pointIndex == mPoints.size()) {
// out of bounds
return false;
}
Point point = mPoints.get(pointIndex);
//EDIT changed point.y to poin.x in the first if statement
if (x > (point.x - mTouchTolerance) && x < (point.x + mTouchTolerance)) {
if (y > (point.y - mTouchTolerance) && y < (point.y + mTouchTolerance)) {
return true;
}
}
return false;
}
public List<Point> getPoints() {
return mPoints;
}
public void setPoints(List<Point> points) {
this.mPoints = points;
}
private int dp2px(int dp) {
Resources r = getContext().getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics());
return (int) px;
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:focusableInTouchMode="false">
<com.example.grzegorz.kropy.PaintView
android:layout_width="670dp"
android:layout_height="820dp"
/>
<!--<Button-->
<!--android:layout_width="wrap_content"-->
<!--android:layout_height="wrap_content"-->
<!--android:text="graj"-->
<!--android:id="#+id/button"-->
<!--android:layout_alignParentTop="true"-->
<!--android:layout_alignParentLeft="true"-->
<!--android:onClick="gra"-->
<!--android:layout_alignParentStart="true" />-->
</RelativeLayout>
Try solution works for me
public class DrawView extends View {
Paint paint = new Paint();
View startView1;
View endView1;
int myToken;
float sX,sY,eX,eY;
public DrawView(Context context,View startView ,View endView) {
super(context);
paint.reset();
myToken=token;
paint.setStrokeWidth(3);
this.startView1 = startView;
this.endView1 = endView;
}
public void onDraw(Canvas canvas) {
paint.setColor(Color.GREEN);
canvas.drawLine(startView1.getX()+startView1.getWidth() / 2.F, startView1.getY()+startView1.getHeight()/ 2.F, endView1.getX()+endView1.getWidth() / 2.F, endView1.getY()+endView1.getHeight() / 2.F, paint);
}
}
and call this DrawView class as :
Button btn1=(Button) findViewById(id1);
Button btn2=(Button) findViewById(id2);
DrawView drawView = new DrawView(RoasterScreen.this,btn1,btn2);
rootLayout.addView(drawView);
public class DrawingPanel extends View implements OnTouchListener {
private Canvas mCanvas;
private Path mPath;
private Paint mPaint, mBitmapPaint;
private ArrayList<PathPoints> paths = new ArrayList<PathPoints>();
private ArrayList<PathPoints> undonePaths = new ArrayList<PathPoints>();
private Bitmap mBitmap;
private int color;
public int SSL = Color.WHITE;
private int x, y;
private int strockWidth = 3;
private String textToDraw = null;
public static boolean isTextModeOn = false;
//public static boolean flag = true;
//public static int angle = 0;
public DrawingPanel(Context context, int color, Bitmap bitmap) {
super(context);
this.color = color;
System.out.println("---> Drawing pannel Construction <--- ");
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
mBitmap = bitmap;
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(color);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(strockWidth);
mPaint.setTextSize(30);
mPath = new Path();
paths.add(new PathPoints(mPath, color,strockWidth, false));
mCanvas = new Canvas();
}
public void colorChanged(int color) {
this.color = color;
mPaint.setColor(color);
//invalidate();
}
public void changeWidthOfStrock(int strockWidth) {
this.strockWidth = strockWidth;
mPaint.setStrokeWidth(strockWidth);
//invalidate();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
// mBitmap = AddReportItemActivity.mPhoto;
//mBitmap = getIntent().getExtras().getParcelable("Bitmap");
System.out.println("mBitmap"+mBitmap);
if(mBitmap != null) {
float xscale = (float) w / (float) mBitmap.getWidth();
float yscale = (float) h / (float) mBitmap.getHeight();
if (xscale > yscale) // make sure both dimensions fit (use the
xscale = yscale;
float newx = (float) w * xscale;
float newy = (float) h * xscale; // use the same scale for both
// dimensions
}
// if you want it centered on the display (black borders)
mBitmap = Bitmap.createScaledBitmap(mBitmap, this.getWidth(),this.getHeight(), true);
// mCanvas = new Canvas(mBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
for (PathPoints p : paths) {
mPaint.setColor(p.getColor());
mPaint.setStrokeWidth(p.getStrockWidth());
if (p.isTextToDraw()) {
//canvas.drawText(p.textToDraw, p.x, p.y, mPaint);
} else {
canvas.drawPath(p.getPath(), mPaint);
}
}
mPaint.setColor(SSL);
mPaint.setStrokeWidth(strockWidth);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private static final float TOUCH_TOLERANCE = 0;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
//mPath = new Path();
paths.add(new PathPoints(mPath, SSL,strockWidth ,false));
mPath = new Path();
}
private void drawText(int x, int y) {
//Log.v(TAG, "Here");
//Log.v(TAG, "X " + x + " Y " + y);
this.x = x;
this.y = y;
paths.add(new PathPoints(color, textToDraw, true, x, y));
// mCanvas.drawText(textToDraw, x, y, mPaint);
}
#Override
public boolean onTouch(View arg0, MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (!isTextModeOn) {
touch_start(x, y);
invalidate();
}
break;
case MotionEvent.ACTION_MOVE:
if (!isTextModeOn) {
touch_move(x, y);
invalidate();
}
break;
case MotionEvent.ACTION_UP:
if (isTextModeOn) {
drawText((int) x, (int) y);
invalidate();
} else {
touch_up();
invalidate();
}
break;
}
return true;
}
public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
invalidate();
} else {
}
// toast the user
}
public void onClickRedo() {
if (undonePaths.size() > 0) {
paths.add(undonePaths.remove(undonePaths.size() - 1));
invalidate();
} else {
}
// toast the user
}
class PathPoints {
private Path path;
// private Paint mPaint;
private int color;
private int strockW;
private String textToDraw;
private boolean isTextToDraw;
private int x, y;
public PathPoints(Path path, int color,int strockWidth ,boolean isTextToDraw) {
this.path = path;
this.color = color;
this.strockW = strockWidth;
this.isTextToDraw = isTextToDraw;
}
public PathPoints(int color, String textToDraw, boolean isTextToDraw,int x, int y) {
this.color = color;
this.textToDraw = textToDraw;
this.isTextToDraw = isTextToDraw;
this.x = x;
this.y = y;
}
public Path getPath() {
return path;
}
public void setPath(Path path) {
this.path = path;
}
/*
* private Paint getPaint() { mPaint = new Paint();
* mPaint.setAntiAlias(true); mPaint.setColor(color);
* mPaint.setStyle(Paint.Style.STROKE);
* mPaint.setStrokeJoin(Paint.Join.ROUND);
* mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(6);
* return mPaint; }
*/
public int getColor() {
return color;
}
public void setColor(int color) {
this.color = color;
}
public int getStrockWidth() {
return strockW;
}
public void setStrokWidth(int color) {
this.strockW = color;
}
public String getTextToDraw() {
return textToDraw;
}
public void setTextToDraw(String textToDraw) {
this.textToDraw = textToDraw;
}
public boolean isTextToDraw() {
return isTextToDraw;
}
public void setTextToDraw(boolean isTextToDraw) {
this.isTextToDraw = isTextToDraw;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
}
Add this view into your layout
DrawingPanel drawingPanel = new DrawingPanel(getApplicationContext(), color, bitmap);
rl_layout.addView(drawingPanel);

Android: Error while using bitmap to display image using android studio

I have created a 10x10 grid, and now would like to place an image of the player inside one of the grid squares. to do this I think i have to use bitmap? I will put all my code below. to try and do this anyway I created a game class which sets and gets the x position of the player image. I then created a player class, which is where I try to add the image, using Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sokobanplayer1);
i keep getting an error under getResources so i created a get resources method in game, but it didnt fix the problem. could someone please show me how to do this, my code is below.
//DRAW CLASS
public class Draw extends View {
Paint red = new Paint();
Paint green = new Paint();
int rectSide = 1000;
public Draw(Context context) {
super(context);
red.setColor(Color.RED);
green.setColor(Color.GREEN);
red.setStrokeWidth(8);
green.setStrokeWidth(8);
}
public void drawGrid(Canvas canvas) {
int width = canvas.getWidth();
int height = canvas.getHeight();
float startX = (width / 2) - (rectSide / 2);
float stopX = (width / 2) + (rectSide / 2);
float startY = (height / 2) - (rectSide / 2);
float stopY = (height / 2) + (rectSide / 2);
for (int i = 0; i < 1100; i += 100) {
float newY = startY + i;
canvas.drawLine(startX, newY, stopX, newY, green);
}
for (int i = 0; i < 1100; i += 100) {
float newX = startX + i;
canvas.drawLine(newX, startY, newX, stopY, green);
}
}
#Override
public void onDraw(Canvas canvas) {
drawGrid(canvas);
}
}
//GAME CLASS
public class Game {
Bitmap image;
int x;
int y;
int height;
int width;
public void setX(int x){
this.x = x;
}
public void setY(int y){
this.y = y;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getHeight(){
return height;
}
public int getWidth(){
return width;
}
public Bitmap getResources(){
return image;
}
}
//PLAYER CLASS
public class Player extends Game {
public Player(Bitmap res, int w, int h){
image = res;
x = 300;
y = 300;
height = h;
width = w;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.sokobanplayer1);
}
}
//MAIN ACTIVITY
public class MainActivity extends Activity {
Draw draw;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_main);
draw = new Draw(this);
draw.setBackgroundColor(Color.BLUE);
setContentView(draw);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Replace your Player class with this:
//PLAYER CLASS
class Player extends Game {
public Player(Context context, int w, int h){
x = 300;
y = 300;
height = h;
width = w;
image = BitmapFactory.decodeResource(context.getResources(), R.drawable.sokobanplayer1);
}
}

Categories

Resources