I extended the ViewPager with my class and overriden onDraw void like this:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
...
}
the problem is that whatever I draw in there, it scrolls with the ViewPager, but I want it to stay on the same place. I already tried setting canvas.translate(0,0); but that didn't work.
I would really appreciate any solution how to make the draw position static.
the easy solution is to translate() your Canvas before drawing your stuff:
canvas.translate(getScrollX(), 0);
// your drawing code follows...
Related
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).
In my OnDraw method, I draw path into my canvas (circle with segements). All work well, now what I am not sure how to do is how can I tilt it (sort of rotation around one axis).
Basically, what I am trying to achieve is something like the tilt functionality of google map.
Here is the pseduo code:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// I do all the drawing here
canvas.tilt(45degrees) <-----??
}
I don't think you have to create the tilt effect within the onDraw method modifying your canvas manually. Instead use setRotationX() method on the whole View. You can also define it in xml as android:rotationX="45".
Use Canvas.concat(Matrix) with a rotation matrix, i.e.:
class MyView {
private final Matrix rotate = new Matrix();
public MyView()
{
rotate.setRotate(45.0f);
}
protected void onDraw(Canvas c)
{
super.onDraw(canvas);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.concat(rotate);
canvas.restore();
}
}
Note also that you should not do any memory allocations inside onDraw() as per the android linter.
I'm trying to draw a few lines on a DrawView which extends SurfaceView.
in my onDraw method I loop over a list of float arrays and draw lines.
#Override
public void onDraw(final Canvas canvas) {
synchronized (lines) {
super.onDraw(canvas);
for (float[] l : lines) {
paint.setAntiAlias(true);
canvas.drawLines(l, paint);
}
}
}
I would like to animate each of these lines. I've tried to use ViewAnimator even though it's only Honeycomb and above but either I don't understand how to use it or it just isn't meant to be used with canvas.drawLine(). I've tried to use paint.setPathEffect but it doesn't seem to work at all. Anyone have any idea how to do this? I just want each line to take something like 1 second to draw one after the other.
I'm extending LinearLayout:
public class MyLinearLayout extends LinearLayout {
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(0xFFFF0000);
canvas.drawLine(0, 0, getWidth(), getHeight(), paint);
}
}
If the layout has child elements, shouldn't the red line above be drawn on top of them? Considering a layout like:
<MyLinearLayout>
<ImageView />
</MyLinearLayout>
I'd expect to get the red line drawn above the child ImageView. But it gets drawn below it. I was assuming all child drawing would have been completed after the super.onDraw() line is finished.
Is there a way to get to the canvas and draw something on it after all child drawing has been completed?
Thanks
Layouts don't draw unless you call setWillNotDraw(false);. They do that for efficiency reasons.
EDIT:
onDraw() really is meant to just allow you to modify the Canvas before the drawing operation happens. It doesn't actually draw. What you want to do is override draw() like so:
#Override
protected void draw(Canvas canvas) {
super.draw(canvas);
Paint paint = new Paint();
paint.setColor(0xFFFF0000);
canvas.drawLine(0, 0, getWidth(), getHeight(), paint);
}
Calling the super will draw all the children in the view. Then it will draw all the lines. I do still believe you need setWillNotDraw(false) to be called though.
I'm rewriting my answer as I hadn't seen your line of code where you were drawing to the canvas.
The canvas like some other graphics environments is inverted. So calling getHeight() is actually drawing the line at the bottom. Instead call
canvas.drawLine( 0, 0, getWidth(), 0, paint);
This means draw the line at the top, across the width of the view.
Also, calling super first paints the children prior to any custom painting so your fine there.
If you have a LinearLayout and you need:
draw all of its children first, like buttons, image views
then, on top of those components, draw something directly on the canvas.
You can try this:
public class YourClass extends LinearLayout
{
#Override
protected void dispatchDraw(Canvas canvas)
{
super.dispatchDraw(canvas);
// do your custom drawings afterwards
canvas.drawCircle...
canvas.drawLine...
I created a layout in my myviewlay.xml but this is not working, what am i missing?
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
imageBack = BitmapFactory.decodeResource(getResources(), R.layout.myviewlay, null);
}
Add this to do the actual drawing:
canvas.drawBitmap(imageBack, x, y, mPaint); //replace x,y,and mPaint with whatever you need to.
However, if you're trying to display an entire layout use setContentView(imageBack) or something similar. It's recommended to do your layout in XML.
Update: Sorry I misunderstood you at first. It looks like you ARE trying to inflate a layout from XML. In that case, in your onCreate(), call setContentView(R.layout.myviewlay);