I am used this from the android developers but don't understand why it force closes:
package com.example.shapedrawable.CustomDrawableView;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.view.View;
public class CustomDrawableViewActivity extends View {
private ShapeDrawable mDrawable;
public CustomDrawableViewActivity(Context context) {
super(context);
int x = 10;
int y = 10;
int width = 300;
int height = 50;
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(Color.BLUE);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
You don't say where it force closes which is always useful information, but I assume it's at this line:
mDrawable.getPaint().setColor(Color.BLUE);
getPaint() will return null until you call setPaint(). Try this:
Paint paint = new Paint();
paint.setColor(Color.BLUE);
mDrawable.setPaint(paint);
Related
The line is drawn with a color which is different from the background color. Then put the bitmap in canvas in an array. If the color of the given point in the array is the same as line's color, then the point is in the line. In addition, I do not want to display the canvas in my app.
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button btnCheck;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnCheck = (Button) findViewById(R.id.btn_check);
btnCheck.setOnClickListener(click);
}
private View.OnClickListener click = new View.OnClickListener() {
#Override
public void onClick(View v) {
int width = 60, height =60;
int startX = 15, startY = 8;
int stopX = 15, stopY = 20;
Paint paint = new Paint();
paint.setStrokeWidth(5);
paint.setColor(Color.RED);
Bitmap baseBitmap;
Canvas canvas;
baseBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas = new Canvas(baseBitmap);
canvas.drawColor(Color.WHITE);
canvas.drawLine(startX, startY, stopX, stopY, paint);
int[] arrImage = new int[width*height];
baseBitmap.setPixels(arrImage, 0, width, 0, 0, width, height);
int[][] points = new int[][]{
{15, 8},{15, 10},
{30, 30},{40, 40}};
String result = "";
for (int i=0; i<points.length; ++i) {
int index = getPixelIndex(width, points[i][0], points[i][1]);
result = result + ":" + (arrImage[index] == Color.RED);
}
Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
}
};
public int getPixelIndex(int imageWidth, int pos_x, int pos_y) {
return pos_y * imageWidth + pos_x;
}
}
But the four results are all false which is not the results I expected.
What are the errors for my code?
Your problem is this line:
baseBitmap.setPixels(arrImage, 0, width, 0, 0, width, height);
The setPixels() method replaces the pixel data in the Bitmap with the passed array, which, in this case, is all zeroes. It does not change the array's values, so they will still be all zeroes when you do your comparisons.
You want the getPixels() method instead.
To see the below image,
Masking star
And the code is,
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Region;
import android.view.View;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
/**
* Created by chozarajan.pandiyarajan on 11/3/2015.
*/
public class SfRatingItem extends View {
private int fillColor, minDim, topXPoint, topYPoint;
private double bigHypot, bigA, bigB, littleHypot, littleA, littleB, value;
private Paint starPaint;
private Path path;
private Bitmap starBitmap;
private Bitmap backBitmap;
public SfRatingItem(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public SfRatingItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize();
}
public SfRatingItem(Context context) {
super(context);
initialize();
this.setBackgroundColor(Color.GREEN);
}
#Override
protected void onDraw(Canvas canvas) {
initialDraw();
Paint q = new Paint(Paint.ANTI_ALIAS_FLAG);
//canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),q); // expensive call, instead set a hardware layer
setLayerType(LAYER_TYPE_HARDWARE, q);
canvas.drawBitmap(backBitmap, 0, 0, q);
q.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
canvas.drawBitmap(starBitmap, 0, 0, q);
q.setXfermode(null);
Paint p=new Paint();
p.setColor(Color.RED);
p.setStyle(Paint.Style.STROKE);
p.setAntiAlias(true);
canvas.drawPath(path,p);
}
private void initialDraw() {
starPaint.setStyle(Paint.Style.FILL_AND_STROKE);
starPaint.setAntiAlias(true);
minDim = Math.min(this.getWidth() - this.getPaddingLeft() - this.getPaddingRight(), this.getHeight() - this.getPaddingTop() - this.getPaddingBottom());
bigHypot = (minDim / Math.cos(Math.toRadians(18)));
bigB = minDim;
bigA = Math.tan(Math.toRadians(18)) * bigB;
littleHypot = bigHypot / (2 + Math.cos(Math.toRadians(72)) + Math.cos(Math.toRadians(72)));
littleA = Math.cos(Math.toRadians(72)) * littleHypot;
littleB = Math.sin(Math.toRadians(72)) * littleHypot;
topXPoint = (this.getWidth() - this.getPaddingLeft() - this.getPaddingRight()) / 2;
topYPoint = this.getPaddingTop();
path.moveTo(topXPoint, topYPoint);
path.lineTo((int) (topXPoint + bigA), (int) (topYPoint + bigB));
path.lineTo((int) (topXPoint - littleA - littleB), (int) (topYPoint + littleB));
path.lineTo((int) (topXPoint + littleA + littleB), (int) (topYPoint + littleB));
path.lineTo((int) (topXPoint - bigA), (int) (topYPoint + bigB));
path.lineTo(topXPoint, topYPoint);
path.close();
RectF bounds = new RectF();
path.computeBounds(bounds, true);
// Draw the background rectangle in a bitmap
starPaint.setColor(Color.RED);
backBitmap = Bitmap.createBitmap((int) bounds.width(), (int) bounds.height(), Bitmap.Config.ARGB_8888);
Canvas backCanvas = new Canvas(backBitmap);
final Rect backRect = new Rect(0, 0, 200, backBitmap.getHeight());
// Draw the STAR mask in a bitmap
starBitmap = Bitmap.createBitmap((int) bounds.width(), (int) bounds.height(), Bitmap.Config.ARGB_8888);
Canvas starCanvas = new Canvas(starBitmap);
starPaint.setColor(Color.RED);
starCanvas.drawPath(path, starPaint);
backCanvas.drawRect(backRect, starPaint);
}
private void initialize() {
starPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
path = new Path();
}
}
Please to see the above mentioned image.
In this code i am set the background of the window is green color.
And my question is, why the outside of the star is showing black color? and how to change that color?
The reason this is not working is because the Hardware acceleration might be turned off and you need to turn it on. Refer this: http://developer.android.com/guide/topics/graphics/hardware-accel.html
But if you are not planning to do this via Hardware Acceleration, then use
canvas.saveLayer(0,0,canvas.getWidth(),canvas.getHeight(),q);
instead of this:
setLayerType(LAYER_TYPE_HARDWARE, q);
I read the article on http://www.curious-creature.org/2013/12/21/android-recipe-4-path-tracing/
Trying to draw arrows with Path which mentioned in the article, but with the following code, I got the half arrow, I already read articles about how to draw arrows on android. This question is more about "what's wrong with the following code." Thanks in advance.
package com.example.linepractice;
import android.os.Bundle;
import android.app.Activity;
import android.view.LayoutInflater;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PracticeLineView pl = new PracticeLineView(this);
LayoutInflater mInflater = LayoutInflater.from(this);
LinearLayout mainView = (LinearLayout) mInflater.inflate(R.layout.activity_main, null);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.setMargins(120, 120, 120, 120);
pl.setLayoutParams(params);
mainView.addView(pl);
setContentView(mainView);
}
}
package com.example.linepractice;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.view.View;
public class PracticeLineView extends View {
private Paint mPaint;
public PracticeLineView(Context context) {
super(context);
mPaint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.translate(getPaddingLeft(), getPaddingTop() - getPaddingBottom());
canvas.drawPath(makeArrow(140,140), mPaint);
}
private static Path makeArrow(float length, float height) {
Path p = new Path();
p.moveTo(-2.0f, -height / 2.0f);
p.lineTo(length, 0.0f);
p.lineTo(-2.0f, height / 2.0f);
p.lineTo(-2.0f, -height / 2.0f);
p.close();
return p;
}
}
pic:
private static Path makeArrow(float length, float height) {
Path p = new Path();
p.moveTo(-2.0f, 0.0f);
p.lineTo(length, height / 2.0f);
p.lineTo(-2.0f, height);
p.lineTo(-2.0f, 0.0f);
p.close();
return p;
}
I want to draw a stack which should raise from the bottom. For example the stack height is 400, from the height 10 it should grow till it reaches 400.
I want to do this using paint and canvas.
I don't want to do it with image view/bitmap and scale animation.
Is it possible to do this with canvas and paint? if so how to achieve it?
Thanks in advance.
You could try using something like this (have not tested myself):
Paint paint = new Paint();
paint.setColor(Color.BLACK);
for(int i = 10; i < 400; i = i + 10)
{
try
{
// To slow the for loop down, can change 100 accordingly or remove altogther
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
canvas.drawRect(0, i, 10, 0, paint); // this will make 10 x 10 square starting from bottom
invalidate();
}
What ever you do with canvas, even if you try for loop or invalidate, sleep, after all its drawing the shape in single stretch. I found the result in following way. May be it would be helpful for someone else, so adding the code here.
import android.os.Bundle;
import android.os.CountDownTimer;
import android.app.Activity;
import android.graphics.Color;
import android.util.Log;
import android.view.Menu;
public class AndroidDraw extends Activity {
private DrawView drawView;
private int height = 300;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_draw);
CountDownTimer timer = new CountDownTimer(2000, 50) {
#Override
public void onTick(long millisUntilFinished) {
height = height - 10;
drawView = new DrawView(AndroidDraw.this, height);
drawView.setBackgroundColor(Color.WHITE);
setContentView(drawView);
}
#Override
public void onFinish() {
}
};
timer.start();
}
}
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
private int height;
public DrawView(Context context, int height) {
super(context);
this.height = height;
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.RED);
canvas.drawRect(30, height, 60, 300, paint );
}
}
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.