Check attached image for easy explanation.
Translate animation works but it animates inside the same view.
I want view to fly out from one layout to other.
I tried this from another answer here. (Animates in same layout)
public class Animations {
public Animation fromAtoB(float fromX, float fromY, float toX, float toY, int speed){
Animation fromAtoB = new TranslateAnimation(
Animation.ABSOLUTE, //from xType
fromX,
Animation.ABSOLUTE, //to xType
toX,
Animation.ABSOLUTE, //from yType
fromY,
Animation.ABSOLUTE, //to yType
toY
);
fromAtoB.setDuration(speed);
fromAtoB.setInterpolator(new AnticipateOvershootInterpolator(1.0f));
return fromAtoB;
}
I recently did animation of a similar kind using Animators. In general, views will not display themselves outside of their parents' boundaries, the view will be cut by it's parent's boundaries. That's why, the trick is to place a new view (shuttleView) on top of the origin view (fromView) that you want to animate, align them, and animate scaling/translation of shuttleView into a target view (toView).
This solution supports both scaling and translation, here is sample: https://www.dropbox.com/s/iom95o93076h52f/device-2016-06-03-111557.mp4?dl=0
Here is the code:
activity_main.xml
<LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_alignParentTop="true"
android:background="#android:color/holo_blue_dark">
<TextView
android:id="#+id/itemTo"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_margin="10dp"
android:background="#android:color/holo_blue_bright"
android:text="to"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="90dp"
android:layout_alignParentBottom="true"
android:background="#android:color/holo_blue_dark">
<TextView
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#android:color/holo_blue_bright" />
<TextView
android:id="#+id/itemFrom"
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:text="from"
android:background="#android:color/holo_blue_bright" />
<TextView
android:layout_width="90dp"
android:layout_height="match_parent"
android:layout_margin="10dp"
android:background="#android:color/holo_blue_bright" />
</LinearLayout>
<View
android:id="#+id/shuttle"
android:layout_width="0dp"
android:layout_height="0dp"
android:background="#android:color/holo_blue_bright"/>
Activity class:
public class MainActivity extends AppCompatActivity {
public static final int ANIMATION_SPEED = 3000;
private RelativeLayout rootView;
private View fromView, toView, shuttleView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootView = (RelativeLayout) findViewById(R.id.rootView);
fromView = findViewById(R.id.itemFrom);
toView = findViewById(R.id.itemTo);
shuttleView = findViewById(R.id.shuttle);
fromView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Rect fromRect = new Rect();
Rect toRect = new Rect();
fromView.getGlobalVisibleRect(fromRect);
toView.getGlobalVisibleRect(toRect);
AnimatorSet animatorSet = getViewToViewScalingAnimator(rootView, shuttleView, fromRect, toRect, ANIMATION_SPEED, 0);
animatorSet.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
shuttleView.setVisibility(View.VISIBLE);
fromView.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
shuttleView.setVisibility(View.GONE);
fromView.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorSet.start();
}
});
}
public static AnimatorSet getViewToViewScalingAnimator(final RelativeLayout parentView,
final View viewToAnimate,
final Rect fromViewRect,
final Rect toViewRect,
final long duration,
final long startDelay) {
// get all coordinates at once
final Rect parentViewRect = new Rect(), viewToAnimateRect = new Rect();
parentView.getGlobalVisibleRect(parentViewRect);
viewToAnimate.getGlobalVisibleRect(viewToAnimateRect);
viewToAnimate.setScaleX(1f);
viewToAnimate.setScaleY(1f);
// rescaling of the object on X-axis
final ValueAnimator valueAnimatorWidth = ValueAnimator.ofInt(fromViewRect.width(), toViewRect.width());
valueAnimatorWidth.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
// Get animated width value update
int newWidth = (int) valueAnimatorWidth.getAnimatedValue();
// Get and update LayoutParams of the animated view
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
lp.width = newWidth;
viewToAnimate.setLayoutParams(lp);
}
});
// rescaling of the object on Y-axis
final ValueAnimator valueAnimatorHeight = ValueAnimator.ofInt(fromViewRect.height(), toViewRect.height());
valueAnimatorHeight.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
// Get animated width value update
int newHeight = (int) valueAnimatorHeight.getAnimatedValue();
// Get and update LayoutParams of the animated view
RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) viewToAnimate.getLayoutParams();
lp.height = newHeight;
viewToAnimate.setLayoutParams(lp);
}
});
// moving of the object on X-axis
ObjectAnimator translateAnimatorX = ObjectAnimator.ofFloat(viewToAnimate, "X", fromViewRect.left - parentViewRect.left, toViewRect.left - parentViewRect.left);
// moving of the object on Y-axis
ObjectAnimator translateAnimatorY = ObjectAnimator.ofFloat(viewToAnimate, "Y", fromViewRect.top - parentViewRect.top, toViewRect.top - parentViewRect.top);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setInterpolator(new DecelerateInterpolator(1f));
animatorSet.setDuration(duration); // can be decoupled for each animator separately
animatorSet.setStartDelay(startDelay); // can be decoupled for each animator separately
animatorSet.playTogether(valueAnimatorWidth, valueAnimatorHeight, translateAnimatorX, translateAnimatorY);
return animatorSet;
}
}
You can do a whole bunch of customizations in terms of what appears and disappears at different stages of animation in animatorSet listener. Hope it's helpful.
If someone is looking for simpler solution, you can use transitions framework:
https://developer.android.com/training/transitions/index.html
To animate translation from one parent view to another, there is special transition ChangeTransform:
https://developer.android.com/reference/android/transition/ChangeTransform.html
And a small example:
animatedView = View.inflate(ActivityMain.this, R.layout.item, firstParent);
animatedView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
Transition move = new ChangeTransform()
.addTarget(animatedView)
.setDuration(2000));
TransitionManager.beginDelayedTransition(rootParent, move);
firstParent.removeView(animatedView);
animatedView.setPadding(2,2,2,2);
animatedView.setElevation(4);
secondParent.addView(animatedView, 0);
Related
I made a little method to translate a view above another view and scale to that view's size.
Method works, but it translate the view with a margin.
This is the method:
public AnimationSet getFromToAnimation(View from, View to, final Runnable onEnd){
AnimationSet animationSet = new AnimationSet(true);
animationSet.setInterpolator(new AccelerateDecelerateInterpolator());
animationSet.setFillEnabled(true);
animationSet.setDuration(3000);
LinearLayout.LayoutParams fromParams = (LinearLayout.LayoutParams) from.getLayoutParams();
LinearLayout.LayoutParams toParams = (LinearLayout.LayoutParams) to.getLayoutParams();
float tx = (to.getX() + toParams.leftMargin) - (from.getX() + fromParams.leftMargin);
float ty = (to.getY() + toParams.topMargin) - (from.getY() + fromParams.topMargin);
TranslateAnimation translateAnimation = new TranslateAnimation(0, tx,0, ty);
float x = (float) to.getWidth() / (float) from.getWidth();
float y = (float) to.getHeight() / (float) from.getHeight();
ScaleAnimation scaleAnimation = new ScaleAnimation(1f, x, 1f, y,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);
animationSet.addAnimation(translateAnimation);
animationSet.addAnimation(scaleAnimation);
animationSet.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
onEnd.run();
}
#Override
public void onAnimationRepeat(Animation animation) {}
});
return animationSet;
}
Then I use it like this
LinearLayout lnrFrom = findViewById(R.id.lnr_game_operation);
LinearLayout lnrTo = findViewById(R.id.lnr_game_operation_old);
AnimationSet animation = getFromToAnimation(lnrFrom, lnrTo, new Runnable() {
#Override
public void run() {
...
}
});
lnrFrom.startAnimation(animation);
And this is xml with many layouts, which I need to start the animation
<LinearLayout
android:gravity="center"
android:orientation="vertical"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/lnr_game_operation_old"
android:background="#drawable/operation"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="#dimen/dp100"
android:layout_height="#dimen/dp60">...</LinearLayout>
<LinearLayout
android:id="#+id/lnr_game_operation"
android:background="#drawable/operation"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="#dimen/dp120"
android:layout_height="#dimen/dp70">...</LinearLayout>
<LinearLayout
android:id="#+id/lnr_game_operation_new"
android:visibility="invisible"
android:background="#drawable/operation"
android:gravity="center"
android:orientation="horizontal"
android:layout_width="#dimen/dp100"
android:layout_height="#dimen/dp60">...</LinearLayout>
</LinearLayout>
Does anyone know another method to do this or why it doesn't work?
I would like to expand/collapse an ImageView but start from 50% picture to expand at 100%, collapse to 50% not under.
I already took a look at some popular questions and answers on SO but I didn't find how to manage only half. I also want to modify on the height of view, not the width.
What I tried :
public static void expand(final View v) {
v.measure(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int targtetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? ViewGroup.LayoutParams.WRAP_CONTENT
: (int)(targtetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int)(targtetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if (interpolatedTime == 1) {
v.setVisibility(View.VISIBLE);
} else {
v.getLayoutParams().height = initialHeight - (int) (initialHeight * interpolatedTime);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
as I said it's not what I want because it make disappeared totally and it change the width.
I also tried this snippet but there is no animation :
mImageDrawable = (ClipDrawable) pic.getDrawable();
mImageDrawable.setLevel(5000);//use set level to expand or collapse manually but no animation.
clip:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:drawable="#drawable/test_pic"
android:gravity="top" />
Use Transition API which is available in support package (androidx). Just call TransitionManager.beginDelayedTransition then change height of view. TransitionManager will handle this changes and it will provide transition which will change imageView with animation.
scaleType of ImageView here is centerCrop thats why image scales when collapse and expand. Unfortunetly there is no "fill width and crop bottom" scaleType, so if you need it I think it can be done throught scaleType = matrix .
import androidx.appcompat.app.AppCompatActivity;
import androidx.transition.TransitionManager;
public class MainActivity extends AppCompatActivity {
private ImageView image;
private ViewGroup parent;
boolean collapse = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
image = findViewById(R.id.image);
parent = findViewById(R.id.parent);
findViewById(R.id.btn).setOnClickListener(view -> {
collapse = !collapse;
collapse();
});
}
private void collapse() {
TransitionManager.beginDelayedTransition(parent);
//change layout params
int height = image.getHeight();
LayoutParams layoutParams = image.getLayoutParams();
layoutParams.height = !collapse ? height / 2 : height * 2;
image.requestLayout();
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="#+id/btn"
android:text="start"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="300dp"
android:scaleType="centerCrop"
android:src="#drawable/qwe" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="random text"
android:layout_margin="8dp"/>
</LinearLayout>
UPDATE:
There is beginDelayedTransition(ViewGroup, Transtion) method. beginDelayedTransition(ViewGroup) by default use AutoTransition as transition.
So if you need handle start/end of transition you can do it like this:
AutoTransition transition = new AutoTransition();
transition.addListener(new TransitionListenerAdapter(){
#Override
public void onTransitionStart(#NonNull Transition transition) {
//TODO
}
#Override
public void onTransitionEnd(#NonNull Transition transition) {
//TODO
}
});
TransitionManager.beginDelayedTransition(parent, transition);
I want to create custom Transition for the Scale View elements in the ConstraintLayout. Inside the AutoTransition.java. We have Fade In, AdjustBounds and Fade Out. So performing simple Scale doesn't animate changes.
After some workaround I was able to Create custom Transition with Scale. And my point, it's to create Transition Set with Visiblity and Scale. With changes below this animation works well, despite Scale Pivot.
//..................... General method from Custom Scale Transition
#Nullable
#Override
public Animator createAnimator(#NonNull ViewGroup sceneRoot, #Nullable TransitionValues startValues,
#Nullable TransitionValues endValues) {
if (null == startValues || null == endValues) {
return null;
}
final View view = endValues.view;
final float startX = (float) startValues.values.get(PROPNAME_SCALE_X);
final float endX = (float) endValues.values.get(PROPNAME_SCALE_X);
final float startY = (float) startValues.values.get(PROPNAME_SCALE_Y);
final float endY = (float) endValues.values.get(PROPNAME_SCALE_Y);
final AnimatorSet set = new AnimatorSet();
final ValueAnimator animatorX = ValueAnimator.ofFloat(startX, endX);
animatorX.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
final float value = (float) animation.getAnimatedValue();
view.setScaleX(value);
}
});
final ValueAnimator animatorY = ValueAnimator.ofFloat(startY, endY);
animatorY.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
final float value = (float) animation.getAnimatedValue();
view.setScaleY(value);
}
});
set.playTogether(animatorX, animatorY);
return set;
}
//..................... Complete Set Transitions
public class ScaleVisibility extends TransitionSet {
public ScaleVisibility() {
setOrdering(ORDERING_TOGETHER);
addTransition(new Fade()).
addTransition(new Scale());
}
}
//..................... Code for starting Animation.
mConstraintSet.clone(mConstraintLayout);
Transition transition = new ScaleVisibility();
transition.setDuration(3000);
mConstraintSet.setScaleX(item.resource, item.scale);
mConstraintSet.setScaleY(item.resource, item.scale);
mConstraintSet.setTransformPivot(item.resource, 0.5f, 0.5f);
mConstraintSet.setVisibility(item.resource, item.visibility);
TransitionManager.beginDelayedTransition(mConstraintLayout, transition);
mConstraintSet.applyTo(mConstraintLayout);
//..................... Main XML. Trying to Animate input_send_button
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_input_panel"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<View
android:id="#+id/input_background"
android:layout_width="match_parent"
android:layout_height="#dimen/chat_input_panel_height"
android:background="#color/white"
app:layout_constraintBottom_toBottomOf="parent"/>
<!--This View will change Visibility with Text Changes-->
<ImageButton
android:id="#+id/input_send_button"
android:layout_width="#dimen/chat_input_panel_height"
android:layout_height="0dp"
android:background="#android:color/transparent"
android:src="#drawable/chat_send"
android:tint="#color/primary"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="#+id/input_background"
app:layout_constraintRight_toRightOf="#+id/input_background"
app:layout_constraintTop_toTopOf="#+id/input_background"
tools:ignore="ContentDescription"
tools:visibility="visible"/>
</android.support.constraint.ConstraintLayout>
Main issue here, it's Scale animation Pivot, which is zero (top left corner of view). And I cannot change Transition pivot for Animated view. Neither with adding this property to the View.java nor ConstraintSet.javaparameters. So question it's how to change View Pivot for this Scale Transition. (As additional question, I was interested with changing Pivot for the default AdjustBounds Transition, where we changing view Height/Width).
Try resetting the pivot on each animation step. If you're looking for center pivot you can just slash through getWidth(), otherwise you need to capture another pivot value and use it.
Try this transition:
public class ScaleTransition extends Transition {
private final static String PROPNAME_SCALE_X = "PROPNAME_SCALE_X";
private final static String PROPNAME_SCALE_Y = "PROPNAME_SCALE_Y";
#Override
public void captureStartValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
#Override
public void captureEndValues(TransitionValues transitionValues) {
captureValues(transitionValues);
}
private void captureValues(TransitionValues values){
values.values.put(PROPNAME_SCALE_X, values.view.getScaleX());
values.values.put(PROPNAME_SCALE_Y, values.view.getScaleY());
}
#Override
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
if(endValues == null || startValues == null)
return null; // no values
float startX = (float) startValues.values.get(PROPNAME_SCALE_X);
float startY = (float) startValues.values.get(PROPNAME_SCALE_Y);
float endX = (float) endValues.values.get(PROPNAME_SCALE_X);
float endY = (float) endValues.values.get(PROPNAME_SCALE_Y);
if(startX == endX && startY == endY)
return null; // no scale to run
final View view = startValues.view;
PropertyValuesHolder propX = PropertyValuesHolder.ofFloat(PROPNAME_SCALE_X, startX, endX);
PropertyValuesHolder propY = PropertyValuesHolder.ofFloat(PROPNAME_SCALE_Y, startY, endY);
ValueAnimator valAnim = ValueAnimator.ofPropertyValuesHolder(propX, propY);
valAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
view.setPivotX(view.getWidth()/2f);
view.setPivotY(view.getHeight()/2f);
view.setScaleX((float) valueAnimator.getAnimatedValue(PROPNAME_SCALE_X));
view.setScaleY((float) valueAnimator.getAnimatedValue(PROPNAME_SCALE_Y));
}
});
return valAnim;
}
}
In order to create a custom transition(s) for TransitionManager you need to create a custom Transition or TransitionSet. For example:
TransitionSet transitionSet = new TransitionSet();
//your types of transitions
Transition first = new ChangeBounds();
Transition second = new Fade();
first.addTarget(firstView);
second.addTarget(secondView);
//Add your transitions to TransitionSet
transitionSet.addTransition(first).addTransition(second);
//Start transitions
TransitionManager.beginDelayedTransition(layout, transitionSet);
You can learn more about TransitionSet here and about Transition here
ObjectAnimator.ofFloat(Object target, String xPropertyName, String yPropertyName, Path path) seems to work in API 21 but not 23?
Simple reproduction: Here's the activity and layout. Try long press on the text view, both level will work. But, just tap on the view: 21 works but not 23.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View hello = findViewById(R.id.hello);
final Path p = new Path();
p.addCircle(-200, 0, 100, Path.Direction.CW);
hello.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ObjectAnimator a = ObjectAnimator.ofFloat(hello, "translationX", "translationY", p);
a.setDuration(1000);
a.start();
}
});
hello.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
ObjectAnimator a = ObjectAnimator.ofFloat(hello, "scaleX", 2);
a.setDuration(1000);
a.start();
return true;
}
});
}
}
--
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="letstwinkle.com.pathtest.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:layout_marginEnd="63dp"
android:layout_marginTop="210dp"
android:id="#+id/hello"
android:background="#880033"/>
</RelativeLayout>
This may be the same as this bug reported in June. https://code.google.com/p/android/issues/detail?id=212776
As a workaround, you can use a ValueAnimator with a custom AnimatorUpdateListener.
First you need a PathMeasure for your Path. This will give you access to data like path length and coordinates on the path for a specific distance (0 <= distance <= path length).
Path p = new Path();
p.addCircle(-200, 0, 100, Path.Direction.CW);
PathMeasure pathMeasure = new PathMeasure(p, true);
Then you set the ValueAnimator to animate from 0 to the path length.
final ValueAnimator a = ValueAnimator.ofFloat(0,pathMeasure.getLength());
a.setDuration(1000);
Next, you add an AnimatorUpdateListener to actually manipulate the View. I'll show first how to add it:
MyAnimatorUpdateListener myListener = new MyAnimatorUpdateListener(hello, pathMeasure);
a.addUpdateListener(myListener);
Continue with the OnClickListener:
hello.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
a.start();
}
});
Please note that I changed the code and declared/ initialized the ValueAnimator outside of the OnClickListener to get a better performance: this way, it will not be newly created each time I click the TextView and so the garbage collector will be less busy :).
Finally, the AnimatorUpdateListener code:
class MyAnimatorUpdateListener implements ValueAnimator.AnimatorUpdateListener
{
private View view;
private PathMeasure pathMeasure;
private float[] coordinates = new float[2];
public MyAnimatorUpdateListener(View view, PathMeasure pathMeasure)
{
this.view = view;
this.pathMeasure = pathMeasure;
}
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float distance = (float) animation.getAnimatedValue();
pathMeasure.getPosTan(distance, coordinates, null);
view.setTranslationX(coordinates[0]);
view.setTranslationY(coordinates[1]);
}
}
Good day i have a view that is programmatically placed at the bottom left part of a SurfaceView and what i want is when a button is clicked, the view slides out of the screen and slides back in but nothing seems to happen in the animation. Here is my code, i will just put the relevant parts:
layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_Info"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#6444"
android:orientation="vertical"
android:visibility="visible" >
<TextView
android:id="#+id/name_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="name" />
<TextView
android:id="#+id/medium_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="med"/>
<TextView
android:id="#+id/dimensions_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:text="dimen" />
</LinearLayout>
positioning the view:
RelativeLayout.param = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 240);
param.leftMargin = 0;
inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.my_info, null);
mylayout = (LinearLayout)view.findViewById(R.id.gallery_Info_root_id); //what i want to animate
view.setLayoutParams(param);
param.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
param.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
view.getLayoutParams().width = 380;
RelativeLayout lContainerLayout = new RelativeLayout(VideoPlayback.this);
lContainerLayout.setLayoutParams(new RelativeLayout.LayoutParams( LayoutParams.MATCH_PARENT , LayoutParams.MATCH_PARENT ));
lContainerLayout.addView(view);
addContentView(lContainerLayout, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
slide in and slide out animation:
private void slideInView(){
Animation slidein = new MyTranslateAnimation(mylayout, -mylayout.getWidth(), 0, 0, 0);
slidein.setDuration(animationDuration);
slidein.setInterpolator(interpolator);
mylayout.startAnimation(slidein);
}
private void slideOutView(){
Animation slidein = new MyTranslateAnimation(mylayout, 0, -mylayout.getWidth(), 0, 0);
slidein.setDuration(animationDuration);
slidein.setInterpolator(interpolator);
mylayout.startAnimation(slidein);
}
MyTranslateAnimation which i got from here
public class MyTranslateAnimation extends Animation {
private View view;
private final float fromX;
private final float toX;
private final float fromY;
private final float toY;
public MyTranslateAnimation(View v, float fromX, float toX, float fromY, float toY) {
view = v;
this.fromX = fromX;
this.toX = toX;
this.fromY = fromY;
this.toY = toY;
setDuration(500);
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
float x = (toX-fromX) * interpolatedTime + fromX;
float y = (toY - fromY) * interpolatedTime + fromY;
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams)view.getLayoutParams();
params.setMargins((int)x, (int)y, 0, 0);
view.requestLayout();
}
}
Please can anyone spot anything i am doing wrong? because i can't seem to see why i can't slide "mylayout" in and out. Thanks in advance.