I am drawing different view in a custom view with canvas, and want to add custom animation to on of the view (infinite bounce) not sure how this can be achieved. Would appreciate any suggestions. Here is block of code and I want to add bounce animation to view1
class MainView extends View {
#Override
protected void onDraw(final Canvas canvas) {
canvas.save();
// Draw view 1
canvas.translate(…);
view1.draw(canvas)
// draw other views
canvas.restore();
}
}
class View1 extends View {
..
}
You can add animators directly to Views using either XML or Java. To create the bounce you would extend the interpolator class (or one of the predefined subclasses)
Related
I have this class that extends View (it's in C# because I use Xamarin)
public class ScannerOverlay : View
{
public ScannerOverlay(Context context) : base(context)
{
//Initializing some values here
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
//Draw some stuff on the canvas
}
}
I create this view using: View v = new ScannerOverlay(context);
Now I want to add a button to this view. How do I do this? The view has no layout whatsoever so AddView() is not going to work. And from what I found it's not possible to draw a button on a canvas.
Fixed it by extending from RelativeLayout instead of View.
If (like in my case) the OnDraw Method is not getting called, set the following in the constructor: this.SetWillNotDraw(false);
Basically, you can't add a View to another View.
Hard Way: You can create a View as if it has many Views inside it, but you should draw them manually using Canvas and Paint, also handle the click based on touch location of that each "fake" View. So it will take you a lot of time. This is called Custom View.
Easy Way: You can add any View to a ViewGroup and any child of ViewGroup like FrameLayout, LinearLayout, and RelativeLayout with ViewGroup.AddView(view) function. This is called Compound View.
ViewGroup extends View so you directly get all features of View event though you extend ViewGroup. In this way you can add new View to CustomView directly.
public class ScannerOverlay : ViewGroup
{
public ScannerOverlay(Context context) : base(context)
{
//Initializing some values here
}
protected override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
//Draw some stuff on the canvas
}
}
I hava a customized view and I draw its UI on its onDraw(Canvas canvas) method. I some case I need do some animation (anim is true)
public class GameView extends View {
//more code
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(item.getBitmap(), item.getXY().getX(), item.getXY().getY(), null);
canvas.drawBitmap(ResizedBitmapMapping.getHouse(), 0f, 0f, null);
if(amin){
canvas.save();
canvas.rotate(currentValue);
drawBall(canvas);
canvas.restore();
}
}
But the ball is very small, so only a small part of the view needs to be re-drawn. it should be a performance issue to draw the whole view. What is the right to draw such animation?
What your are looking for is Canvas.clipRect().
Here is a short video from Google that explains how it works and how to use it. Alternatively, you can invalidate only a region of a view with View.invalidate(int,int,int,int).
I have a code where I draw image:
class Panel extends View {
public Panel(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
Bitmap _scratch = BitmapFactory.decodeResource(getResources(), R.drawable.calvin_logo_small);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(_scratch, x-point, y-point, null);
}
}
How can I draw this image in my activity, but I don't want to change may layout. I have layout: setContentView(R.layout.main); This is possible to draw in this lauout with canvas? I have this activity and this layout have a lot of components. I only want image in place where I click with canvas. This is idea. I start application where start activity with my setContentView(R.layout.main);. After that I click on the screen and canvas draw picture in place where I clicked. This is possible to do?
Your code should work. Just override the onTouchEvent() for the view, store the co-ordinates of the touch event in field variables and invalidate() the view so that onDraw() would be called. Use the co-ordinates in onDraw() to render the image as you've already done.
To improve performance, you can cache the bitmap if it's not going to change.
I am using the onDispatchDraw(Canvas canvas) method to draw lines in my view. When I call canvas.drawLine() it always draws the line on top of all my views. Is there any way to draw the line under a button but on top of another view in my layout using canvas.drawLine()?
I have tried the following but it still draws the line over the button.
Button b;
RelativeLayout r;
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
Paint p = new Paint();
p.setColor(Color.Black);
canvas.drawLine(0,0,100,100,p);
r.removeView(b);
r.addView(b);
}
You're trying to reinvent the wheel. Z-ordering is already implemented in the window management subsystem and you can use it.
Create a custom view you want to draw on.
Make it non-clickable using android:clickable="false" or setClickable(false).
Make its background transparent and implement dispatchDraw().
Put all the views you don't want to draw on above this view in the view hierarchy.
Call super.dispatchDraw() after drawing the line. The dispatchDraw is called by viewgroup for drawing its children, so in your case, calling super.dispatchDraw() will draw the button first then you are drawing the line over it. Do dispatchDraw this way :
Updated code
class myListViewWithLine extends ListView {
....
#Override
protected void dispatchDraw(Canvas canvas) {
Paint p = new Paint();
p.setColor(Color.Black);
canvas.drawLine(0,0,100,100,p);
super.dispatchDraw(canvas);
}
....
}
Another method will be to just add a view with 1 dip as height and background color whatever you like under the button. It should look like like a line.
View v = new View(this);
ViewGroup.LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT,1);
v.setLayoutParams(lp);
v.setBackgroundColor(Color.WHITE);
addView(v,INDEX NUMBER AFTER THE BUTTON);
How can I draw a button on top of the canvas in a custom view? (Preferably on the mid-right side) Is there something I have to call before doing the button.draw(canvas)?
public class MyClass extends View {
public Simulation(Context context) {
super(context);
pauseButton.setText("TestButton");
pauseButton.setClickable(true);
pauseButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.i(TAG, "Button Pressed!");
}
});
public onDraw(Canvas canvas) {
super.onDraw(canvas);
pauseButton.draw(canvas);
}
}
Thanks for your time
You cannot insert a button into canvas. Canvas is an interface for bitmap or a bitmap buffer for a view. You can only draw other bitmap or pixels in it, not insert an object or a widget.
There are some solutions:
as Nikolay suggested, use a FrameLayout and create two layers (views), first your custom view and the second LinerView or RelativeView, which will come on top, where you can have buttons etc
draw an image of a buttun on Canvas then use onTouchEvent in your custom view and test for the coordinates of the touch, then do something... an example for onTouchEvent here: Make certain area of bitmap transparent on touch
Why do you need to draw the button yourself? Use a FrameLayout and simply have the button overlayed on your custom view.
Try this
public onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
pauseButton.draw(canvas);
canvas.restore();
}