I have a bit specific problem, but hopefully someone will chime in and help.
I've written a custom zoom animation (posting runnables that change the target view to a handler between certain amount of time) but when i change the view's width and height it is as if I've performed a zoom around (0,0) of the view whereas I want to zoom around its center so I move the view by changing its margins accordingly. The thing is though that when the zoom iteration step is too small (i.e 0.01f and less) I have to change the margins of the view by something like 1px sometimes only in one of the directions which makes it look as if the animation is glitchy. I'm not sure of the exact reason but I've tried the following things:
1) I tried changing the margins by overriding onLayout() of my parent view which will be caled when setting the layoutParams upon zooming( I did this in order to avoid a second call to setLayoutParams() upon moving which actually now doesn't seem quite reasonable since setLayoutParams() just sets some flag which will be used later on).
2) I'm checking the new margins to set so that they are set only when there's a difference between the new and the old margins in both X and Y directions.
3)I tried using view.offsetLeftAndRight() view.offsetTopAndBottom() instead of changing the layout params in order to move the view, but it was again to no avail.
Any suggestions what will do the trick?
If I undestand you correctly you need to get Bitmap cache from view and draw it manually. In this case bitmap will be drawn without glitches (if Bitmap filtering is on).
You can do it in following steps:
get view cache - through View.getDrawingCache or by calling View.draw function
hide view
get current system time - SystemClock.elapsedRealtime (thanks to this you can calculate animation progress)
start posting runnables to invalidate your screen and check whether animation is ended
show view
Possibly it can be done via Android Animation class but I do not use it as it quite limited.
Related
Another questions about setting position of a view. If you want to move a view around then you can do setX, setTranslationX, setLeft or LayoutParam.leftMargin
Offcourse there is also overriding the onDraw method and using Matrix/Bitmap/Canvas operation.
I was wondering what's the difference. Do they all ultimetly adjust the same value which is x coordinate of the view?
It would be good to have it all in one post for future readers as well
So far I know,
LayoutParam.LeftMargin: is available for all API (specific under Api
8)
SetTranslation: Difference between original left bound of the view and the new leftbound. Though I heard maybe it is not persistent?
Anyone can shed light on the differences and if they impact different properties or the same property?
I believe that the main difference between setLeft and setX() is that setLeft() is relative to its parent view, where setX() just sets the position relative to the whole screen, which is the same as setTranslationX().
In setLeft() terms it means that the layout system can change its layout position. For example if we would use setLeft while scrolling through a RecyclerView the system would change its position accordingly, so the proper use in this case would be setX().
I'm tackling the task of an overlaying drawable over a view that animates the drawing of a checkmark as in the following video https://vid.me/MsQj
I don't have a preferred method for doing this but it's just not coming out the way I wanted it to, I tried:
Two views, each with on side of the checkmark to be revealed with an animation, however I'm stuck at the "revealed with an animation" since I can't use the circular reveal on -21
Frame by frame animation, this is the easiest but I'd hate to have 60 images for this stupid animation if it can be done programmatically
Drawing on a custom view canvas
My question would be, is there anything that can make this easier on me, or do I have to tackle it head first and just get on with it
You could create a custom View class which contains two lines defined by ShapeDrawables, one for each leg of the tick. Expose the lengths of these two lines as properties of the class, and then use Property Animation to animate the lengths of the lines.
Property Animation is flexible enough to handle pretty complex timing and sequencing of various properties. In this particular case you would probably want to use an AnimatorSet to sequence the two line animations so the second starts once the first has finished.
I ended up developing a custom View thanks to #SoundConception suggestion and finding out about ObjectAnimator which are very powerful in Android. In essence what goes on is we set a width for the first and second line that make the checkmark and using the animator change the value of those properties from 0 to the desired one.
On the setter for the property, we invalidate the View to redraw it with the new value and with a little tweaking I made a nice View that while its currently only working for my specific layout (ie it needs some more work on the offset calculation) it's able to draw an animated checkmark with some stuff that is customizable.
Precisely, you can set the line width, the color, the length and the animation time. And touching the java file, you can change the interpolator and all the rest of the stuff.
Hopefully the code, while not really commented serves as a basis for someone trying something similar.
For example the following code would generate something like this video, although not really because I was testing opacity and thinner lines, but you get my drift.
<coop.devtopia.CheckmarkView
android:layout_width="250dp"
android:layout_height="250dp"
android:layout_centerInParent="true"
android:id="#+id/view"
app:first_leg_length="50"
app:second_leg_length="100"
app:total_duration="1500"
app:stroke_width="20"
app:stroke_color="#22000000"/>
Repository
Update 4/2/15
I've played with this a little further and added dynamic offset calculation (fancy way of saying centering) to the tick, meaning we can generate big checkmarks, small checkmarks, skinny or thick, reversed or straight and they will be centered in the view. Can't guarantee the same for checkmarks bigger than the container, they will likely be cropped.
Here are a few of the checkmarks generated for this demonstration, of course the animate as if drawn and the effect can be very pleasing and resource friendly. This turn out to be a pretty interesting subject after all.
Is it possible to rotate views in XML with APIs previous to Honeycomb - maybe with the support package? Or is the only way to create a custom class, like described here Vertical (rotated) label in Android
Edit: What I need is a statically rotated view (specifically a TextView, but I guess it's enough to know how to do it with a View). Starting with honeycomb there's a rotation attribute which can be used in XML. I need something like that.
The only thing I have found until now is use an animation with duration 0 but this still moves a bit at start and I don't want that. I tried setting the views invisible and attaching a listener to the animation which makes them visible on animation finished callback, but that made strange results... that changed the position of the views, for some reason.
The best way is with the custom subclass implementation that you linked to, where you can rotate the canvas and resize the view appropriately. This ensures that the view bounds are also set to match the text that is drawn.
The only method of transforming views externally prior to HC is the animation framework, and applying an Animation to the view with a duration of 0 and fillAfter set to true will work, but you may notice flickering on some devices as often the view will render normally on its first frame and then animated to its final position from that point onward. You can work around this by hiding the view and displaying it a bit late...but you can see how hacks are starting to stack up.
In addition, doing an Animation prior to HC will not transform the view bounds themselves, so you won't be able to neatly pack other views around this one because its position from a layout perspective will still be the rectangle calculated for the horizontal (non-rotated) text.
The simple subclass is definitely the preferred method.
HTH
Is it possible to rotate views in XML with APIs previous to Honeycomb
There is RotateAnimation. However, depending on what you are trying to accomplish, that may not meet your needs.
So, much to my chagrin, I found out while testing on an earlier device, that pre-API version 11, the View class has no setAlpha nor setX methods. Can someone suggest an alternative? I'm currently moving a view around by updating its X location, and fading it in and out based on user interaction.
You may use standard Animation to implement such program logic, such as AlphaAnimation and TranslateAnimation to make movement of your View. But also you should keep in mind that original position of View at it's parent layout isn't changed (only pixels are redrawn). That means, that when user would taps on new image of View, this View would not get event, as it's Rect remains in the old position.
You could relocate Views rectangle after the end of animation, using View.layout() method with 4 positioning parameters passed there, but in this case you should consider about your layout nature, because for example if you work with LinearLayout and change the position of it sibling by calling layout() method, next change of one of UI elements size will call reaqestLayout() method and your animated View will come back at it's initial position
I want to rotate an Android View with API level 8. For example, I want to rotate an EditText by 90 degrees so that when the user enters text into a left justified EditText, the first character is at the bottom (rotated 90 degrees) and subsequent characters are entered upwards.
I first tried using an animation with duration of 0, but you still see the field rotate. Unfortunately, this is a non-starter. If I could find a way to hide the animation completely, this method looks to be the simplest.
I then tried rotating the canvas in onDraw which works great for square Views but not so great for ones that aren't square (and I don't control the dimensions of the EditText). I tried various attempts at clipping and translating the canvas, but while I could get the cursor to come into view at the start of text input, it would do weird things once somebody started entering more content (usually the content would disappear out of view).
I also tried making the View square in onMeasure, then rotating the canvas in onDraw, then putting the View dimensions back in a subsequent onMeasure. The first two steps worked great. But the third step produced similar results as described above: things looked ok until the user started entering more text at which point the field text did strange things (usually disappearing).
Has anybody been able to successfully rotate a non-square Android View (an EditText for example) without animation, and with API level 8 or lower?
I've spent a pretty good amount of time trying to rotate a view exactly on API level 8 and I think it's impossible to make it work properly. FYI, it doesn't work correctly on android 3.2 either although there's a setRotation(int angle) method in the View class. This won't work correctly at all for VideoView for example.
P.S back then it seemed that I've managed to make the rotation thing work for anything other than VideoView though. Have you overriden the onTouchEvent method? If you have not your view won't be receiving the touch event since rotating the canvas will just make the view draw rotated but it will still receive the touch events in its old area. You have to manually apply rotation matrix to the touch event coordinates in order to offset them to the proper location.