android View animation doesn't working - android

I tried this code and it just doesn't start the animation. the image i putted on the bitmap doesn't move as it should, it's just stay in it's place.
i didn't get any errors and i didn't change the XML file.
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.Paint.Style;
import android.graphics.Rect;
import android.view.View;
public class game extends View{
int x = 0;//locations
int y = 0;
public game(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.t);
super.onDraw(canvas);
Rect rectangle = new Rect();
rectangle.set(0, 0, canvas.getWidth(), canvas.getHeight());
Paint red = new Paint();
red.setColor(Color.RED);
red.setStyle(Paint.Style.FILL);
canvas.drawRect(rectangle, red);
if(x < canvas.getHeight())
x =+ 10;
else
x = 0;
if(y < canvas.getWidth())
y =+ 10;
else
y = 0;
Paint a = new Paint();
canvas.drawBitmap(ball, x, y, a);
invalidate();//repeat the code
}
}

Try this -
Paint a= new Paint();
a.setAntiAlias(true);
a.setFilterBitmap(true);
a.setDither(true);
canvas.drawBitmap(ball, x, y, a);

call super.onDraw(canvas) at the and of your function, and don't use invalidate() from OnDraw:
protected void onDraw(Canvas canvas) {
Bitmap ball = BitmapFactory.decodeResource(getResources(), R.drawable.t);
Rect rectangle = new Rect();
rectangle.set(0, 0, canvas.getWidth(), canvas.getHeight());
Paint red = new Paint();
red.setColor(Color.RED);
red.setStyle(Paint.Style.FILL);
canvas.drawRect(rectangle, red);
if(x < canvas.getHeight())
x =+ 10;
else
x = 0;
if(y < canvas.getWidth())
y =+ 10;
else
y = 0;
Paint a = new Paint();
canvas.drawBitmap(ball, x, y, a);
super.onDraw(canvas);
}
you can use this method to invalidate your view every X ms:
private void startTimerThread() {
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
public void run() {
try {
int ms = 500 //example of 0.5 sec
Thread.sleep(ms);
}
catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable(){
public void run() {
invalidate();
}
});
}
};
new Thread(runnable).start();
}
and call startTimerThread() at your constructor:
public game(Context context) {
super(context);
startTimerThread();
}

Related

Android SweepGradient and Drawing Lines in a circular pattern

I am trying to achieve this circular progress bar with gradient intervals UI effect
Currently I have been able to achieve this.
The code for my current implementation is below.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.graphics.drawable.AnimationDrawable;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class CBPDrawable extends AnimationDrawable {
Paint paint = new Paint();
RectF clip = new RectF();
LinearGradient shader;
Path path;
private static final int MAX = 360;
int dots = 75;
int dotRadius = 20;
RectF dotRect;
Context mContext;
public CBPDrawable(Context context){
mContext = context;
}
Shader gradient;
private int mTickOffset = 0;
private int mTickLength = 15;
private int mArcRadius = 10;
double slope, startTickX, startTickY, endTickX, endTickY, midTickX, midTickY, thetaInRadians;
double radiusOffset = mArcRadius + mTickOffset;
#Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
path = new Path();
dotRect = new RectF(0, 0, dotRadius, dotRadius);
/*
for (int i = 0; i < dots; ++i) {
start();
path.addRoundRect(dotRect, dotRadius, dotRadius, Path.Direction.CCW);
stop();
}
*/
for (int i = 360; i >= 0; i -= 5) {
thetaInRadians = Math.toRadians(360 - i);
slope = Math.tan(thetaInRadians);
startTickX = (radiusOffset * Math.cos(thetaInRadians));
startTickY = slope * startTickX;
endTickX = startTickX + ((mTickLength) * Math.cos(thetaInRadians));
endTickY = slope * endTickX;
RectF r = new RectF();
r.set((float) startTickX, (float) startTickY, (float) endTickX, (float) endTickY);
path.addRoundRect(r, (int)radiusOffset, (int)radiusOffset, Path.Direction.CCW);
}
}
#Override
public void draw(#NonNull Canvas canvas) {
Rect b = getBounds();
final int width = canvas.getWidth();
final int height = canvas.getHeight();
final int squareSide = Math.min(width, height);
canvas.translate(width / 2f, height / 2f); // moving to the center of the View
canvas.rotate(270);
final float outerRadius = squareSide / 2f;
final float innerRadius = outerRadius - dotRadius;
final float angleFactor = 360f / 72;
int[] colors = new int[]{Color.BLUE, Color.RED};
float[] positions = new float[]{0,0.4f};
gradient = new SweepGradient(outerRadius / 2f, outerRadius / 2f,colors,null);
for (int i = 0; i < 72; ++i) {
canvas.save(); // creating a "checkpoint"
canvas.rotate(angleFactor * i);
canvas.translate(innerRadius, 0); //moving to the edge of the big circle
clip.set(b);
paint.setColor(Color.GRAY);
if(angleFactor * i <= 200){
paint.setShader(gradient);
}else{
paint.setShader(null);
}
//canvas.clipRect(clip, Region.Op.REPLACE);
canvas.drawPath(path, paint);
canvas.restore(); //restoring a "checkpoint"
//stop();
}
}
#Override
public void setAlpha(#IntRange(from = 0, to = 255) int i) {
}
#Override
public void setColorFilter(#Nullable ColorFilter colorFilter) {
}
#Override
public int getOpacity() {
return PixelFormat.OPAQUE;
}
}
As can be seen from the 2 images, I am unable to get the intervals correctly as a rectangle or line.
And, the gradient does not show, in spite of using a SweepGradient.
How should I go about achieving the desired effect?
Thanks.

