I am having a problem with visual artifacts on the screen when applying the 3D transformation found here. I have changed this so it rotates around the x axis instead of the y. When i do a full 180 rotation (top going away from you at first) im getting single pixel line artifacts at the bottom area (bottom 10-20%) of every other view that this is applied to. I am using a selector as the background of a LinearLayout and then applying this Animation to it. Can anyone think of a quick solution to this issue?
Thanks for any help!
Turns out you just have to invalidate the parent view on each animation step. If you have a custom Animation object you can just do this inside Animation.applyTransformation(...)
I had a similiar problem with a 2D animation where a View is moved off screen (outside parent view). My solution was quite simple. In my custom View I simply invalidate the parent view to have it redrawn at every frame.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
((View) this.getParent()).invalidate();
canvas.drawBitmap(icon, bm_x, bm_y, mPaint);
}
Related
I'm using a custom View to draw rectangles(which will have text inside them at a certain point) and I want to highlight each rectangle when selected, which will happen every few seconds when user selects a rectangle. Should I implement highlighted rectangle in onDraw or is there a way just to redraw each rectangle without redrawing the whole View? I was thinking of using "invalidate(rect)" but it's been deprecated.
I'm trying to be considerate of the cost of invalidating the whole View compared to just redrawing a rectangle.
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for(CellCoordinates cellCoordinate : mCoordinateCells) {
canvas.drawText(" ", cellCoordinate.getRect().exactCenterX(), cellCoordinate.getRect().exactCenterY(), cellPaint);
}
}
Using invalidate() and onDraw() is fine. Dirty rect is not really have effect on API21+
... In API 21 the given rectangle is ignored entirely in favor of an internally-calculated area instead. ...
Dirty rect is deprecated because of different drawing model in hardware accelerated views. Checkout this link for more information
Also, it seems your rectangles can be implemented as custom Drawables with states (selected and normal). It will not give you extra performance, but might help to divide and structure code for drawing. This might help
I've written a custom view that displays text in the center of the screen as seen below.
I've also made it so that if you touch the green box you can rotate and scale the text as seen below.
Heres the problem.
Whenever I rotate the text and let go, then try to rotate again it cant detect that the rect is being touched using myRect.contains(X,Y).
After some time I found that after its rotated, and touch where the original green box was, it allows me to rotate again.
OnTouchEvent is obviously calculating the Rects position correctly since it drawing in the correct location. I just can figure out why the touch coordinates seem to be referencing old positions.
Here's my onDraw() method.
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.rotate((float)mAngle, mBorderRect.centerX(), mBorderRect.centerY());
canvas.drawRect(mBorderRect, mTextBorderPaint);
canvas.drawText(mText, mBorderRect.left, mBorderRect.bottom, mTextPaint);
canvas.drawRect(mResizeRect, mBGPaint);
canvas.restore();
}
Remember that you're rotating the canvas, not the Rect. To get this to work you'll have to apply the inverse rotation on the touch position first, then compute myRect.contains(X,Y).
I am making simple ball game and l have problem.I can't change position of Ball.
I tried:
SetX() and setY() but lower APIs aren't supported.
Params and margins but when I move it left or right, the whole activity content is moving with it. Up and down moving is working fine. (Activity will have 10 ImageViews)
Android animations - Problem is that I can't get coorinates (getLeft(), getTop()) during the animation.
Canvas and draw elements - I change position of image with onDraw() and invalidate() functions but when I but backgorund and all other images (as bitmaps) it is very slow.
Can you give to me any ideas or suggestions? Thanks in advance.
Try VerticalLayout and then change position with params
I have created CustomView. The view is higher in size than the screen. So it is showing fully in the device screen.
I want to determine position to determine how much it is outside the screen in left, right top and bottom. How to do that?
For what purpose you want to know how much of your view is outside of the screen? Can't you just use Scroller?
You can call getLocalVisibleRect on the view to get the "on screen" rectangle.
For example say in your onDraw
#Override
protected void onDraw(Canvas canvas) {
Rect r=new Rect();
getLocalVisibleRect(r);
// 0 to r.top is above the visible screen, etc
...
Once you have that rect it should be simple to calculate the values you want.
Ok, here's the deal. I want to move items in my extended gallery class to change the order of images. The way i'm doing it now:
on long press remove the current selected item,
use onDraw() to draw the same image so i can move it around using onTouchEvent()
on release add the item again
This works fine but the problem is that when using the onDraw() method it will draw the image behind the gallery items. Is there a way to change the priority of what is drawn?
Well i found this out after going into a totally different direction =/
Here's the solution for people that have the same problem:
In constructor (or anywhere else you initialize the component) set setWillNotDraw(false) and override dispatchDraw(). dispatchDraw() draws the ViewGroup children so you can decide yourself if you want to draw behind or a top of the other views.
Example taken from Custom drawing on top of Gallery view (and it's child views)
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
// do your drawing stuff here
canvas.drawPath(mPath,mPaint);
}