I am starting to play around with Property Animations over view animations as I have a view that needs to scale and push others out of the way as it does. I've seen some examples but I'm just wondering if there is anywhere that provides a list of the properties that can be altered using these classes. For example, I saw one tutorial that did a quick rotation using:
ObjectAnimator.ofFloat(aniView, "rotation", 360)
Which is quite cool, but I wouldn't have known the rotation property if not for that exact tutorial, is there any comprehensive list of what can be done? The particular property I want to animate is the weight of a view within a LinearLayout, if anyone has any advice on that specifically.
Better late than never, so here is the comprehensive list of the properties that can be animated with ObjectAnimator.
http://developer.android.com/guide/topics/graphics/prop-animation.html#views
The Docs imply that any value can be used with ObjectAnimator as long as you follow a naming convention:
The object property that you are animating must have a setter function (in camel case) in the form of set<propertyName>(). Because
the ObjectAnimator automatically updates the property during
animation, it must be able to access the property with this setter
method. For example, if the property name is foo, you need to have a
setFoo() method. If this setter method does not exist, you have three
options:
Add the setter method to the class if you have the rights to
do so.
Use a wrapper class that you have rights to change and have
that wrapper receive the value with a valid setter method and forward
it to the original object.
Use ValueAnimator instead.
[...]
With respect to your question, View has the method setRotation(float) -- that gives you a hint it can be used. In particular here's how you would do it with a particular TimeInterpolator:
ObjectAnimator anim = ObjectAnimator.ofFloat(myView, "rotation", 0f, 90f);
anim.setDuration(2000); // Duration in milliseconds
anim.setInterpolator(timeInterpolator); // E.g. Linear, Accelerate, Decelerate
anim.start() // Begin the animation
You can read the docs for more details on the expectations of ObjectAnimator.
Here is the comprehensive list of property names that you are looking for:
rotation
rotationX
rotationY
translationX
translationY
scaleX
scaleY
pivotX
pivotY
alpha
x
y
Source: Docs
Use "translateX" or "transalteY" to move a <group>
Take a look at vectorDrawable
You can check it at the View.java file in Properties block. Now it starts with the line of:
public static final Property<View, Float> ALPHA = new FloatProperty<View>("alpha")
Related
I have to do this in xml of an item of a recycler view (I'm using databinding and the viewholder pattern). Based on the value of the variable that is bound to the view, I need to rotate a drawable and set it as the src of an ImageView.
I've checked many options online but haven't found any, rotating the original xml drawable 45 degrees cuts of some parts of the shape which is a curved rectangle. This results in a shape that does not match the requirements.
I need suggestions on how to get this done from inside the xml or adapter without rewriting it to use getView.
Hello #staa99 try following code may it will help you.
ImageView imageView = findViewById(R.id.imageView);
RotateAnimation anim = new RotateAnimation(0, 45,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
anim.setInterpolator(new LinearInterpolator());
anim.setDuration(1000);
anim.setFillEnabled(true);
anim.setFillAfter(true);
imageView.startAnimation(anim);
The solution I eventually used was to create four different vector variables based of the original with rotation info included. I then used a variable bound to the view to store the data that determines the vector drawable to display.
This solution is not good when you need a large or unknown number of possible rotations, or if the angles are calculated at runtime. However, I've not seen a way to do that from xml so you still need to do it from java/kotlin code
I can not to set alpha parameter for my GlSurfaceView. XML-attribute android:alpha= not working, call of method from code mView.setAlpha() too not working. I read about a similar problem, for example, - how to make a transparent background on this View, but unfortunately solution did not help to solve my problem - to set alpha channel the contains of GlSurfaceView. I tried to move GlSurfaceView inside FrameLayout and yet to set alpha of FrameLayout, but this solution did not help.
Now i am still see only a one variant - to move a sample View above GlSurfaceView and to set a transparent of a sample View. This solution to be last case for me!
I want to ask - Is there any way to solve this problem differently?
The problem is solved!
Only one variant is correct - to set parametr 'alpha' in 'gl_FragColor' of your shader! For example: gl_FragColor.a=0.5;
That to have acces to your shader from code - need to make parameter alpha in shader as global ('uniform' type), and to link him across methods 'glGetUniformLocation', 'glUniform1f'. For example:
// View-code
int mAlpha;
float alpha = 0.5f;
mAlpha = GLES20.glGetUniformLocation(mProgrammerHandle, "u_alpha");
GLES20.glUniform1f(mAlpha, alpha);
// Shader-code
...
uniform float u_alpha;
...
gl_FragColor = vec4(rgb,u_alpha);
But that is not all!
Need to set parameters GlSurfaceView and Render. After initialization GlSurfaceView should be allowed a transparent Drawing:
setEGLConfigChooser(8, 8, 8, 8, 16, 0);
getHolder().setFormat(PixelFormat.RGBA_8888);
In render object too must to set a transparent color cleaning and correct color mixing.
GLES20.glClearColor ( 0.0f, 0.0f, 0.0f, 0.0f );
GLES20.glEnable(GL_BLEND);
Color mixing can be different. Default - colors mix i.e. GLES20.glBlendEquation(GL_FUNC_ADD); - not necessary write.
But there are other options of mixing:
GL_FUNC_SUBTRACT
GL_FUNC_REVERSE_SUBTRACT
I was not write 'glBlendEquation' in my code.
Next important moment - alpha mixing. Method 'glBlendFunc' or 'glBlendFuncSeparate'. More information you can read in OpenGL tutorial. For correct alpha mixing i took advantage of more detailed setup:
GLES20.glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO);
The last thing to do - overriding methods 'setAlpa' and 'getAlpa' in your GlSurfaceView.
P.S. If in your View a transparent artifact appear, then you may tried to set parameters setZOrderOnTop(true); and/or android:windowIsTranslucent="true" inside XML. But for me it was not required - everything works fine!
I'm trying to move a view to the upper right corner of the screen, using ObjectAnimator.ofFloat(...) But, I'm not getting the results I expect. I'm getting the coordinates of the view beforehand, using ViewTreeListener, etc, and I already know the x value I need to offset from the end of the overall width. I can't get either dimension to move to where I want it. Relevant code:
Getting the starting coordinate; where the view currently is:
int[] userCoords = new int[]{0,0};
userControlLayout.getLocationInWindow(userCoords);
//also tried getLocationInScreen(userCoords); same result
userUpLeft = userCoords[0];
userUpTop = userCoords[1];
Surprisingly, I get the same value as userUpLeft (which is in screen coordinates, and not relative to parent) when I call userControlLayout.getLeft() I'd expect them to be different per my understanding of the docs. Anyway...
Constructing the ObjectAnimators:
//testXTranslate is a magic number of 390 that works; arrived at by trial. no idea why that
// value puts the view where I want it; can't find any correlation between the dimension
// and measurements I've got
ObjectAnimator translateX = ObjectAnimator.ofFloat(userControlLayout, "translationX",
testXTranslate);
//again, using another magic number of -410f puts me at the Y I want, but again, no idea //why; currently trying the two argument call, which I understand is from...to
//if userUpTop was derived using screen coordinates, then isn't it logical to assume that -//userUpTop would result in moving to Y 0, which is what I want? Doesn't happen
ObjectAnimator translateY = ObjectAnimator.ofFloat(userControlLayout, "translationY",
userUpTop, -(userUpTop));
My understanding is that the one arg call is equivalent to specifying the end coordinate you want to translate/move to, and the two arg version is starting at...ending at, or, from...to I've messed around with both and can't get there.
Clearly, I'm missing very fundamental knowledge, just trying to figure out what exactly that is. Any guidance much appreciated. Thanks.
First, userControlLayout.getLeft() is relative to the parent view. If this parent is aligned to the left edge of the screen, those values will match. For getTop() it's generally different simply because getLocationInWindow() returns absolute coordinates, which means that y = 0 is the very top left of the window -- i.e. behind the action bar.
Generally you want to translate the control relative to its parent (since it won't even be drawn if it moves outside those bounds). So supposing you want to position the control at (targetX, targetY), you should use:
int deltaX = targetX - button.getLeft();
int deltaY = targetY - button.getTop();
ObjectAnimator translateX = ObjectAnimator.ofFloat(button, "translationX", deltaX);
ObjectAnimator translateY = ObjectAnimator.ofFloat(button, "translationY", deltaY);
When you supply multiple values to an ObjectAnimator, you're indicating intermediate values in the animation. So in your case userUpTop, -userUpTop would cause the translation to go down first and then up. Remember that translation (as well as rotation and all the other transformations) is always relative to the original position.
I have an image, which I have already clipped in circle. I want this image to animate over an oval path within angle 20 to 135.
I have searched a lott but i dint get exact answer.
Any help will be greatly appreciated?
This animation can be achieved using the Android Accelerometer and the Sensor Manager class.
Refer to this link. It has 3 different detailed sample codes.
Moving an image using Accelerometer of android
Hope it helps.
Check this out, I was able to move an image on a path.
You can simply define path
AnimatorPath path = new AnimatorPath();
path.moveTo(0, 0);
path.lineTo(0, 300);
path.curveTo(100, 0, 300, 900, 400, 500);
public static ObjectAnimator ofObject (Object target, String propertyName, TypeEvaluator evaluator, Object... values)
Constructs and returns an ObjectAnimator that animates between Object values. A single value implies that that value is the one being animated to. Two values imply a starting and ending values. More than two values imply a starting value, values to animate through along the way, and an ending value (these values will be distributed evenly across the duration of the animation).
Parameters
target: The object whose property is to be animated. This object should have a public method on it called setName(), where name is the value of the propertyName parameter.
propertyName: The name of the property being animated.
evaluator: A TypeEvaluator that will be called on each animation frame to provide the necessary interpolation between the Object values to derive the animated value.
values: A set of values that the animation will animate between over time.
Returns
An ObjectAnimator object that is set up to animate between the given values.
For more reference you may check here.
I'd like to create an indeterminate animation that simply fades from one color to another (a pulse, if you will). I don't think this should require the use of images but despite my best efforts, I'm not sure I understand how to use something like AlphaAnimation with a Shape to accomplish this.
Could someone please provide some insight as to how to accomplish this? I have a feeling I'm missing something pretty straightforward here. (Examples are always appreciated!)
Thanks!
This is a trivial task in 3.0 - you can set up an ObjectAnimator to change the "color" or "backgroundColor" of an object (View, ColorDrawable, whatever has the property) between two values. See the ApiDemo animations/BouncingBalls for an example of this.
But assuming you're using pre-3.0 APIs, there are a couple of approaches. First, you could set up your own handler to give you the timing events you need, then calculate the new color at each point.
It's probably slightly easier (if not entirely intuitive) to use an AlphaAnimation. All you really want from the animation is percentage values, not to fade anything. So you don't set the animation on a view, but just set it up to run internally from a value of 0 to 1, then get the current animated value in your onDraw() method and set the current color appropriately.
For example, this will set up and start the alpha animation to run for one second:
Transformation transform = new Transformation();
AlphaAnimation anim = new AlphaAnimation(0f, 1f);
anim.setDuration(1000);
anim.start();
Then in your drawing loop, you grab the current animated value:
long time = getDrawingTime();
anim.getTransformation(time, transform);
float elapsedFraction = transform.getAlpha();
Once you have the elapsedFraction (a value between 0 and 1), you can calculate the appropriate in-between color value.
The code above may not match your situation exactly, but you should be able to do something similar to get what you want.