Dynamically updating the same canvas in android

Im building an application to draw a map structure when the user is walking. To do this i use Sensor.TYPE_STEP_DETECTOR. Upon every step detected i call the following method 'setCordinates(StepCalculator stepCalculator)'. But when i do that only the current position (one circle) is displayed, the path taken to come there(previous circles) are not shown.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import java.util.ArrayList;
public class DrawView extends View {
Paint paint = new Paint();
private int cx=0,cy=0;
private Step step;
private ArrayList<Step> steps;
private Bitmap bm;
public DrawView(Context context) {
super(context);
paint.setColor(Color.BLACK);
steps = new ArrayList<Step>();
step = new Step();
}
#Override
public void onDraw(Canvas canvas) {
for (Step i : steps) {
cy = i.getY();
cx = i.getX();
paint.setColor(Color.RED);
canvas.drawCircle(cx, cy, 50, paint);
paint.setColor(Color.BLACK);
canvas.drawCircle(cx, cy, 30, paint);
this.invalidate();
}
// }
/*for(int i =0;i<100;i++)
{
paint.setColor(Color.RED);
canvas.drawCircle(50+(i*10), 50+(i*10), 50, paint);
paint.setColor(Color.BLACK);
canvas.drawCircle(50+(i*10), 50+(i*10), 30, paint);
this.invalidate();
}*/
}
public void setCordinates(StepCalculator stepCalculator) {
stepCalculator.calculateCordinates();
step.setX(stepCalculator.getXCordinates());
step.setY(stepCalculator.getYCordinates());
steps.add(step);
this.invalidate();
}
}
A suggestion:
final Path mPath = new Path();
final Paint mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(40);
mPaint.setColor(
Color.RED
);
mPaint.setPathEffect(
new DashPathEffect(
new float[]{10, 10},
0
)
);
ImageView line = new ImageView(context) {
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPath.reset();
mPath.moveTo(
YOUR_STEP_X,
YOUR_STEP_Y
);
// If you are saving your steps, then cicle them here using lineTo()
mPath.lineTo(
YOUR_NEW_STEP_X,
YOUR_NEW_STEP_Y
);
canvas.drawPath(mPath, mPaint);
}
};
Then, on each new step, call invalidade on line line.invalidate();

Move ball back and forth

