Edit: see my own answer, I have added more detail as I have managed to get an animation working through XMLs, I cannot see why the code I have isn't doing the same thing.
I'm trying in Xamarin Android (not Forms) to display a couple of Vector Drawables and have one of the rotate on the other. The idea is a timer, a single hand going around a clock. I'm after the hand to appear to do a couple of full rotations then stop at a random angle. So it could stop at say 3 o'clock or 10 o'clock when it is done rotating.
I would have thought what I am trying to do would be done programmatically rather than via XMLs however I cannot find any good information to start me off on this. I'm not that familiar with base Android (I'm quite familiar with Xamarin Forms).
I can get both the face and the hand to display in an ImageView control. This I have done with both a layer-list.xml and a LayerDrawable. I have tried creating a RotateDrawable from the hand with a fromRotation and a toRotation set then applying that to LayerDrawbale. It does draw but not rotated.
The same applies in the layer-list xml, both draw, the hand is without rotation.
I have tried searching here and google, I cannot find anything solid so far to get me started. just snippets of XMLs. I feel I'm missing something very fundamental.
Any help is massively apricated.
This is the xml for the layerlist
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
>
<item
android:drawable="#drawable/Clock"/>
<item>
<rotate
android:drawable="#drawable/Needle"
android:pivotX="50%"
android:pivotY="1%"
android:fromDegrees="0"
android:toDegrees="1080"
/>
</item>
</layer-list>
The code for the setting the layer-list to a Imageview.
ImageView clockDisplay = FindViewById<ImageView>(Resource.Id.ThreePlayers);
Drawable clock = VectorDrawableCompat.Create(Resources, Resource.Drawable.Clock, null);
clockDisplay.SetImageDrawable(clock);
/*
I have also used the following to no avail.
RotateDrawable clockRotate = new RotateDrawable();
clockRotate.Drawable = needle;
clockRotate.FromDegrees = 180;
clockRotate.ToDegrees = 180;
clockDisplay.SetImageDrawable(clockRotate);
*/
Cheers
Andy.
Edit: I've changed this answer completely from what it was.
from the suggestions in the comments of the main post, I have got the rotation working by rotating the image view.
I have created a test program here
that animates an ImageView with an AnimationSet and OhectAnimator, one using a Spring Animator and one that attempts to Animate the VectorDrawable directly in C#
The 1st two work as expected and is good enough for the project I am working on as all I need is rotation.
However is it not possible to Animate a VectorDrawable in C# without having animate the ImageView control?
If I creating a static animation in XMLs I could manipulate different layers of the VectorDrawable and Animate them Separately, surely this is possible to do in C#?
I'm starting to think it is not possible to do programmatically.|
Any advice?
Thanks.
Andy.
Related
I understand how to create gradients using start color, end color, etc like below:-
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient
android:type="radial" android:gradientRadius="260"
android:startColor="#A74171" android:endColor="#690136"/>
</shape>
But I dont understand how to bring about more complex effects. For Eg:- I am faced with a task of making a textview look like a button where it will look a little raised at the center, something like the image attached .
How can such an effect be brought by code without using images?
Here's the good news: Something like the button, shown in the picture, already exists. Maybe in other colors, but with a little painting you should get there easily. Check out the design downloads
When there're good news, than there might be some news with - lets say - more work involved. This link to Drawable Resource gives you an overview of what is possible with XML.
When you get out of XML possibilities, you must create your own Drawable, which is described here which is extremely powerful.
You can always paint your own drawings, load them as bitmap and use them. There you must be very sensitive on the size of the bitmap and the good looking (painted with enough pixels). I mysef have not found the right mix up to now.
All in all, in my experience, even the most complex XML drawables are quite efficient, whereas my own Drawables, painted at runtime are always a cause for lagging on the UI-Thread.
I would like to have a pattern along the edge of a view. For this particular case, I would like it to be a jagged edge (like tearing parchment paper or tinfoil out of a roll). I would prefer a more general solution - perhaps at some point I would like waves along the top of a view, or a binder coil down the side. I would prefer to have some kind of repeating image rather than stretching an image.
Edit:
I would like a the pattern to occur just around the edge of the view (perhaps only on one edge). For example, a tear mark on the bottom or top of a receipt. The tear should not repeat up or down the image, just at the bottom edge.
Create a drawable (pattern_tile.xml) with the root element of a <bitmap>. Like this for instance:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:dither="true"
android:src="#drawable/bgnoise_lg"
android:tileMode="repeat" >
</bitmap>
And the drawable image used in the code above is:
Then, in your XML, you set it like you set the usual background using this attribute:
android:background="#drawable/pattern_tile"
Oh. Almost forgot, I put these two files, in the drawable-nodpi folder. I don't want Android to ever scale the image for me.
Obviously, since your question is a little vague, you will have to use your own image instead of the example I have posted, play around with it a bit till you get the result that suits your needs.
NOTE: Such a thing is typically done when you have patterns that should repeat instead of filling up the screen or stretching. So make sure the image you use is such a pattern that can repeat and not look out of place.
I have a problem with a custom XML drawable that I have rotated by 135 degrees.
The drawable is used as the thumb in a SeekBar layout component.
This works fine on Android 4, but on Android 2.x, the thumb heads off at a 135 degree angle, instead of following the SeekBar orientation. Here is the drawable that I am setting as the thumb:
<item>
<rotate android:drawable="#drawable/thumb_basic_shape"
android:visible="true"
android:fromDegrees="135"
android:toDegrees="135" />
</item>
I suspect it is related to the way Android 2.x handles references in layered drawables, but is there a way to fix it, preferably in XML?
Here is an image with the red circle indicating where the thumb should be, and the red arrow indicating the direction the thumb is moving in, as I drag the slider.
[EDIT]
The first answer given below states that I need to create a separate persistent rotate animation and apply it to my thumb drawable. There are loads of examples when rotating a View or similar GUI elements, but in this case I want to rotate a drawable that is part of a GUI SeekBar element, and it presents some additional problems.
You can use a persistant rotate animation to do that and have a full 2.x compatibility.
Hope it will be helpful.
I am currently writing an open source project that aims to port the famous Holo theme to previous versions of Android (since 1,6!!!)
Everything works fine and I am really proud of my work, but the problem I am facing now is to get the ProgressBar totally looking like the ICS one.
I used the same xml code than Android source: (progress_medium_holo.xml)
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate
android:drawable="#drawable/spinner_48_outer_holo"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="1080" />
</item>
<item>
<rotate
android:drawable="#drawable/spinner_48_inner_holo"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="720"
android:toDegrees="0" />
</item>
</layer-list>
With same png:
spinner_76_outer_holo.png and spinner_76_inner_holo.png
white pic =>
But unfortunately, I only get one circle...
If you don't understand what I mean, you can try this app on a pre-ICS device:
https://play.google.com/store/apps/details?id=com.WazaBe.HoloDemo
FULL SOURCE IS HERE: https://github.com/ChristopheVersieux/HoloEverywhere
Thank a lot for your help
Just found the answer here!
https://stackoverflow.com/a/8697806/327402
Very usefull post!
There is indeed a platform limitation, although it's not what you might think. The issue is that pre-API11, RotateDrawable had some crude code in it to require that the animation rotate clockwise by checking if toDegrees was greater than fromDegrees; if not, the two were forced equal to each other. If you modified your example to have the second item move in a forward direction (from 0 to 720, or even -720 to 0), both images would animate fine on all platforms; though I realize that defeats the purpose of what you're aiming for.
Take a look at the cached version Google Codesearch has of RotateDrawable.inflate(), which is the 2.3 version of the method used to turn the XML into the object, and you'll see what I mean.
RotateDrawable.java ...the offending code is around line 235...
float fromDegrees = a.getFloat(
com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f);
float toDegrees = a.getFloat(
com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);
toDegrees = Math.max(fromDegrees, toDegrees); //<--There's the culprit
This takes an XML block like the second item that you have there, and turns it into a RotateDrawable that ends up with the same value for fromDegrees and toDegrees (in your case, 720), causing the image to simply stand still. You can visible test this by setting the start value to some value not a multiple of 360 (like 765). You'll see that the image still does not animate, but is rotated to the initial coordinate.
This awkward check was removed in the Honeycomb/ICS sources, which is why you can do backwards rotation on those platforms. Also, it doesn't look like there is a way to set these values from Java code, so a custom RotateDrawableCompat may be in your future :)
HTH
As addendum to Profete162's answer: I know that Jake has managed to bypass this limitation in his implementation for SherlockActionBar and make both the spinning images visible. Looking at the source code for abs__progress_medium_holo.xml it looks like he simply flipped around the fromDegrees and toDegrees values, although there might be more to it that I'm not aware of.
I'm not sure, but I think the <rotate> tag inside a layer-list is simply not compatible with Android 1.6.
By looking in the Donut (1.6) source code I see that the spinner is implemented in this way (progress_medium.xml):
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#drawable/spinner_black_48"
android:pivotX="50%"
android:pivotY="50%"
android:framesCount="12"
android:frameDuration="100" />
You could try that with the Holo drawables.
Hope it helps,
Yuvi
iam stuck with the creation of a nine patch for a progressbar background.
It has a repeating pattern like a ruler-scala and that given me headache.
here is a image of what i want(at the bottom) and what i have (top).
can someone give me a hint how to acomplish my goal?
edit: or is it generelly possible to do this with a 9patch?
my other attempt was to make a with android:tileMode="repeat" but there i get problems with the height of my image (repeating in the second line), i need something like repeat-x.
Thanks in advance
edit2: ok i managed to do my repeating 9patch by stretching the whole repeating pattern, but its not ideal :(
You seem to be overestimating the power of 9-patches. The most you could do is have a ruler image with expanding space between the ticks. You can't, however, make a 9-patch that automatically tiles parts of your image.
On the other hand, if you create a BitmapDrawable programatically, you can set the tile mode separately for the X and Y axes.
I used to do this in my webview project using border image which provides both options (repeat, stretch, fill).
As webview has kind of it's own problems in android (mostly fixed element) I decided to be more android for the next project and I found out that it's not possible to have the repeated border using 9Patch. It's so awkward as it's needy but not implemented.
In a word android development area makes me crazy, one option here one option there is a usual thing here.