I am trying to create in game gravity in Android. I created an update method, a display, and gravity. Right now the app does not force close, but the ball just doesn't move. Do I need to use a canvas for the .getHieght() and .getWidth() methods?
public class MainActivity extends Activity {
private int c = Color.YELLOW;
private Canvas g;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
draw();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
// draws the ball
public void draw ()
{
Display display = getWindowManager().getDefaultDisplay();
int width = display.getHeight();
int height = display.getWidth();
Bitmap bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
g = new Canvas(bitmap);
g.drawColor(c);
Paint paint = new Paint();
paint.setColor(Color.BLACK);
g.drawCircle(50, 10, 25, paint); //Put your values
update();
// In order to display this image, we need to create a new ImageView that we can display.
ImageView imageView = new ImageView(this);
// Set this ImageView's bitmap to ours
imageView.setImageBitmap(bitmap);
// Create a simple layout and add imageview to it.
RelativeLayout layout = new RelativeLayout(this);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.CENTER_IN_PARENT);
layout.addView(imageView, params);
layout.setBackgroundColor(Color.BLACK);
// Show layout in activity.
setContentView(layout);
}
private void update(){
// wall collisions;
if (x + dx > sp.getWidth() - radius - 1) {
x = sp.getWidth() - radius - 1;
// bounce off right wall;
dx = -dx;
// bounce off left wall;
} else if (x + dx < 0 + radius) {
x = 0 + radius;
dx = -dx;
} else {
x += dx;
}
// friction;
if (y == sp.getHeight() - radius - 1) {
dx *= xFriction;
if (Math.abs(dx) < .8) {
dx = 0;
}
}
// gravity;
if (y > sp.getHeight() - radius - 1) {
y = sp.getHeight() - radius - 1;
dy *= energyloss;
dy = -dy;
} else {
// velocity formula;
dy += gravity * dt;
// position formula;
y += dy * dt + .5 * gravity * dt * dt;
}
}
}
In my opinion, your approach is all wrong and is creating complexity.
Here's how I'd do it. Create two classes, one for the ball and one for somewhere to draw it. Something along these lines:
public class Ball{
private int radius;
private int xPosition;
private int yPosition;
private int color;
private Paint paint;
public Ball(int x, int y, int radius, int color)
{
this.xPosition = x; this.yPosition = y; this.radius = radius;
paint = new Paint(color);
}
void moveBall(int x, int y){
xPosition = x; yPosition =y;
}
void onDraw(Canvas canvas){
canvas.drawCircle(x, y, radius, paint);
}
}
Now somewhere to draw it.
public class Playground extends ImageView{
public Ball ball;
#Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if (ball != null ){
ball.onDraw(canvas);
}
}
}
In your activity, probably in onStart():
imageView.ball = new Ball(startX, startY, radius, Color.BLUE);
Move your "update" method into the ball class also and call ball.update() on a timer (or whenever you want to update it).
Replace the ImageView in your layout with the Playground class (first name that popped into my head).
Override onMeasure() in the ImageView extension to get height and width of the "playground".
That gives you the basics. I wrote this off the top of my head so please excuse typos etc
Also, review the answers given to you in your multiple previous questions on this topic and read the Android documentation on extending View classes, onDraw and onMeasure.
I think you're drawing just once, you may add a timer to trigger the draw() method
Related
This code is working, I created Scratch image view through which I can scratch the image view to see the the image, but scratch image view is automatically filling with scratch pattern when I reopen the app or I move to previous activity.only once the user should scratch the image view to view image and it should not fill again when I reopen the app or move to previous activity .Can anyone help me
<com.example.swapnanadendla.scratch.ScratchImageView
android:id="#+id/sample_image"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:background="#android:color/white"
android:src="#drawable/image" />
.
public class ScratchImageView extends ImageView{
public interface IRevealListener {
void onRevealed(ScratchImageView iv);
void onRevealPercentChangedListener(ScratchImageView siv, float percent);
}
public static final float STROKE_WIDTH = 12f;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
/**
* Bitmap holding the scratch region.
*/
private Bitmap mScratchBitmap;
/**
* Drawable canvas area through which the scratchable area is drawn.
*/
private Canvas mCanvas;
/**
* Path holding the erasing path done by the user.
*/
private Path mErasePath;
/**
* Path to indicate where the user have touched.
*/
private Path mTouchPath;
/**
* Paint properties for drawing the scratch area.
*/
private Paint mBitmapPaint;
/**
* Paint properties for erasing the scratch region.
*/
private Paint mErasePaint;
/**
* Gradient paint properties that lies as a background for scratch region.
*/
private Paint mGradientBgPaint;
/**
* Sample Drawable bitmap having the scratch pattern.
*/
private BitmapDrawable mDrawable;
/**
* Listener object callback reference to send back the callback when the image has been revealed.
*/
private IRevealListener mRevealListener;
/**
* Reveal percent value.
*/
private float mRevealPercent;
/**
* Thread Count
*/
private int mThreadCount = 0;
public ScratchImageView(Context context) {
super(context);
init();
}
public ScratchImageView(Context context, AttributeSet set) {
super(context, set);
init();
}
public ScratchImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* Set the strokes width based on the parameter multiplier.
* #param multiplier can be 1,2,3 and so on to set the stroke width of the paint.
*/
public void setStrokeWidth(int multiplier) {
mErasePaint.setStrokeWidth(multiplier * STROKE_WIDTH);
}
/**
* Initialises the paint drawing elements.
*/
private void init() {
mTouchPath = new Path();
mErasePaint = new Paint();
mErasePaint.setAntiAlias(true);
mErasePaint.setDither(true);
mErasePaint.setColor(0xFFFF0000);
mErasePaint.setStyle(Paint.Style.STROKE);
mErasePaint.setStrokeJoin(Paint.Join.BEVEL);
mErasePaint.setStrokeCap(Paint.Cap.ROUND);
setStrokeWidth(6);
mGradientBgPaint = new Paint();
mErasePath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
Bitmap scratchBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_scratch_pattern);
mDrawable = new BitmapDrawable(getResources(), scratchBitmap);
mDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
setEraserMode();
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mScratchBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mScratchBitmap);
Rect rect = new Rect(0, 0, mScratchBitmap.getWidth(), mScratchBitmap.getHeight());
mDrawable.setBounds(rect);
int startGradientColor = ContextCompat.getColor(getContext(), R.color.scratch_start_gradient);
int endGradientColor = ContextCompat.getColor(getContext(), R.color.scratch_end_gradient);
mGradientBgPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), startGradientColor, endGradientColor, Shader.TileMode.MIRROR));
mCanvas.drawRect(rect, mGradientBgPaint);
mDrawable.draw(mCanvas);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mScratchBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mErasePath, mErasePaint);
}
private void touch_start(float x, float y) {
mErasePath.reset();
mErasePath.moveTo(x, y);
mX = x;
mY = y;
}
/**
* clears the scratch area to reveal the hidden image.
*/
public void clear() {
int[] bounds = getImageBounds();
int left = bounds[0];
int top = bounds[1];
int right = bounds[2];
int bottom = bounds[3];
int width = right - left;
int height = bottom - top;
int centerX = left + width / 2;
int centerY = top + height / 2;
left = centerX - width / 2;
top = centerY - height / 2;
right = left + width;
bottom = top + height;
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
mCanvas.drawRect(left, top, right, bottom, paint);
checkRevealed();
invalidate();
}
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) {
mErasePath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
drawPath();
}
mTouchPath.reset();
mTouchPath.addCircle(mX, mY, 30, Path.Direction.CW);
}
private void drawPath() {
mErasePath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mErasePath, mErasePaint);
// kill this so we don't double draw
mTouchPath.reset();
mErasePath.reset();
mErasePath.moveTo(mX, mY);
checkRevealed();
//reveal();
}
public void reveal() {
clear();
}
private void touch_up() {
drawPath();
}
#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();
invalidate();
break;
default:
break;
}
return true;
}
public int getColor() {
return mErasePaint.getColor();
}
public Paint getErasePaint() {
return mErasePaint;
}
public void setEraserMode() {
getErasePaint().setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
}
public void setRevealListener(IRevealListener listener) {
this.mRevealListener = listener;
}
public boolean isRevealed() {
return mRevealPercent == 1;
}
private void checkRevealed() {
if(! isRevealed() && mRevealListener != null) {
int[] bounds = getImageBounds();
int left = bounds[0];
int top = bounds[1];
int width = bounds[2] - left;
int height = bounds[3] - top;
// Do not create multiple calls to compare.
if(mThreadCount > 1) {
Log.d("Captcha", "Count greater than 1");
return;
}
mThreadCount++;
// new AsyncTask<Integer, Void, Float>() {
//
// #Override
// protected Float doInBackground(Integer... params) {
//
// try {
// int left = params[0];
// int top = params[1];
// int width = params[2];
// int height = params[3];
//
// Bitmap croppedBitmap = Bitmap.createBitmap(mScratchBitmap, left, top, width, height);
//
// return BitmapUtils.getTransparentPixelPercent(croppedBitmap);
// } finally {
// mThreadCount--;
// }
// }
//
// public void onPostExecute(Float percentRevealed) {
//
// // check if not revealed before.
// if( ! isRevealed()) {
//
// float oldValue = mRevealPercent;
// mRevealPercent = percentRevealed;
//
// if(oldValue != percentRevealed) {
// mRevealListener.onRevealPercentChangedListener(ScratchImageView.this, percentRevealed);
// }
//
// // if now revealed.
// if( isRevealed()) {
// mRevealListener.onRevealed(ScratchImageView.this);
// }
// }
// }
//
// }.execute(left, top, width, height);
}
}
public int[] getImageBounds() {
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int vwidth = getWidth() - paddingLeft - paddingRight;
int vheight = getHeight() - paddingBottom - paddingTop;
int centerX = vwidth/2;
int centerY = vheight/2;
Drawable drawable = getDrawable();
Rect bounds = drawable.getBounds();
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
if(width <= 0) {
width = bounds.right - bounds.left;
}
if(height <= 0) {
height = bounds.bottom - bounds.top;
}
int left;
int top;
if(height > vheight) {
height = vheight;
}
if(width > vwidth) {
width = vwidth;
}
ScaleType scaleType = getScaleType();
switch (scaleType) {
case FIT_START:
left = paddingLeft;
top = centerY - height / 2;
break;
case FIT_END:
left = vwidth - paddingRight - width;
top = centerY - height / 2;
break;
case CENTER:
left = centerX - width / 2;
top = centerY - height / 2;
break;
default:
left = paddingLeft;
top = paddingTop;
width = vwidth;
height = vheight;
break;
}
return new int[] {left, top, left + width, top + height};
}
}
What you can do is store into Firebase a variable like isScratched = 1 or 0, if it's 1 it's because the user didn't scratch it yet. If the user scratch it that variable will be 0 and then in onStart you put a listener of Firebase database, if the listener finds out the value is 0 the scratch card will not be available.
I will show you some snippet here
private DatabaseReference mDatabase; //First declare your database reference
Then in init() or onCreate()
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("isScratched").setValue("1"); //here we create the isScratched and set it to 1 , meaning that the photo is not even scratched yet
Now, after the photo is scratched just set that value to 0
//After your scratch method or when the user finishes scratching the pick
mDatabase.child("isScratched").setValue("0");
Now in your onStart() or in the Activity where the image appears just attach a listener
mDatabase.child("isScratched").addSingleValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String getScratchedValue = datasnapshot.getValue(String.class);
Log.e("IsScratched : " ,""+getScratchedValue);
if(getScratchedValue.equals(0)){
//Your picture is already scratched, run the method that will show it scratched
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("Database Error: "+databaseError.getDetails());
}
});
Guys I know How to draw circle in android..But what I need is using onTouch method to rotate that circle depending on the user hand movement on that circle. Please help.
public class MainActivity extends Activity {
public class SampleView extends View {
Paint mPaint = new Paint();
private Animation anim;
public SampleView(Context context) {
super(context);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setStrokeWidth(10);
mPaint.setColor(Color.RED);
}
private void createAnimation(Canvas canvas) {
anim = new RotateAnimation(0, 360, getWidth()/2, getHeight()/2);
anim.setRepeatMode(Animation.RESTART);
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(10000L);
startAnimation(anim);
}
protected void onDraw(Canvas canvas) {
int cx = getWidth()/2; // x-coordinate of center of the screen
int cy = getHeight()/2; // y-coordinate of the center of the screen
// Starts the animation to rotate the circle.
if (anim == null)
createAnimation(canvas);
canvas.drawCircle(cx, cy, 150, mPaint); // drawing the circle.
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new SampleView(this));
}
}
First, we have to determine the angle between old and new position of circle (as below figure).
cos a = uv / (|u|*|v|)
The simple equation may be
double tx = touch_x - center_x, ty = touch_y - center_y;
double t_length = Math.sqrt(tx*tx + ty*ty);
double angle = Math.acos(ty / t_length);
Then to rotate your Canvas. you can use the code
canvas.rotate(angle);
Or you can use another method as
public int touch_x,touch_y,cx,cy;
public float angle=0;
#Override
public boolean onTouchEvent(MotionEvent event) {
touch_x = (int)event.getX();
touch_y = (int)event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
}
//double tx = touch_x - cx, ty = touch_y - cy;
// double t_length = Math.sqrt(tx*tx + ty*ty);
//angle = (float) Math.acos(ty / t_length);
double dx = touch_x - cx;
// Minus to correct for coord re-mapping
double dy = -touch_y - cy;
double inRads = Math.atan2(dy,dx);
// We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12 O'clock
if (inRads < 0)
inRads = Math.abs(inRads);
else
inRads = 2*Math.PI - inRads;
angle= (float) Math.toDegrees(inRads);
return false;
}
I'm trying to draw 4 circles horizontally in a view. But the problem is I see only 3 half circles. Circles are not being drawn properly. What is wrong with below code?
CircleView.java
public class CircleView extends View
{
private int radius;
private Paint blackPaint = new Paint();
float eachDotWidth;
float x = 0;
float circleRadius;
float width, height;
public CircleView(Context context)
{
this(context, null);
}
public CircleView(Context context, AttributeSet attrs)
{
super(context, attrs);
blackPaint.setStyle(Paint.Style.STROKE);
blackPaint.setColor(Color.BLACK);
blackPaint.setStrokeWidth(5f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
calculateDimensions();
}
private void calculateDimensions()
{
width = getWidth() ;
height = getHeight();
invalidate();
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
width = getWidth();
height = getHeight();
eachDotWidth = getWidth()/5;
circleRadius = getHeight()/2;
canvas.drawColor(Color.WHITE);
for(int i=0; i < 4; i++) {
x=(i*eachDotWidth)-circleRadius;
canvas.drawCircle(x, 2*circleRadius, circleRadius/2, blackPaint);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
FrameLayout circleLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
circleLayout = (FrameLayout) findViewById(R.id.circle_layout);
CircleView circleView = new CircleView(this);
circleLayout.addView(circleView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}
}
Please help me find and resolve the issue. Thanks.
You can create vertically circles:
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
width = getWidth();
height = getHeight();
eachDotWidth = getWidth()/8;
circleRadius = getHeight()/2;
canvas.drawColor(Color.WHITE);
for(int i=0; i < 4; i++) {
x=(2*i*eachDotWidth)+eachDotWidth;
canvas.drawCircle(x, eachDotWidth, eachDotWidth, blackPaint);
}
}
Also you can create horizontally circles:
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
width = getWidth();
height = getHeight();
eachDotWidth = getWidth()/8;
circleRadius = getHeight()/8;
canvas.drawColor(Color.WHITE);
for(int i=0; i < 4; i++) {
x=(2*i*circleRadius)+circleRadius;
canvas.drawCircle(circleRadius, x, circleRadius, blackPaint);
}
}
And also you can create diagonal circles (create y variable):
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
width = getWidth();
height = getHeight();
eachDotWidth = getWidth()/8;
circleRadius = getHeight()/8;
canvas.drawColor(Color.WHITE);
for(int i=0; i < 4; i++) {
y=(2*i*circleRadius)+circleRadius;
x=(2*i*eachDotWidth)+eachDotWidth;
canvas.drawCircle(x, y, circleRadius, blackPaint);
}
}
I think you need to revise the code drawing the circles. I don't know why you, for example, have separate values for a circle's radius and a "dot's width". I suggest that you count only with an each circle's (~ dot's) radius and add some spacing in between them to compound the width to suit your needs.
Try something like this (it draws four equal circles at zero coordinates across the canvas' width, but it doesn't account for the stroke's thickness):
// we want four equal circles across the whole width, so each circle's radius will be equal to 'width/(2*4)'
circleRadius = width/8;
// zero spacing for this example, but it can be defined
int spacingPx = 0;
canvas.drawColor(Color.WHITE);
for(int i=0; i < 4; i++) {
// the x-coordinate of each circle's middle will be a circle's radius offset by the width of the circles previously drawn plus a single spacing width multiplied by the number of the circles already drawn
x=(i*2*circleRadius) + circleRadius + i*spacingPx;
// we just simply pass the values – calculated x coordinate, y coordinate (here we want to have the circle's top at 0, so we need to set its middle y-coordinate to the value of its radius), the circle's radius and the Paint object that you already defined
canvas.drawCircle(x, circleRadius, circleRadius, blackPaint);
}
Here's how it looks like
If you want to customize it more to your needs, please specify how exactly would you like the circles to be drawn.
Using a Path and a RectF is more flexible if you want to draw shapes, you can take a look at this tutorial :
http://raphaelfavero.github.io/Creating_Animated_Custom_View/
I have a class (SpotDetails) which includes a fragment which is drawn programically. Untill now i've had the fragment drawing class (WindRose) as a child of the main class.
What i would like to do is to move the WindRose class into a AsynTask for better User Experience. Now the Application is suffering from too much work on the main thread.
Code to implement the WindRose :
WindRose windRose = new WindRose(SpotDetails.this);
//Add a new windRose (Which is created under)
FrameLayout.addView(windRose);
WindRose code :
public class WindRose extends View {
public WindRose(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float height = (float) getHeight();
float width = (float) getWidth();
float radius;
if (width > height) {
radius = height / 2;
} else {
radius = width / 2;
}
// radius = (height )/ 2;
Path path = new Path();
path.addCircle(width, height, radius, Path.Direction.CCW);
// / 2
Resources resources = getResources();
int color = resources.getColor(R.color.green_back);
Paint paint = new Paint();
paint.setColor(color);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.FILL);
float center_x, center_y;
center_x = width / 2;
center_y = height / 2;
final RectF oval = new RectF();
//Formulas :
//SD = Start Degree
//ED = End Degree
//If cakepiece passes 0 (East)
//SD, 360-(SD+ED)
//Else :
//SD, (ED-SD)
oval.set(center_x - radius, center_y - radius, center_x + radius, center_y + radius);
if (End > Start) {
canvas.drawArc(oval, Start, (End - Start), true, paint);
} else if (End < Start) {
canvas.drawArc(oval, Start, ((360 - Start) + End), true, paint);
}
}
}
Im not sure if i explained things right so please tell me if things are unclear :)
I have tried to do this :
public class WindRose extends Activity {
float Start, End;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public View DrawRose (Context context){
this.context = context;
WindRoseDrawer windRoseDrawer = new WindRoseDrawer(context);
return null; //What should i return here ?
}
private class DrawWindRose extends AsyncTask<String, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(String... strings) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
}
public class WindRoseDrawer extends View {
public WindRoseDrawer(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float height = (float) getHeight();
float width = (float) getWidth();
float radius;
if (width > height) {
radius = height / 2;
} else {
radius = width / 2;
}
// radius = (height )/ 2;
Path path = new Path();
path.addCircle(width, height, radius, Path.Direction.CCW);
// / 2
Resources resources = getResources();
int color = resources.getColor(R.color.green_back);
Paint paint = new Paint();
paint.setColor(color);
paint.setStrokeWidth(5);
paint.setStyle(Paint.Style.FILL);
float center_x, center_y;
center_x = width / 2;
center_y = height / 2;
final RectF oval = new RectF();
//Formulas :
//SD = Start Degree
//ED = End Degree
//If cakepiece passes 0 (East)
//SD, 360-(SD+ED)
//Else :
//SD, (ED-SD)
oval.set(center_x - radius, center_y - radius, center_x + radius, center_y + radius);
if (End > Start) {
canvas.drawArc(oval, Start, (End - Start), true, paint);
} else if (End < Start) {
canvas.drawArc(oval, Start, ((360 - Start) + End), true, paint);
}
}
}
}
But how should i implement this back to the SpotDetails ? And what should i return from DrawRose ?
You should draw only in the UI thread. You can't draw in the background if using the Draw inheritance method from View. Better to use a SurfaceView with lock / unlock canvas. It will use an optimized algorithm which allows for background drawing.
#Override
public void run() {
while(locker){
//checks if the lockCanvas() method will be success,and if not, will check this statement again
if(!holder.getSurface().isValid()){
continue;
}
/** Start editing pixels in this surface.*/
Canvas canvas = holder.lockCanvas();
//ALL PAINT-JOB MAKE IN draw(canvas); method.
draw(canvas);
// End of painting to canvas. system will paint with this canvas,to the surface.
holder.unlockCanvasAndPost(canvas);
}
}
Each time I create a new rectangle with this code it does not work, I can only draw to a specified position, if I use a variable to change position on execution it does not draw anything.
Inside a Asynctask method:
rect = new desenho(main.this, x, y);
Which calls this:
public class desenho extends View{
int x, y;
Paint mPaint = new Paint();
public desenho(Context context, int x, int y) {
super(context);
this.x = x;
this.y = y;
mPaint.setStrokeWidth(3);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setColor(Color.BLACK);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(width, y);
}
#Override
protected void onDraw(Canvas c) {
// TODO Auto-generated method stub
super.onDraw(c);
c.drawRect(5, y, width-5, y+x, mPaint);
}
}
It seems to me that you want the size to be independent of position. For that, these requirements must be met in your Canvas.drawRect(left, top, right, bottom, paint):
left - right = a
top - bottom = b
where a, b are constant. Example:
c.drawRect(xPos, yPos, xPos + width - 1, yPos + height - 1, mPaint);
You see in this example that
left - right = xPos - (xPos + width - 1) = 1 - width
top - bottom = yPos - (yPos + height - 1) = 1 - height
Both are constant → size is constant.