Trying to get the ball where it moves back and forth across the screen (left-right).
I tried using the draw function to update the ball position using if statements
x += speed_x;
y += speed_y;
canvas.drawCircle(x, y, 20, paint);
if (x == 0)
speed_x=-1;
if (x == getHeight())
speed_x=1;
if (y == 0)
speed_y = -1;
if (y == getWidth())
speed_y = 1;
invalidate();
This did not work.
**game.java*
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.widget.ImageView;
public class GameWorld extends SurfaceView implements Runnable {
boolean isRunning;
GameObject obj;
SurfaceHolder holder;
Canvas canvas;
Thread gameThread;
Paint paint;
private Context mContext;
int x = -1;
int y = -1;
int speed_x=1, speed_y=1;
private int xVelocity = 10;
private int yVelocity = 5;
private Handler h;
private final int FRAME_RATE = 30;
public GameWorld(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
h = new Handler();
}
private Runnable r = new Runnable() {
#Override
public void run() {
invalidate();
}
};
public GameWorld(Context context){
super(context);
isRunning=true;
obj=new GameObject(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher),200,300);
paint=new Paint();
gameThread= new Thread(this);
gameThread.start();
holder=getHolder();
}
public void run(){
while(isRunning){
if(!holder.getSurface().isValid()){
continue;
}
update();
draw();
}
}
private void update(){
obj.update();
}
private void draw(){
canvas=holder.lockCanvas();
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.FILL);
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
obj.draw(canvas);
canvas.drawColor(Color.WHITE);
x+=speed_x;
y+=speed_y;
canvas.drawCircle(x, y, 20, paint);
if(x==0)
speed_x=-1;
if(x== getHeight())
speed_x=1;
if(y==0)
speed_y=-1;
if(y==getWidth())
speed_y=1;
invalidate();
holder.unlockCanvasAndPost(canvas);
}
public boolean onTouchEvent(MotionEvent event){
obj.jump();
return super.onTouchEvent(event);
}
}
**main:**
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new GameWorld(this));
}
}
**gameobject.java**
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
public class GameObject {
int x,y;
int velY;
int width, height;
boolean jump;
Bitmap bitmap;
final int GRAVITY =2;
public GameObject(Bitmap bitmap, int x, int y){
this.x=x;
this.y=y;
this.width=bitmap.getWidth();
this.height=bitmap.getHeight();
this.bitmap=bitmap;
velY=0;
jump=false;
}
public void update(){
//handles input
if (jump){
velY=-30;
}
//add gravity
velY+=GRAVITY;
y+=velY;
//POSITION
if(y>300){
y=300;
velY=0;
}
jump=false;
}
public void jump(){
jump=true;
}
Paint paint = new Paint();
public void draw(Canvas canvas){
canvas.drawBitmap(bitmap,x,y,null);
int x=5; //ball
boolean game = true;
// while(game = true)
// {
int maxx = canvas.getWidth();
if (x <= maxx)
{
paint.setColor(Color.WHITE);
canvas.drawCircle(x, 305, 10, paint);
x= (x+2);
}
///else{
// x= (x-2);
// paint.setColor(Color.WHITE);
// canvas.drawCircle(x, 305, 10, paint);
// game = false;
//}
// }
}
public void moveball()
{
x= (x-2);
}
}
Here is my version of a ball moving based on the swipes it recives
import android.app.Activity;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.os.Bundle;
import android.view.View;
public class BouncingBallActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View boundcingBallView = new BouncingBallView(this);
setContentView(boundcingBallView);
}
}
Here is the actual view that will make the ball
package com.example.bouncingball;
import java.util.Formatter;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
public class BouncingBallView extends View {
private int xMin=0,xMax,yMin=0,yMax;
private float ballRadius = 80,ballX = ballRadius+20, ballY= ballRadius+40,ballSpeedX=5,ballSpeedY=3,previousX,previousY;
private RectF ballBounds;
private Paint paint;
private StringBuilder statusmsg = new StringBuilder();
private Formatter formatter = new Formatter(statusmsg);
public BouncingBallView(Context context) {
super(context);
ballBounds = new RectF();
paint = new Paint();
paint.setDither(true);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setHinting(Paint.HINTING_ON);
paint.setPathEffect(new DashPathEffect(new float[] {1,1}, 0));
paint.setTypeface(Typeface.MONOSPACE);
paint.setTextSize(16);
this.setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas) {
ballBounds.set(ballX-ballRadius , ballY-ballRadius,ballX+ballRadius,ballY+ballRadius);
paint.setColor(Color.GREEN);
canvas.drawOval(ballBounds, paint);
paint.setColor(Color.BLACK);
canvas.drawText(statusmsg.toString(), 10, 30,paint);
update();
invalidate();
}
private void update() {
ballX +=ballSpeedX;
ballY+=ballSpeedY;
if(ballX+ballRadius> yMax) {
ballSpeedX =-ballSpeedX;
ballX = xMax -ballRadius;
}
else if(ballX - ballRadius < xMin) {
ballSpeedX = -ballSpeedX;
ballX = xMin+ballRadius;
}
if(ballY + ballRadius > yMax) {
ballSpeedY = -ballSpeedY;
ballY = yMax-ballRadius;
}
else if (ballY - ballRadius < yMin) {
ballSpeedY = -ballSpeedY;
ballY = yMin+ballRadius;
}
statusmsg.delete(0, statusmsg.length());
formatter.format("Ball#(%3.0f,%3.0f),Speed=(%2.0f,%2.0f)", ballX, ballY,ballSpeedX, ballSpeedY);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
xMax = w-1;
yMax = h-1;
}
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT:
ballSpeedX++;
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
ballSpeedX--;
break;
case KeyEvent.KEYCODE_DPAD_UP:
ballSpeedY--;
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
ballSpeedY++;
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
ballSpeedX = 0;
ballSpeedY = 0;
break;
case KeyEvent.KEYCODE_A:
float maxRadius = (xMax > yMax) ? yMax / 2* 0.9f : xMax / 2 * 0.9f;
if(ballRadius < maxRadius)
ballRadius*=1.05;
break;
case KeyEvent.KEYCODE_Z:
if(ballRadius>20){
ballRadius *=0.95;
}
break;
}
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float currentX=event.getX();
float currentY = event.getY();
float deltaX,deltaY;
float scalingFactor = 5.0f / ((xMax > yMax) ? yMax : xMax);
switch(event.getAction()) {
case MotionEvent.ACTION_MOVE:
deltaX = currentX - previousX;
deltaY = currentY - previousY;
ballSpeedX += deltaX*scalingFactor;
ballSpeedY += deltaY*scalingFactor;
}
previousX = currentX;
previousY = currentY;
return true;
}
}

