I've drawn a circle programmatically to act as a paint brush, but I'm having trouble scaling it. I've connected the values of the radius to progress in the seekbar methods and they scale numerically, but when I touch my tablet, the brush is still the same size. How do I get the brush to redraw itself constantly scaling while I'm sliding the seekbar?
Here is the code to change the radius of circle on seek bar progress
private class test extends View {
private int radius;
public test(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint paint = new Paint();
paint.setAntiAlias(false);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
// RectF rect = new RectF(100, 100, 200, 200);
// canvas.drawRect(rect, paint);
canvas.drawCircle(50, 50, getRadius(), paint);
canvas.drawLine(10, 10, 10, 10 + 15, paint);
}
/**
* #param radius the radius to set
*/
public void setRadius(int radius) {
this.radius = radius;
}
/**
* #return the radius
*/
public int getRadius() {
return radius;
}
}
in your activity
LinearLayout layout = new LinearLayout(this);
layout.setLayoutParams(new LayoutParams(320, 420));
layout.setOrientation(LinearLayout.VERTICAL);
tt = new test(this);
tt.setLayoutParams(new LayoutParams(100, 200));
layout.addView(tt);
SeekBar bar = new SeekBar(this);
bar.setMax(40);
bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
// TODO Auto-generated method stub
tt.setRadius(progress);
tt.invalidate();
}
});
layout.addView(bar);
setContentView(layout);
Hope useful to you.
Related
I'm trying to draw 4 rectangles on the canvas so that the canvas is divided in 4 equal rectangles. With the code I now have, only the last rectangle in my code is drawn.
This is the code in my Activity:
protected void onCreate(Bundle savedInstanceState) {
...
setContentView(new MyView(this));
}
public class MyView extends View {
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = getWidth();
int y = getHeight();
Paint paintTopLeft = new Paint();
paintTopLeft.setStyle(Paint.Style.FILL);
paintTopLeft.setColor(Color.WHITE);
canvas.drawPaint(paintTopLeft);
// Use Color.parseColor to define HTML colors
paintTopLeft.setColor(Color.parseColor("#F44336"));
canvas.drawRect(0,0,x / 2,y / 2,paintTopLeft);
Paint paintTopRight = new Paint();
paintTopRight.setStyle(Paint.Style.FILL);
paintTopRight.setColor(Color.WHITE);
canvas.drawPaint(paintTopRight);
// Use Color.parseColor to define HTML colors
paintTopRight.setColor(Color.parseColor("#2196F3"));
canvas.drawRect(x / 2, 0, x, y / 2, paintTopRight);
}
}
What am I doing wrong?
Actually I see only two rectangles that are drawn with your code. But anyway, the problem is that you are calling canvas.drawPaint which clears/fills the complete canvas with that color. So you are erasing all rectangles that have been drawn already just before you draw the last one.
This code should work:
protected void onCreate(Bundle savedInstanceState) {
...
setContentView(new MyView(this));
}
public class MyView extends View {
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = getWidth();
int y = getHeight();
Paint paintTopLeft = new Paint();
paintTopLeft.setStyle(Paint.Style.FILL);
paintTopLeft.setColor(Color.WHITE);
//canvas.drawPaint(paintTopLeft); // don't do that
// Use Color.parseColor to define HTML colors
paintTopLeft.setColor(Color.parseColor("#F44336"));
canvas.drawRect(0,0,x / 2,y / 2,paintTopLeft);
Paint paintTopRight = new Paint();
paintTopRight.setStyle(Paint.Style.FILL);
paintTopRight.setColor(Color.WHITE);
// canvas.drawPaint(paintTopRight); // don't do that
// Use Color.parseColor to define HTML colors
paintTopRight.setColor(Color.parseColor("#2196F3"));
canvas.drawRect(x / 2, 0, x, y / 2, paintTopRight);
}
}
I have multiple rectangles in the middle of the view (canvas). I want to move them all to the edges of the screen smoothly simultaneously. This is not a jump, i need to see the between positions from start to end so it appear as a smooth transition.
Whats the best way to do that?
Try this code :
public class animatedView extends View {
Bitmap i;
int x=0;
int y=0;
public animatedView(Context context) {
super(context);
// TODO Auto-generated constructor stub
i = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Rect bk = new Rect();
bk.set(0, 0, canvas.getWidth(), canvas.getHeight());
Paint pBk = new Paint();
pBk.setStyle(Paint.Style.FILL);
pBk.setColor(Color.BLUE);
canvas.drawRect(bk, pBk);
canvas.drawBitmap(i, x, y, pBk);
x+=10;
invalidate();
}
}
Hope it helps !
When i choose initially red and draw a line, and then later select blue and draw a line , now the older line is also getting changed to blue instead of red, However i want the red to remain as red, and blue as such can any one help?
I also tried to get this solution online bt not solve my problem.so please help me.
DrawingView.java
public class DrawingView extends View {
Paint mPaint;
Path mpath;
Canvas mCanvas;
Bitmap myBitmap;
//initial color
private int paintColor = 0xFF660000;
private ArrayList<PathWithPaint> _graphics1 = new ArrayList<PathWithPaint>();
private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
// private Map<Path,Float> stoWid = new HashMap<Path,Float>();
private Map<Path, Integer> colorsMap = new HashMap<Path, Integer>();
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
Drawingsetup();
}
private void Drawingsetup() {
// TODO Auto-generated method stub
mPaint = new Paint();
mpath = new Path();
mCanvas = new Canvas();
mPaint.setDither(true);
mPaint.setColor(0xFFFFFFFF);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.BEVEL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// TODO Auto-generated method stub
super.onSizeChanged(w, h, oldw, oldh);
myBitmap = Bitmap.createBitmap(820, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(myBitmap);
mCanvas.drawBitmap(myBitmap, 20, 20, mPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
//return super.onTouchEvent(event);
PathWithPaint pp = new PathWithPaint();
//mCanvas.drawPath(path, mPaint);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
undonePaths.clear();
mpath.moveTo(event.getX(), event.getY());
mpath.lineTo(event.getX(), event.getY());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
mpath.lineTo(event.getX(), event.getY());
pp.setPath(mpath);
pp.setmPaint(mPaint);
_graphics1.add(pp);
} else if (event.getAction()==MotionEvent.ACTION_UP) {
mpath.lineTo(event.getX(), event.getY());
// commit the path to our offscreen
mCanvas.drawPath(mpath, mPaint);
// kill this so we don't double draw
paths.add(mpath);
mpath = new Path();
colorsMap.put(mpath,paintColor); // store the color of mPath
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
//canvas.drawBitmap(myBitmap, 0, 0, mPaint);
for(Path p: paths){
canvas.drawPath(p, mPaint);
mPaint.setColor(colorsMap.get(p));
}
canvas.drawPath(mpath, mPaint);
canvas.setColor(paintColor);
}
public void CurrentDraw(){
}
public void StartNew(){
//colorsMap.clear();
undonePaths.clear();
paths.clear();
myBitmap.eraseColor(Color.TRANSPARENT);
mpath.reset();
invalidate();
_graphics1.clear();
}
public void ColorChanged(String newColor){
//set color
// start by invalidating the View
//parse and set the color for drawing
paintColor = Color.parseColor(newColor);
mPaint.setColor(paintColor);
invalidate();
}
public void onClickUndo()
{
if (paths.size()>0) {
undonePaths.add(paths.remove(paths.size()-1));
invalidate();
}
else
{
}
}
public void onClickRedo (){
if (undonePaths.size()>0) {
paths.add(undonePaths.remove(undonePaths.size()-1));
invalidate();
}
else
{
}
}
}
DrawingActivity.java
public class DrwaingActivity extends Activity {
DrawingView drawView;
Bitmap myBitmap;
private ImageButton currentpaint ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.draw_image);
//get drawing view
drawView = (DrawingView)findViewById(R.id.drawing);
// drawView.setOnClickListener(this);
//get the palette and first color button
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
currentpaint = (ImageButton)paintLayout.getChildAt(0);
currentpaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
}
#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_item, menu);
return true;
}
public void paintClicked(View view){
if(view!=currentpaint)
{
//update color
// retrieve the tag we set for each button in the layout, representing the chosen color
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
// call the new method on the custom drawing View object
drawView.ColorChanged(color);
// update the UI to reflect the new chosen paint and set the previous one back to normal
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currentpaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currentpaint=(ImageButton)view;
}
}
I have TextDrawable class. When i call setText, the text is change but size of drawable not change follow text size. I want size of drawable auto change same as TextView. Thanks
This is my code
public class TextDrawable extends Drawable {
private Paint paint, strokePaint;
private String text;
private int instrinsicWidth, instrinsicHeight;
private float strokeWidth;
private Rect recBounds;
public TextDrawable(String text){
this.text = text;
strokeWidth = 4f;
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
paint.setTextSize(32f);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
instrinsicWidth = (int)(paint.measureText(text, 0, text.length()) + 4);
instrinsicHeight = paint.getFontMetricsInt(null) + 4;
strokePaint = new Paint();
strokePaint.setAntiAlias(true);
strokePaint.setColor(Color.GRAY);
strokePaint.setTextSize(32f);
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(4f);
strokePaint.setTextAlign(Paint.Align.CENTER);
recBounds = new Rect();
paint.getTextBounds(text, 0, text.length(), recBounds);
}
public TextDrawable(String text, float textSize, int textColor, float strokeWidth, int strokeColor){
this.text = text;
this.strokeWidth = strokeWidth;
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(textColor);
paint.setTextSize(textSize);
paint.setStyle(Paint.Style.FILL);
paint.setTextAlign(Paint.Align.CENTER);
instrinsicWidth = (int)(paint.measureText(text, 0, text.length()) + strokeWidth);
instrinsicHeight = (int)(paint.getFontMetricsInt(null) + strokeWidth);
strokePaint = new Paint();
strokePaint.setAntiAlias(true);
strokePaint.setColor(strokeColor);
strokePaint.setTextSize(textSize);
strokePaint.setStyle(Paint.Style.STROKE);
strokePaint.setStrokeWidth(strokeWidth);
strokePaint.setTextAlign(Paint.Align.CENTER);
recBounds = new Rect();
paint.getTextBounds(text, 0, text.length(), recBounds);
//Log.d("htdu87", "rW-rH; w-h: " +recBounds.width()+"-"+recBounds.height()+";"+instrinsicWidth+"-"+instrinsicHeight);
}
public void setText(String text) {
this.text = text;
instrinsicWidth = (int)(paint.measureText(text, 0, text.length()) + strokeWidth);
instrinsicHeight = (int)(paint.getFontMetricsInt(null) + strokeWidth);
setBounds(0, 0, instrinsicWidth, instrinsicHeight);
invalidateSelf();
}
#Override
public void draw(Canvas canvas) {
// TODO Auto-generated method stub
Log.d("htdu87", "bouns: "+getBounds());
canvas.drawText(text, instrinsicWidth/2, instrinsicHeight-(instrinsicHeight-recBounds.height())-strokeWidth/2, strokePaint);
canvas.drawText(text, instrinsicWidth/2, instrinsicHeight-(instrinsicHeight-recBounds.height())-strokeWidth/2, paint);
}
#Override
public int getOpacity() {
// TODO Auto-generated method stub
return paint.getAlpha();
}
#Override
public void setAlpha(int alpha) {
// TODO Auto-generated method stub
paint.setAlpha(alpha);
}
#Override
public void setColorFilter(ColorFilter filter) {
// TODO Auto-generated method stub
paint.setColorFilter(filter);
}
#Override
public int getIntrinsicHeight() {
// TODO Auto-generated method stub
return instrinsicHeight;
}
#Override
public int getIntrinsicWidth() {
// TODO Auto-generated method stub
return instrinsicWidth;
}
}
Problem is that default Views are not designed to catch changes in Drawable's size. So, you should assume that your Drawable is immutable and remove setText method at all - instead supply this parameter directly in constructor.
Basically, it leads to either recreating TextDrawable each time you want to change a text or reassigning it to respective View.
I was trying to get hold of 2D graphics in Android.
As a example i want to implement a custom drawable and show it in my Activity
I have defined a customized drawable by extending from Android drawable as mentioned below
class myDrawable extends Drawable {
private static final String TAG = myDrawable.class.getSimpleName();
private ColorFilter cf;
#Override
public void draw(Canvas canvas) {
//First you define a colour for the outline of your rectangle
Paint rectanglePaint = new Paint();
rectanglePaint.setARGB(255, 255, 0, 0);
rectanglePaint.setStrokeWidth(2);
rectanglePaint.setStyle(Style.FILL);
//Then create yourself a Rectangle
RectF rectangle = new RectF(15.0f, 50.0f, 55.0f, 75.0f); //in pixels
Log.d(TAG,"On Draw method");
// TODO Auto-generated method stub
Paint paintHandl = new Paint();
// paintHandl.setColor(0xaabbcc);
paintHandl.setARGB(125, 234, 213, 34 );
RectF rectObj = new RectF(5,5,25,25);
canvas.drawRoundRect(rectangle, 0.5f, 0.5f, rectanglePaint);
}
#Override
public int getOpacity() {
// TODO Auto-generated method stub
return 100;
}
#Override
public void setAlpha(int alpha) {
// TODO Auto-generated method stub
}
#Override
public void setColorFilter(ColorFilter cf) {
// TODO Auto-generated method stub
this.cf = cf;
}
}
I am trying to get this displayed in my activity, as shown below
public class custDrawable extends Activity {
/** Called when the activity is first created. */
LinearLayout layObj = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layObj = (LinearLayout) findViewById(R.id.parentLay);
ImageView imageView = (ImageView) findViewById(R.id.icon2);
myDrawable myDrawObj = new myDrawable();
imageView.setImageDrawable(myDrawObj);
imageView.invalidate();
// layObj.addView(myDrawObj, params);
}
}
But when i run the app i see no rectangle on the activity, can anyone help me out?
Where am i going wrong?
Your problem is in the getOpacity() method. 100 is not a valid value. You should use a PixelFormat value. Also, you should create your RectF and Paint in the constructor and then just adjust the values in draw() so you don't create so many objects that need garbage collected. Like this:
public class Square extends Drawable
{
private final Paint mPaint;
private final RectF mRect;
public Square()
{
mPaint = new Paint();
mRect = new RectF();
}
#Override
public void draw(Canvas canvas)
{
// Set the correct values in the Paint
mPaint.setARGB(255, 255, 0, 0);
mPaint.setStrokeWidth(2);
mPaint.setStyle(Style.FILL);
// Adjust the rect
mRect.left = 15.0f;
mRect.top = 50.0f;
mRect.right = 55.0f;
mRect.bottom = 75.0f;
// Draw it
canvas.drawRoundRect(mRect, 0.5f, 0.5f, mPaint);
}
#Override
public int getOpacity()
{
return PixelFormat.OPAQUE;
}
#Override
public void setAlpha(int arg0)
{
}
#Override
public void setColorFilter(ColorFilter arg0)
{
}
}
You may have to implement other overrides like getIntrinsicWidth and getIntrinsicHeight. One way to tell is that you set your layout_width and layout_height to some constant (layout_width="42dip" layout_height="42dip" in XML or setting your layoutParams to some value if you are using Java layouts). Some View types handle not having getIntrinsic* implemented than others, so try them! This includes a straight View.
You can try returning -1 if there's no specific width or height.
Hard to tell if the issue ever got resolved, but I got here via Google trying to help myself remember the details of making a custom Drawable, plus I want to help people avoid this: http://xkcd.com/979/