【问题标题】:Animate top and bottom dimensions of a view动画视图的顶部和底部尺寸
【发布时间】:2017-08-09 22:43:27
【问题描述】:

我需要对视图做两件事:

  1. 将顶部尺寸移动到窗口的最顶部
  2. 将底部尺寸移动到窗口的最底部。

简而言之,我需要视图覆盖 100% 的父视图。

翻译动画不起作用,因为它会移动视图但不会增加大小。

缩放动画有效,但它会拉伸视图的内容,我不希望这样。我想增加可见区域,而不是拉伸内容以适应新尺寸。

这样做的正确方法是什么?

【问题讨论】:

  • 它是什么类型的视图?是否在 RecyclerView 之类的列表中?
  • @Kevinrob:它不在 RecyclerView 上。视图是TabHost

标签: android android-layout animation android-animation android-view


【解决方案1】:

这可以通过Transitions API 轻松实现。

使用 Transitions API,您无需负责编写动画,您只需告诉最终值是什么,Transitions 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)。

【讨论】:

  • TransitionManager 在 API 级别 19 中添加
  • 是否可以设置动画的时长?
  • 是否可以同时为多个控件设置动画?
  • 什么意思?
  • 如果您同时为view 制作动画,您可以在同一过渡上下文中为另一个控件制作动画
【解决方案2】:

我喜欢让一切尽可能简单。

所以我的建议是使用 android Animating Layout Changes

这是一个示例:

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

【讨论】:

    【解决方案3】:

    您可以尝试使用 ValueAnimator,如此答案所示: https://stackoverflow.com/a/32835417/3965050

    注意:我想写这个作为评论,但我没有声誉。这不应被视为完整的答案。

    【讨论】:

      【解决方案4】:
      animateLayoutChanges="true" in the parent xml
      

      +

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

      大多数时候都能做到这一点,它不会拉伸现有的子视图

      【讨论】:

        【解决方案5】:

        将 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 应用于您的视图或活动。

        【讨论】:

          【解决方案6】:
          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(); 
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-05-22
            • 2014-06-05
            • 1970-01-01
            • 1970-01-01
            • 2015-09-16
            • 2012-01-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多