implemanting freehand crop in android

i m trying to implement freehand crop in android using canvas. i use drawPath and store it in List and draw it in canvas path drawing ok,
like this
but now i want to make all pixel in that path in side area with this code but i dont no how to do it..
public Bitmap getBitmapWithTransparentBG(Bitmap srcBitmap)
{
Bitmap result = srcBitmap.copy(Bitmap.Config.ARGB_8888, true);
int nWidth = result.getWidth();
int nHeight = result.getHeight();
for (int y = 0; y < nHeight; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
for (int i = 0; i < points.size() ; i++)
{
}
result.setPixel(x, y, Color.TRANSPARENT);
}
}
return result;
}
points is list of path coordinate hear is code for draw path
package com.org;
import java.util.ArrayList;
import java.util.List;
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.Paint.Style;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
public class SomeView extends View implements OnTouchListener {
private Paint paint;
List<Point> points;
int DIST = 2;
boolean flgPathDraw = true;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.waterlilies);
public SomeView(Context c ) {
super(c);
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
this.setOnTouchListener(this);
points = new ArrayList<Point>();
}
public SomeView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);
this.setOnTouchListener(this);
points = new ArrayList<Point>();
}
public void onDraw(Canvas canvas)
{
canvas.drawBitmap(bitmap, 0, 0, null);
Path path = new Path();
boolean first = true;
for (int i = 0; i < points.size(); i += 2)
{
Point point = points.get(i);
if (first) {
first = false;
path.moveTo(point.x, point.y);
} else if (i < points.size() - 1) {
Point next = points.get(i + 1);
path.quadTo(point.x, point.y, next.x, next.y);
} else {
path.lineTo(point.x, point.y);
}
}
canvas.drawPath(path, paint);
}
public boolean onTouch(View view, MotionEvent event) {
// if(event.getAction() != MotionEvent.ACTION_DOWN)
// return super.onTouchEvent(event);
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
if (flgPathDraw) {
points.add(point);
}
invalidate();
Log.e("Hi ==>", "Size: " + points.size());
return true;
}
public void fillinPartofPath()
{
Point point = new Point();
point.x = points.get(0).x;
point.y = points.get(0).y;
points.add(point);
invalidate();
}
public void resetView()
{
points.clear();
paint.setColor(Color.WHITE);
paint.setStyle(Style.STROKE);
flgPathDraw=true;
invalidate();
}
}
class Point {
public float dy;
public float dx;
float x, y;
#Override
public String toString() {
return x + ", " + y;
}
}
Hi i think below link for your exact solution, what u try?
Android: Free Croping of Image
Don't forget to put your vote and feedback here.
Lets look at a bit more complex example:
The red point is the point you want to test. You have to find the edges that cross the y coordinate of the red point. In this example 4 edges cross the y coordinate (the blue points).
Now test how much intersections you get on the left side and on the right side of the point you want to check. If there is an odd number of intersections on both sides the point is inside the shape.
update: you can find a more detailed description of this algorithm here
You can use Canvas.clipPath to draw only cropped region. But be awared that this method doesn't work with hardware acceleration so you have to turn it off and use software rendering.

Draw New Circle on Bitmap Android

I want to draw a circle on a canvas and have it leave a trail, rather draw a new circle each time. How would I go about doing this? All I can get it to do is move the circle around.
-CanvasTest Class
package canvas.test;
import android.app.Activity;
import android.os.Bundle;
public class CanvastestActivity extends Activity {
/** Called when the activity is first created. */
float x = 80;
float y = 20;
float r = 15;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Draw2D d = new Draw2D(this, x, y, r);
try {
Thread.sleep(100);
x++;
y++;
} catch(InterruptedException e) {}
setContentView(d);
}
}
--Draw2D Class
package canvas.test;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class Draw2D extends View {
float x;
float y;
float r;
public Draw2D(Context context, float x, float y, float r) {
super(context);
this.x = x;
this.y = y;
this.r = r;
}
#Override
protected void onDraw(Canvas c) {
super.onDraw(c);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
c.drawPaint(paint);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
c.drawCircle(x, y, r, paint);
}
}
This is my most recent test. Why would the circle now move? It's does not move at all.
Are you doing something like canvas.drawColor(Color.TRANSPARENT) or canvas.drawColor(Color.BLACK) in the begining of your doDraw method?
If you omit that call it should not clear the canvas and leave the trails you are looking for.

Categories

Resources