在LinearLayout中更改LayoutParams时的动画效果

16

我的应用程序中有一个高度为0的LinearLayout。 当我点击按钮时,此布局高度应该是LayoutParams.WRAP_CONTENT。 这是我在onclicklistner中使用的代码。

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

我想要给这个滑块添加动画效果。如何将动画效果应用到滑块上?


1
你想在滑块上添加动画效果吗? - Nixit Patel
@NixitPatel:你想要实现滑块动画吗? - Shreyash Mahajan
@iDroid Explorer,是的,我需要实现滑块动画。 - Chrishan
5个回答

25

我认为你只是想将一个视图从0高度动画到其最终高度,你可以使用自定义动画来实现:

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;
    }
}

在你的代码中执行以下操作来启动动画:

Animation ani = new ShowAnim(headerView, 100/* target layout height */);
ani.setDuration(2000/* animation time */);
headerView.startAnimation(ani);

2
你怎么做才能让它不每次都从零高度开始?如果我先设置目标布局高度为100,然后再设置目标布局高度为200,我希望它从0到100,然后再从100到200。 - Andrew
如果你想从100 -> 200,只需要修改这行代码 view.getLayoutParams().height = (int) (targetHeight * interpolatedTime); 为类似于 view.getLayoutParams().height = initialHeight /*在你的情况下是100*/ + (int) (targetHeight/*在你的情况下是200*/-initialHeight * interpolatedTime); - Kai
1
有一件事情是不起作用的,那就是当 initialHeight 为0时什么也不会发生。完全没有任何视觉变化。 - Andrew
你之前的回答有一个问题。运算顺序不正确。你必须在 targetHeight - initialHeight 周围加上括号,这样 * interpolatedTime 才会在后面应用。 - Andrew
3
这只是快速的伪代码,以便开始工作,请根据您自己的需求进行调整。 - Kai
显示剩余4条评论

3
使用 animateLayoutChanges xml 和在 java 或 kotlin 中启用 enableTransitionType。
1. 将 animateLayoutChanges 添加到根布局的 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. 在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. 在 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()

1
自从JELLYBEAN以来,Android已经有了布局转换,我们可以使用它来替代使用动画对象。
下面的文章详细解释了这一点。 https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec 简而言之,我们只需要这段代码 -
tView.getLayoutTransition().enableTransitionType(LayoutTransition.CHANGING);
tView.setLayoutParams(lp);

这里的 "lp" 是布局参数。
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams
                            (RelativeLayout.LayoutParams.MATCH_PARENT, newHeight);

还有一件事需要补充,就是在布局文件中添加这行代码,添加到执行转换的布局中。

android:animateLayoutChanges="true"

0

要在线性布局及其子项的布局参数中实现动画变化,您可以使用LayoutTransition

重要的是,在更改子项的LayoutParams之前,您需要定义并将转换附加到线性布局父项,例如:在下面的代码片段中使用llRoot.setLayoutTransition(layoutTransition)

LayoutTransition的支持在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
    }

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接