16

In my app there is a LinearLayout which has 0 Layout height. When I click the button this layout height should be LayoutParams.WRAP_CONTENT. This is the code I use in onclicklistner.

LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
slider.setLayoutParams(lp);

I want to animate this. How can I set animation to slider.

Gladius
  • 9
  • 4
Chrishan
  • 4,076
  • 7
  • 48
  • 67

5 Answers5

25

I think you just want to animate a view from 0 height to its final height, you can do this with a custom Animation:

public class ShowAnim extends Animation {
    int targetHeight;
    View view;

    public ShowAnim(View view, int targetHeight) {
        this.view = view;
        this.targetHeight = targetHeight;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        view.getLayoutParams().height = (int) (targetHeight * interpolatedTime);
        view.requestLayout();
    }

    @Override
    public void initialize(int width, int height, int parentWidth,
            int parentHeight) {
        super.initialize(width, height, parentWidth, parentHeight);
    }

    @Override
    public boolean willChangeBounds() {
        return true;
    }
}

And do this in your code to start the animation:

Animation ani = new ShowAnim(headerView, 100/* target layout height */);
ani.setDuration(2000/* animation time */);
headerView.startAnimation(ani);
Kai
  • 15,284
  • 6
  • 51
  • 82
  • 2
    How do you do this without it starting at a height of zero every time? If I do this once with a target layout height of 100, and then again with a target layout time of 200, I want it to go from 0 -> 100 and then 100 -> 200. – Andrew Nov 01 '13 at 19:30
  • If you want to go from 100 -> 200, then just modify this line `view.getLayoutParams().height = (int) (targetHeight * interpolatedTime);` to something like `view.getLayoutParams().height = initialHeight /*100 in your case*/ + (int) (targetHeight/*200 in your case*/-initialHeight * interpolatedTime);` – Kai Nov 02 '13 at 01:09
  • 1
    One thing that does not work is nothing happens when the initialHeight is 0. There is no visual change at all. – Andrew Nov 04 '13 at 16:06
  • There is also 1 problem with your previous response. The order-of-operations is incorrect. You must put parenthesis around `targetHeight - initialHeight` so the `* interpolatedTime` is applied after. – Andrew Nov 04 '13 at 16:56
  • 3
    It's just quick psudo code to get things started, please adapt it to your own needs – Kai Nov 05 '13 at 01:37
  • @Andrew I found out that if you want animation to start not from zero you must specify height of params as follwoing: `view.getLayoutParams().height = (originalHeight*2) + (int) (targetHeight * interpolatedTime);`. By `multiply originalHeight with 2` and add it to targetHeight which is multiply with interpolatedTime, it works for me. – Mansour Fahad Jul 22 '14 at 18:09
  • What's the point of overriding `initialize()` if you're just going to pass all the parameters to `super.intialize()`? – Nate Feb 28 '15 at 22:51
  • @Nate in many situations you'd need to do some initialization/calculation in initialize(...) to set up for the coming animation. So while in this particular example no customization is done, the method was overridden so that people know this method exists as a customization point. – Kai Mar 01 '15 at 14:57
  • I had something similar implemented for a sliding animation. This works pretty well until you have another sliding animation nested within. Since the parent doesn't wrap_content then it fails to expand with the child view. – masterwok Nov 22 '16 at 22:22
3

use animateLayoutChanges xml and enableTransitionType in java or kotlin

1. add animateLayoutChanges to root layout xml

    <LinearLayout
        android:id="@+id/mainLinearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="true"
        android:orientation="vertical">

        <android.support.v7.widget.AppCompatEditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="0dp" />
    </LinearLayout>

2. in java

LayoutTransition layoutTransition = mainLinearLayout.layoutTransition;
layoutTransition.setDuration(5000); // Change duration
layoutTransition.enableTransitionType(LayoutTransition.CHANGING);

editText.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; // you can set number, example: 300

editText.requestLayout();

3.in kotlin

 val layoutTransition = mainLinearLayout.layoutTransition
 layoutTransition.setDuration(5000) // Change duration
 layoutTransition.enableTransitionType(LayoutTransition.CHANGING)

 editText.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT // you can set number, example: 300 

 editText.requestLayout()
Rasoul Miri
  • 11,234
  • 1
  • 68
  • 78
1

Since we have the layout transitions in android since JELLYBEAN we can use that instead of using the animation object.

The article below explains it in detail. https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec

In short we would only need this code -

tView.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
tView.setLayoutParams(lp);

Here lp would be the layout params

RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
                            (RelativeLayout.LayoutParams.MATCH_PARENT, newHeight);

One more thing to add would be to add this line in the layout file, to the layout that would be doing the transition.

android:animateLayoutChanges="true"
Dinesh
  • 889
  • 14
  • 34
0

To animate change in Layout params of a Linear layout and its child you can use LayoutTransition.

Its important that you define and attach transition to Linear layout parent for eg: llRoot.setLayoutTransition(layoutTransition) in below code snippet before c hanging LayoutParams of child.

Support for LayoutTransition is above Android JellyBean

   private var AnimationDuration = 1100f


    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
    private fun fadeOutControls() {
        var layoutTransition = LayoutTransition()
        layoutTransition.setDuration(AnimationDuration.toLong()) // Change duration

        layoutTransition.enableTransitionType(LayoutTransition.CHANGING)
        layoutTransition.addTransitionListener(object : LayoutTransition.TransitionListener {
            override fun startTransition(transition: LayoutTransition, container: ViewGroup, view: View, transitionType: Int) {

            }

            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            override fun endTransition(transition: LayoutTransition, container: ViewGroup, view: View, transitionType: Int) {
                //Change this line of code to below one
                transition.disableTransitionType(LayoutTransition.CHANGING)
            }
        })

        // set transition to Linear layout
        llRoot.setLayoutTransition(layoutTransition)


         // change Layout params of child now to animate Transition
        val lp = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
        lp.weight = 10f
        mediaRoot.setLayoutParams(lp)

        leftControl.visibility = View.GONE
        rightControl.visibility = View.GONE
    }
Hitesh Sahu
  • 41,955
  • 17
  • 205
  • 154
-1

If you want to implement the slider animation for your layout then see this demo.

UPDATED

Also see http://www.inter-fuser.com/2009/07/android-transistions-slide-in-and-slide.html

Hope it will help you.

If not then let me know.

Thanks. Enjoy. :)

Shreyash Mahajan
  • 23,386
  • 35
  • 116
  • 188