使视图的顶部和底部尺寸动画化

8
我需要对视图执行两个操作:
  1. 将顶部维度移动到窗口的最顶端
  2. 将底部维度移动到窗口的最底部。
简而言之,我需要视图覆盖父视图的100%。
翻译动画不起作用,因为它移动了视图但没有增加大小。
缩放动画可以工作,但它会拉伸视图内容,我不想要那样。我想增加可见区域,而不是拉伸内容以适应新的尺寸。
正确的方法是什么?

它是什么类型的视图?它是否像RecyclerView一样在列表中? - Kevin Robatel
@Kevinrob:它不在一个RecyclerView上。该视图是一个TabHost - StackOverflower
6个回答

12

使用转换API可以轻松实现这一点。

使用转换API,您无需编写动画代码,只需告诉它您想要的最终值,转换API将负责构建动画。

如果将此xml作为内容视图(即屏幕中央的视图):

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <View
        android:id="@+id/view"
        android:layout_width="120dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        android:background="@color/colorAccent" />

</FrameLayout>

正在进行的活动:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.item)

    val root = findViewById(R.id.root) as ViewGroup
    val view = findViewById(R.id.view)

    view.setOnClickListener {

        // After this line Transitions API would start counting the delta
        // and will take care of creating animations for each view in `root`
        TransitionManager.beginDelayedTransition(root)

        // By default AutoTransition would be applied,
        // but you can provide your transition with the second parameter

        // val transition = AutoTransition()
        // transition.duration = 2000
        // TransitionManager.beginDelayedTransition(root, transition)

        // We are changing size of the view to match parent
        val params = view.layoutParams
        params.height = ViewGroup.LayoutParams.MATCH_PARENT
        params.width = ViewGroup.LayoutParams.MATCH_PARENT

        view.requestLayout()
    }
}

这是输出结果:

平台的转换API(android.transition.TransitionManager)可从API 19开始使用,但支持库将其功能向后兼容至API 14(android.support.transition.TransitionManager)。


1
TransitionManager被添加到API 19级。 - zombie
是否可以为动画设置持续时间? - StackOverflower
使用这个,能否同时对多个控件进行动画处理? - StackOverflower
你是什么意思? - azizbekian
如果你所说的“控制”是指另一个视图,那么是的,你可以。 - azizbekian
显示剩余2条评论

2

我喜欢保持一切尽可能简单。

所以我的建议是使用Android的布局动画

以下是一个示例:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:animationCache="true">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name"
        android:background="@color/colorPrimary"
        android:layout_gravity="center" />

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.textView);
    }

    @Override
    protected void onResume() {
        super.onResume();

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {

                View view = getWindow().getDecorView();

                int height = getWindow().getDecorView().getHeight();
                int width = getWindow().getDecorView().getWidth();
                textView.setLayoutParams(new LinearLayout.LayoutParams(width, height));

                LayoutTransition layoutTransition = ((ViewGroup) textView.getParent()).getLayoutTransition();
                layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
            }
        }, 2000);
    }
}

1

0
ValueAnimator anim = ValueAnimator.ofInt(viewToIncreaseHeight.getMeasuredHeight(), -100);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        int val = (Integer) valueAnimator.getAnimatedValue();
        ViewGroup.LayoutParams layoutParams = viewGroup.getLayoutParams();
        layoutParams.height = val;
        viewGroup.setLayoutParams(layoutParams);
    }
});
anim.setDuration(DURATION);
anim.start(); 

0
使用ConstraintLayout与ConstrainSet应该是最有效的方式来满足您的需求。
public class MainActivity extends AppCompatActivity {
    ConstraintSet mConstraintSet1 = new ConstraintSet(); // create a Constraint Set
    ConstraintSet mConstraintSet2 = new ConstraintSet(); // create a Constraint Set
    ConstraintLayout mConstraintLayout; // cache the ConstraintLayout
    boolean mOld = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Context context = this;
        mConstraintSet2.clone(context, R.layout.state2); // get constraints from layout
        setContentView(R.layout.state1);
        mConstraintLayout = (ConstraintLayout) findViewById(R.id.activity_main);
        mConstraintSet1.clone(mConstraintLayout); // get constraints from ConstraintSet
    }

    public void foo(View view) {
        TransitionManager.beginDelayedTransition(mConstraintLayout);
        if (mOld = !mOld) {
            mConstraintSet1.applyTo(mConstraintLayout); // set new constraints
        }  else {
            mConstraintSet2.applyTo(mConstraintLayout); // set new constraints
        }
    }
}

源代码 https://developer.android.com/reference/android/support/constraint/ConstraintSet.html

你只需要定义一个带有扩展约束的第二个layout.xml,并在必要时将第二个ConstraintSet应用于你的视图或活动。


0
animateLayoutChanges="true" in the parent xml

+

.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

这个技巧大多数情况下都能奏效,并且不会拉伸现有的子视图


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