动画视图的顶部和底部尺寸
Animate top and bottom dimensions of a view
我需要用视图做两件事:
- 将顶部维度移动到 window
的最顶部
- 将底部维度移动到 window 的最底部。
简而言之,我需要视图覆盖父视图的100%。
平移动画不起作用,因为它移动了视图但没有增加尺寸。
缩放动画有效,但它会拉伸视图的内容,我不希望这样。我想增加可见区域,而不是拉伸内容以适应新尺寸。
正确的做法是什么?
您可以尝试使用此答案中所示的 ValueAnimator:
注意:我想写这个作为评论,但我没有声誉。这不应被视为完整答案。
我喜欢让一切尽可能简单。
所以我的建议是使用 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);
}
}
这可以通过 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>
在activity中:
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
) is available from API 19, but support libraries backport the functionality upto API 14 (android.support.transition.TransitionManager
)。
animateLayoutChanges="true" in the parent xml
+
.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
大部分时间都可以做到这一点,它不会拉伸现有的子视图
将 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 应用到您的视图或在必要时 activity。
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();
我需要用视图做两件事:
- 将顶部维度移动到 window 的最顶部
- 将底部维度移动到 window 的最底部。
简而言之,我需要视图覆盖父视图的100%。
平移动画不起作用,因为它移动了视图但没有增加尺寸。
缩放动画有效,但它会拉伸视图的内容,我不希望这样。我想增加可见区域,而不是拉伸内容以适应新尺寸。
正确的做法是什么?
您可以尝试使用此答案中所示的 ValueAnimator:
注意:我想写这个作为评论,但我没有声誉。这不应被视为完整答案。
我喜欢让一切尽可能简单。
所以我的建议是使用 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);
}
}
这可以通过 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>
在activity中:
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
) is available from API 19, but support libraries backport the functionality upto API 14 (android.support.transition.TransitionManager
)。
animateLayoutChanges="true" in the parent xml
+
.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
大部分时间都可以做到这一点,它不会拉伸现有的子视图
将 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 应用到您的视图或在必要时 activity。
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();