原理是在onMeasure中得到隐藏内容的高度,点击这个view的时候对隐藏的view startAnimation,让它的高度从0增长到onMeasure得到的这个View的measureHeight
具体这样写:
public class ExpandableLayout extends LinearLayout {
private Context mContext;
private LinearLayout mHandleView;
private RelativeLayout mContentView;
private ImageView mIconExpand;
int mContentHeight = 0;
int mTitleHeight = 0;
private boolean isExpand;
private Animation animationDown;
private Animation animationUp;
public ExpandableLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (this.mContentHeight == 0) {
this.mContentView.measure(widthMeasureSpec, 0);
this.mContentHeight = this.mContentView.getMeasuredHeight();
}
if (this.mTitleHeight == 0) {
this.mHandleView.measure(widthMeasureSpec, 0);
this.mTitleHeight = this.mHandleView.getMeasuredHeight();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
this.mHandleView = (LinearLayout) this
.findViewById(R.id.collapse_value);
this.mContentView = (RelativeLayout) this.findViewById(R.id.expand_value);
this.mIconExpand = (ImageView) this.findViewById(R.id.icon_value);
this.mHandleView.setOnClickListener(new ExpandListener());
this.mContentView.setOnClickListener(new ExpandListener());
mContentView.setVisibility(View.GONE);
}
private class ExpandListener implements View.OnClickListener {
@Override
public final void onClick(View paramView) {
//clearAnimation是view的方法
clearAnimation();
if (!isExpand) {
if (animationDown == null) {
animationDown = new DropDownAnim(mContentView,
mContentHeight, true);
animationDown.setDuration(200); // SUPPRESS CHECKSTYLE
}
startAnimation(animationDown);
mContentView.startAnimation(AnimationUtils.loadAnimation(
mContext, R.anim.animalpha));
mIconExpand.setImageResource(R.drawable.update_detail_up);
isExpand = true;
} else {
isExpand = false;
if (animationUp == null) {
animationUp = new DropDownAnim(mContentView,
mContentHeight, false);
animationUp.setDuration(200); // SUPPRESS CHECKSTYLE
}
startAnimation(animationUp);
mIconExpand.setImageResource(R.drawable.update_detail_down);
}
}
}
class DropDownAnim extends Animation {
/** 目标的高度 */
private int targetHeight;
/** 目标view */
private View view;
/** 是否向下展开 */
private boolean down;
/**
* 构造方法
*
* @param targetview
* 需要被展现的view
* @param vieweight
* 目的高
* @param isdown
* true:向下展开,false:收起
*/
public DropDownAnim(View targetview, int vieweight, boolean isdown) {
this.view = targetview;
this.targetHeight = vieweight;
this.down = isdown;
}
//down的时候,interpolatedTime从0增长到1,这样newHeight也从0增长到targetHeight
@Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
int newHeight;
if (down) {
newHeight = (int) (targetHeight * interpolatedTime);
} else {
newHeight = (int) (targetHeight * (1 - interpolatedTime));
}
view.getLayoutParams().height = newHeight;
view.requestLayout();
if (view.getVisibility() == View.GONE) {
view.setVisibility(View.VISIBLE);
}
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
@Override
public boolean willChangeBounds() {
return true;
}
}
}
Layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF" >
<com.example.view.ExpandableLayout
android:id="@+id/app_detail_safety_info"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/collapse_value"
android:layout_width="fill_parent"
android:layout_height="34dip"
android:layout_marginLeft="14dip"
android:gravity="center_vertical"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:text="点击我会显示隐藏的内容"
android:textColor="#000000"
android:textSize="18sp" >
</TextView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="right|center_vertical"
android:orientation="horizontal" >
<ImageView
android:id="@+id/icon_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="22dip"
android:src="@drawable/update_detail_down" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:id="@+id/expand_value"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/app_detail_safety_info_bg"
android:orientation="horizontal"
android:paddingBottom="8dip"
android:paddingTop="8dip" >
<ImageButton
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="30dp"
android:background="@null"
android:src="@drawable/btn_icon"
android:textColor="#0A84BD"
android:textSize="16sp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_toRightOf="@id/btn"
android:text="隐藏的内容"
android:textColor="#000000"
android:textSize="18sp" >
</TextView>
</RelativeLayout>
</com.example.view.ExpandableLayout>
</RelativeLayout>
只要在这个activity中setContentView这个layout,点击view就可以执行展开动画
代码:http://download.csdn.net/detail/baidu_nod/7812705
效果图: