很多需要实现点击显示和隐藏指定布局的功能,但不带过渡动画的显示和隐藏会显得比较生硬,因此需要自定义一个带过渡动画的控件,代码如下:
public class UMExpandLayout extends RelativeLayout {
public UMExpandLayout(Context context) {
this(context, null);
}
public UMExpandLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public UMExpandLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView();
}
private View layoutView;
private int viewHeight;
private boolean isExpand;
private long animationDuration;
private void initView() {
layoutView = this;
isExpand = true;
animationDuration = 300;
setViewDimensions();
}
/**
* @param isExpand 初始状态是否折叠
*/
public void initExpand(boolean isExpand) {
this.isExpand = isExpand;
if (!isExpand) {
animateToggle(10);
}
}
/**
* 设置动画时间
*
* @param animationDuration 动画时间
*/
public void setAnimationDuration(long animationDuration) {
this.animationDuration = animationDuration;
}
/**
* 获取 subView 的总高度
* View.post() 的 runnable 对象中的方法会在 View 的 measure、layout 等事件后触发
*/
private void setViewDimensions() {
layoutView.post(new Runnable() {
@Override
public void run() {
if (viewHeight <= 0) {
viewHeight = layoutView.getMeasuredHeight();
}
}
});
}
public static void setViewHeight(View view, int height) {
final ViewGroup.LayoutParams params = view.getLayoutParams();
params.height = height;
view.requestLayout();
}
/**
* 切换动画实现
*/
private void animateToggle(long animationDuration) {
ValueAnimator heightAnimation = isExpand ?
ValueAnimator.ofFloat(0f, viewHeight) : ValueAnimator.ofFloat(viewHeight, 0f);
heightAnimation.setDuration(animationDuration / 2);
heightAnimation.setStartDelay(animationDuration / 2);
heightAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float val = (float) animation.getAnimatedValue();
setViewHeight(layoutView, (int) val);
}
});
heightAnimation.start();
}
public boolean isExpand() {
return isExpand;
}
/**
* 折叠view
*/
public void collapse() {
isExpand = false;
animateToggle(animationDuration);
}
/**
* 展开view
*/
public void expand() {
isExpand = true;
animateToggle(animationDuration);
}
public void toggleExpand() {
if (isExpand) {
collapse();
} else {
expand();
}
}
}
然后就可以在 layout 中使用了:
<com.eyefate.view.ExpandLayout
android:id="@+id/setting_about_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/margin_negative_6dp"
android:background="@android:color/white"
android:clickable="true">
<!--您要显示和隐藏的内容-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="@dimen/height_0.5dp"
android:layout_marginLeft="@dimen/margin_8dp"
android:layout_marginRight="@dimen/margin_8dp"
android:background="@color/color_divide_line" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/margin_12dp"
android:layout_marginLeft="@dimen/margin_20dp"
android:layout_marginRight="@dimen/margin_20dp"
android:layout_marginTop="@dimen/margin_12dp"
android:lineSpacingExtra="@dimen/line_space_4dp"
android:text="@string/app_description"
android:textSize="@dimen/font_text_size_14sp" />
</LinearLayout>
</com.eyefate.view.ExpandLayout>
ExpandLayout 的子控件有且只能拥有一个布局,具体效果如下: