Android expand/collapse 相对布局
Android expand/collapse RelativeLayout
我已经尝试了该主题的各种解决方案(参见 Android: Expand/collapse animation ),其中 none 确实对我有用。我确定投票最多的是好的,它不起作用的原因是我不明白某些东西。请告诉我我做错了什么。提前谢谢你:)
编辑: 我的问题的要点是,当我单击元素 'relativeZaplon' 时,它扩展得很好,但是当我想折叠它时,它不对应。
MainActivity
public class MainActivity extends AppCompatActivity {
private boolean isVisible = false;
private RelativeLayout mRelativeZaplon;
private RelativeLayout mRelativeToSlide;
private ExpandOrCollapse mAnimationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAnimationManager = new ExpandOrCollapse();
mRelativeZaplon = (RelativeLayout) findViewById(R.id.relativeZaplon);
mRelativeToSlide = (RelativeLayout) findViewById(R.id.relativevToSlide);
mRelativeZaplon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isVisible) {
mAnimationManager.collapse(mRelativeToSlide, 1000, 200);
isVisible = false;
} else if (!isVisible){
mAnimationManager.expand(mRelativeToSlide, 1000, 200);
isVisible = true;
}
}
});
}
}
Expand/Collapse Class
public class ExpandOrCollapse {
public static void expand(final View v, int duration, int targetHeight) {
int prevHeight = v.getHeight();
v.setVisibility(View.VISIBLE);
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
public static void collapse(final View v, int duration, int targetHeight) {
int prevHeight = v.getHeight();
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
}
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:orientation="vertical">
<RelativeLayout
android:background="@color/colorPrimaryDark"
android:id="@+id/relativevToSlide"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
</RelativeLayout>
<RelativeLayout
android:id="@+id/relativeZaplon"
android:background="@color/colorAccent"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_below="@+id/relativevToSlide"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
</RelativeLayout>
</LinearLayout>
是因为
if (isVisible) {
mAnimationManager.collapse(mRelativeToSlide, 1000, 200);
isVisible = false;
} else if (!isVisible){
mAnimationManager.expand(mRelativeToSlide, 1000, 200);
isVisible = true;
}
collapse() 和 expand() 做同样的事情,在本例中它们都是展开动画。您需要将不同的值传递给 collapse() 方法;
简单的解决方案是
mAnimationManager.collapse(mRelativeToSlide, 1000, -200);
但是您的编码风格还有一些问题,例如,您可以去掉 collapse() 方法,因为像这样调用两次 expand 也可以:
if (isVisible) {
mAnimationManager.expand(mRelativeToSlide, 1000, -200);
isVisible = false;
} else if (!isVisible){
mAnimationManager.expand(mRelativeToSlide, 1000, 200);
isVisible = true;
}
我建议你 post 在 Code Review。
这是我的方法版本,您无需设置任何高度,它会根据其可见性展开或折叠任何视图。
public static void expand(final View v, int duration) {
final boolean expand = v.getVisibility()!=View.VISIBLE;
int prevHeight = v.getHeight();
int height = 0;
if (expand) {
int measureSpecParams = View.MeasureSpec.getSize(View.MeasureSpec.UNSPECIFIED);
v.measure(measureSpecParams, measureSpecParams);
height = v.getMeasuredHeight();
}
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, height);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (expand){
v.setVisibility(View.VISIBLE);
}
}
@Override
public void onAnimationEnd(Animator animation) {
if (!expand){
v.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
调用方法如下:
expand(YOURVIEWID,500);
我将解释我选择动画布局更改的方式。
Android 有一个名为 ScaleAnimation
的特殊动画 class,借助它我们可以平滑地展开或折叠视图。
通过对角线展开显示视图:
ScaleAnimation expand = new ScaleAnimation(
0, 1.0f,
0, 1.0f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
expand.setDuration(250);
view.startAnimation(expand)
其中使用的构造函数是:
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
因此您可以相应地更改值。
例如,下面的示例将水平显示动画:
ScaleAnimation expand = new ScaleAnimation(
0, 1.1f,
1f, 1f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
expand.setDuration(250);
您可以根据需要更改fromX
、toX
、fromY
和toY
。
例如,如果显示了视图,而您只需展开它,将 fromX
和 fromY
放入 1.0f
,然后 toX
、toY
根据需要。
现在,使用相同的 class,您可以通过稍微扩展视图然后将其缩小到原始大小来创建更酷的显示视图效果。为此,将使用 AnimationSet
。所以它会产生一种气泡效果。
下面的例子是创建显示视图的气泡效果:
AnimationSet expandAndShrink = new AnimationSet(true);
ScaleAnimation expand = new ScaleAnimation(
0, 1.1f,
0, 1.1f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
expand.setDuration(250);
ScaleAnimation shrink = new ScaleAnimation(
1.1f, 1f,
1.1f, 1f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
shrink.setStartOffset(250);
shrink.setDuration(120);
expandAndShrink.addAnimation(expand);
expandAndShrink.addAnimation(shrink);
expandAndShrink.setFillAfter(true);
expandAndShrink.setInterpolator(new AccelerateInterpolator(1.0f));
view.startAnimation(expandAndShrink);
我已经尝试了该主题的各种解决方案(参见 Android: Expand/collapse animation ),其中 none 确实对我有用。我确定投票最多的是好的,它不起作用的原因是我不明白某些东西。请告诉我我做错了什么。提前谢谢你:)
编辑: 我的问题的要点是,当我单击元素 'relativeZaplon' 时,它扩展得很好,但是当我想折叠它时,它不对应。
MainActivity
public class MainActivity extends AppCompatActivity {
private boolean isVisible = false;
private RelativeLayout mRelativeZaplon;
private RelativeLayout mRelativeToSlide;
private ExpandOrCollapse mAnimationManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAnimationManager = new ExpandOrCollapse();
mRelativeZaplon = (RelativeLayout) findViewById(R.id.relativeZaplon);
mRelativeToSlide = (RelativeLayout) findViewById(R.id.relativevToSlide);
mRelativeZaplon.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (isVisible) {
mAnimationManager.collapse(mRelativeToSlide, 1000, 200);
isVisible = false;
} else if (!isVisible){
mAnimationManager.expand(mRelativeToSlide, 1000, 200);
isVisible = true;
}
}
});
}
}
Expand/Collapse Class
public class ExpandOrCollapse {
public static void expand(final View v, int duration, int targetHeight) {
int prevHeight = v.getHeight();
v.setVisibility(View.VISIBLE);
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
public static void collapse(final View v, int duration, int targetHeight) {
int prevHeight = v.getHeight();
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, targetHeight);
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
}
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:orientation="vertical">
<RelativeLayout
android:background="@color/colorPrimaryDark"
android:id="@+id/relativevToSlide"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
</RelativeLayout>
<RelativeLayout
android:id="@+id/relativeZaplon"
android:background="@color/colorAccent"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_below="@+id/relativevToSlide"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true">
</RelativeLayout>
</LinearLayout>
是因为
if (isVisible) {
mAnimationManager.collapse(mRelativeToSlide, 1000, 200);
isVisible = false;
} else if (!isVisible){
mAnimationManager.expand(mRelativeToSlide, 1000, 200);
isVisible = true;
}
collapse() 和 expand() 做同样的事情,在本例中它们都是展开动画。您需要将不同的值传递给 collapse() 方法; 简单的解决方案是
mAnimationManager.collapse(mRelativeToSlide, 1000, -200);
但是您的编码风格还有一些问题,例如,您可以去掉 collapse() 方法,因为像这样调用两次 expand 也可以:
if (isVisible) {
mAnimationManager.expand(mRelativeToSlide, 1000, -200);
isVisible = false;
} else if (!isVisible){
mAnimationManager.expand(mRelativeToSlide, 1000, 200);
isVisible = true;
}
我建议你 post 在 Code Review。
这是我的方法版本,您无需设置任何高度,它会根据其可见性展开或折叠任何视图。
public static void expand(final View v, int duration) {
final boolean expand = v.getVisibility()!=View.VISIBLE;
int prevHeight = v.getHeight();
int height = 0;
if (expand) {
int measureSpecParams = View.MeasureSpec.getSize(View.MeasureSpec.UNSPECIFIED);
v.measure(measureSpecParams, measureSpecParams);
height = v.getMeasuredHeight();
}
ValueAnimator valueAnimator = ValueAnimator.ofInt(prevHeight, height);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
v.getLayoutParams().height = (int) animation.getAnimatedValue();
v.requestLayout();
}
});
valueAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
if (expand){
v.setVisibility(View.VISIBLE);
}
}
@Override
public void onAnimationEnd(Animator animation) {
if (!expand){
v.setVisibility(View.INVISIBLE);
}
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
valueAnimator.setInterpolator(new DecelerateInterpolator());
valueAnimator.setDuration(duration);
valueAnimator.start();
}
调用方法如下:
expand(YOURVIEWID,500);
我将解释我选择动画布局更改的方式。
Android 有一个名为 ScaleAnimation
的特殊动画 class,借助它我们可以平滑地展开或折叠视图。
通过对角线展开显示视图:
ScaleAnimation expand = new ScaleAnimation(
0, 1.0f,
0, 1.0f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
expand.setDuration(250);
view.startAnimation(expand)
其中使用的构造函数是:
ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
因此您可以相应地更改值。
例如,下面的示例将水平显示动画:
ScaleAnimation expand = new ScaleAnimation(
0, 1.1f,
1f, 1f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
expand.setDuration(250);
您可以根据需要更改fromX
、toX
、fromY
和toY
。
例如,如果显示了视图,而您只需展开它,将 fromX
和 fromY
放入 1.0f
,然后 toX
、toY
根据需要。
现在,使用相同的 class,您可以通过稍微扩展视图然后将其缩小到原始大小来创建更酷的显示视图效果。为此,将使用 AnimationSet
。所以它会产生一种气泡效果。
下面的例子是创建显示视图的气泡效果:
AnimationSet expandAndShrink = new AnimationSet(true);
ScaleAnimation expand = new ScaleAnimation(
0, 1.1f,
0, 1.1f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
expand.setDuration(250);
ScaleAnimation shrink = new ScaleAnimation(
1.1f, 1f,
1.1f, 1f,
Animation.RELATIVE_TO_PARENT, 0,
Animation.RELATIVE_TO_PARENT, 0);
shrink.setStartOffset(250);
shrink.setDuration(120);
expandAndShrink.addAnimation(expand);
expandAndShrink.addAnimation(shrink);
expandAndShrink.setFillAfter(true);
expandAndShrink.setInterpolator(new AccelerateInterpolator(1.0f));
view.startAnimation(expandAndShrink);