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 !
Related
I simply need to draw a line which moves from one coordinate of a canvas to another. I am having troubles with synchronizing my drawing code with time.\
public class CustomMYChart extends View {
float x=0,y=0;
Canvas canvas;
Paint paint;
public CustomMYChart(Context context) {
super(context);
// TODO Auto-generated constructor stub
paint = new Paint();
paint.setColor(Color.GREEN);
}
#Override
protected void onDraw(final Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
this.canvas=canvas;
for(int i=0; i<1000; i++){
canvas.drawCircle(x, y, 5, paint);
x+=1;
y+=1;
invalidate();
}
}
}
Just remove the for statement in onDraw, with just one for iteration you call 1000 times invalidate() and then you get x and y out of the screen.
#Override
protected void onDraw(final Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
this.canvas=canvas;
canvas.drawCircle(x, y, 5, paint);
x+=1;
y+=1;
invalidate();
}
I want to add canvas to relative layout. How, I do this ?
public class Board extends View{
Canvas c;
public Board(Context context) {
super(context);
// TODO Auto-generated constructor stub
character = BitmapFactory.decodeResource(getResources(), R.drawable.female_char_2);
bg = BitmapFactory.decodeResource(getResources(), R.drawable.ice_texture);
//ARENA LAYOUT is Relative Layout
arenaLayout = (RelativeLayout) findViewById(R.id.arena_layout);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.setBitmap(bg.copy(Bitmap.Config.ARGB_8888, true));
//set Background
Rect area = new Rect();
area.set(0,0,canvas.getWidth(), canvas.getHeight());
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.BLUE);
canvas.drawRect(area, paint);
//menggambar
menggambar(x,y,canvas);
if(x < canvas.getWidth()) {
x = x + 10;
} else {
y = y + 10;
x = 0;
}
}
private void menggambar(int x2, int y2, Canvas canvas) {
// TODO Auto-generated method stub
canvas.drawBitmap(character, x2, y2, paint);
arenaLayout.addView(getApplicationContext());
}
}
I want to add canvas to relative layout which possess name arenaLayout. How to add canvas to 'arenaLayout' relative layout.
If you confuse read my source code. You can give simple code to add canvas to relative layout
may be you want something in this way...
public class MainActivity extends Activity
{
...........
..........
onCreate(Bundle savedInstances)
{
........
super.oncreate(savedInstances);
arenaLayout = (RelativeLayout) findViewById(R.id.arena_layout);
Board board = new Board(this);
setContentView(board) ;
..........
}
}
or you can add the view to relativeLayout here.
I am trying to implement a Drawing Application in Android. Where the user should be able to select and move the drawn shapes.
Currently i have statically drawn some rects and text on my Drawing Canvas:
View mDrawingCanvas = new View(mContext)
{
ShapeDrawable rectangle;
#Override
public boolean isFocused() {
// TODO Auto-generated method stub
Log.d(TAG, "View's On focused is called !");
return super.isFocused();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return super.onTouchEvent(event);
}
#Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
// Work out current total scale factor
// from source to view
final float scale = mSourceScale*(float)getWidth()/(float)mSize.x;
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
//Custom View
rectangle = new ShapeDrawable(new RectShape());
rectangle.getPaint().setColor(Color.GRAY);
rectangle.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
rectangle.getPaint().setStrokeWidth(3);
rectangle.setBounds((int)(50*scale), (int)(30*scale), (int)(200*scale), (int)(150*scale));
rectangle.draw(canvas);
rectangle.getPaint().setColor(Color.BLUE);
rectangle.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
rectangle.getPaint().setStrokeWidth(3);
rectangle.setBounds((int)(200*scale), (int)(200*scale), (int)(400*scale), (int)(350*scale));
rectangle.draw(canvas);
}
};
I want to select (draw borders on the selected shape) and move the drawn Shapes in onTouch events of the drawing canvas.
Can some one please guide me about this, any help is Highly Appreciated.
This answer has demonstrated the Shape Moving Methodology that i was looking for.
And my problem is solved now. The Link is :
Drag and move a circle drawn on canvas
You should save the X and Y positions in the touch event and use them when drawing your shapes.
Below is a very basic example of how to do this, but you need to improve it (check if the touch is inside the object and only change values for that object)
Example:
public class DrawTest extends View {
private static final String TAG = "Desenho";
private ShapeDrawable rectangle;
private Paint paint;
private float currX, currY;
private Rect blue, gray;
public DrawTest(Context context) {
super(context);
currX = 1;
currY = 1;
gray = new Rect(50,30,200,150);
blue = new Rect(200,200,400,350);
paint = new Paint();
rectangle = new ShapeDrawable(new RectShape());
}
#Override
public boolean isFocused() {
Log.d(TAG, "View's On focused is called !");
return super.isFocused();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
currX = event.getX();
currY = event.getY();
invalidate();
Log.d(TAG, "View's On touch is called! X= "+currX + ", Y= "+currY);
return super.onTouchEvent(event);
}
#Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
//Custom View
rectangle.getPaint().setColor(Color.GRAY);
rectangle.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
rectangle.getPaint().setStrokeWidth(3);
gray.set((int)(50+currX), (int)(30+currY), (int)(200+currX), (int)(150+currY));
rectangle.setBounds(gray);
gray = rectangle.getBounds();
rectangle.draw(canvas);
rectangle.getPaint().setColor(Color.BLUE);
rectangle.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
rectangle.getPaint().setStrokeWidth(3);
blue.set((int)(200+currX), (int)(200+currY), (int)(400+currX), (int)(350+currY));
rectangle.setBounds(blue);
blue = rectangle.getBounds();
rectangle.draw(canvas);
}
}
I am having doubt related to working of canvas while drawing , it is mentioned that canvas holds the drawing calls and bitmap holds the actual pixel data ,for e.g in the code
public class MyView extends View{
private Paint _p;
public float x=10,y=10;
private Canvas _canvas;
static int cnt=0;
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
_p = new Paint();
_p.setColor(Color.GREEN);
_canvas = new Canvas();
this.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
cnt++;
_canvas.drawCircle(event.getX(), event.getY(), 10, _p);
if(cnt>3){
cnt = 0;
invalidate();
}
return false;
}
});
}
public void onDraw(Canvas can){
_canvas = can;
super.onDraw(_canvas);
_canvas.drawColor(Color.BLACK);
_canvas.drawCircle(x, y, 10, _p);
x = x +10;
y= y+10;
}
}
3 circles should be drawn but it is not the case , can anybody please explain me?thanks in advance
Regards,
Rohit
Your onTouch only has a one time check to draw the circle, it's not a recursive loop to keep drawing until 3 are drawn. This is assuming your _canvase.drawCircle() event (which isn't shown) doesn't draw 3 circles.
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/