我在垂直LinearLayout(父级)中有两个布局(绿色在顶部,红色在底部),看起来与此类似:
。
当焦点从绿色变为红色时,我希望绿色从屏幕上滑下并让红色同时向上滑动并填满整个屏幕。当焦点从红色向上移动时,我希望绿色滑回屏幕并返回到原始配置。我试过看了很多其他的问题,但没有人有我需要的解决方案。我尝试改变去掉和可见之间的可见性,但我希望它是一个平滑的动画。我尝试在外部LinearLayout上使用parentLayout.animate().translationY(greenLayout.getHeight())
并确实提供了我想要的动画但是红色不会扩展以填充屏幕,如下所示:
我知道这个问题与this one相似,但这个问题真的很陈旧,只有一个答案对我不起作用。
答案 0 :(得分:0)
我的解决方案有很多不同的部分,所以我将从完整的XML和Java代码开始,然后讨论重要的部分:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:id="@+id/green"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#0f0" />
<View
android:id="@+id/red"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#f00"/>
</LinearLayout>
在XML中,唯一非常重要的部分是红色视图使用0dp
的高度和1
的权重。这意味着它占用了所有额外的垂直空间,这在我们摆脱绿色视图时非常重要。
public class MainActivity extends AppCompatActivity {
private int originalHeight;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final View green = findViewById(R.id.green);
final View red = findViewById(R.id.red);
green.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
green.getViewTreeObserver().removeGlobalOnLayoutListener(this);
originalHeight = green.getHeight();
}
});
green.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
animateHeightOfView(green, originalHeight, 0);
}
});
red.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
animateHeightOfView(green, 0, originalHeight);
}
});
}
private void animateHeightOfView(final View view, int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
int height = (int) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = height;
view.setLayoutParams(params);
}
});
animator.start();
}
}
在Java中,两个主要部分是ViewTreeObserver.OnGlobalLayoutListener
和animateHeightOfView()
方法。
OnGlobalLayoutListener
存在以捕获绿色视图的原始高度。我们必须使用侦听器才能执行此操作,而不是仅在originalHeight = green.getHeight()
内编写onCreate()
,因为此时绿色视图实际上并未布局,因此getHeight()
将返回0
如果我们尝试过的话。
animateHeightOfView()
方法利用ValueAnimator
类为您传递给它的任何视图的高度设置动画。由于视图的高度没有直接的设置器,我们不能使用更简单的方法,如.animate()
。我们设置ValueAnimator
以在每个帧上生成int
值,然后我们使用ValueAnimator.AnimatorUpdateListener
修改视图的LayoutParams
来设置高度。
随意玩它。我正在使用点击监听器来触发动画,你提到了焦点,但如果它适合你,你应该能够以不同的方式调用animateHeightOfView()
。