![属性动画](https://img-blog.csdn.net/20161206193359363?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYXhpMjk1MzA5MDY2/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
<?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="#ffffff"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp" >
<ImageView
android:id="@+id/app_detail_safe_iv_arrow"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="15dp"
android:src="@drawable/arrow_down" />
<LinearLayout
android:id="@+id/app_detail_safe_pic_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingTop="5dp" >
</LinearLayout>
</RelativeLayout>
<LinearLayout
android:background="#ffffff"
android:id="@+id/app_detail_safe_des_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
public class AppDetailSafeHolder extends BaseHolder<AppInfoBean> implements OnClickListener {
@ViewInject(R.id.app_detail_safe_pic_container)
LinearLayout mContainerPic;
@ViewInject(R.id.app_detail_safe_des_container)
LinearLayout mContainerDes;
@ViewInject(R.id.app_detail_safe_iv_arrow)
ImageView mIvArrow;
private boolean isOpen = true;
@Override
public View initHolderView() {
View view = View.inflate(UIUtils.getContext(), R.layout.item_app_detail_safe, null);
ViewUtils.inject(this, view);
view.setOnClickListener(this);
return view;
}
@Override
public void refreshHolderView(AppInfoBean data) {
List<AppInfoSafeBean> safeBeans = data.safe;
for (AppInfoSafeBean appInfoSafeBean : safeBeans) {
ImageView ivIcon = new ImageView(UIUtils.getContext());
BitmapHelper.display(ivIcon, URLS.IMAGEBASEURL + appInfoSafeBean.safeUrl);
mContainerPic.addView(ivIcon);
LinearLayout ll = new LinearLayout(UIUtils.getContext());
ImageView ivDes = new ImageView(UIUtils.getContext());
BitmapHelper.display(ivDes, URLS.IMAGEBASEURL + appInfoSafeBean.safeDesUrl);
TextView tvDes = new TextView(UIUtils.getContext());
tvDes.setText(appInfoSafeBean.safeDes);
if (appInfoSafeBean.safeDesColor == 0) {
tvDes.setTextColor(UIUtils.getColor(R.color.app_detail_safe_normal));
} else {
tvDes.setTextColor(UIUtils.getColor(R.color.app_detail_safe_warning));
}
tvDes.setGravity(Gravity.CENTER);
int padding = UIUtils.dip2Px(5);
ll.setPadding(padding, padding, padding, padding);
ll.addView(ivDes);
ll.addView(tvDes);
mContainerDes.addView(ll);
}
toggle(false);
}
@Override
public void onClick(View v) {
toggle(true);
}
private void toggle(boolean isAnimation) {
if (isOpen) {
/**
mContainerDes高度发生变化
应有的高度-->0
*/
mContainerDes.measure(0, 0);
int measuredHeight = mContainerDes.getMeasuredHeight();
int start = measuredHeight;
int end = 0;
if (isAnimation) {
doAnimation(start, end);
} else {
LayoutParams params = mContainerDes.getLayoutParams();
params.height = end;
mContainerDes.setLayoutParams(params);
}
} else {
/**
mContainerDes高度发生变化
0-->应有的高度
*/
mContainerDes.measure(0, 0);
int measuredHeight = mContainerDes.getMeasuredHeight();
int end = measuredHeight;
int start = 0;
if (isAnimation) {
doAnimation(start, end);
} else {
LayoutParams params = mContainerDes.getLayoutParams();
params.height = end;
mContainerDes.setLayoutParams(params);
}
}
if (isAnimation) {
if (isOpen) {
ObjectAnimator.ofFloat(mIvArrow, "rotation", 180, 0).start();
} else {
ObjectAnimator.ofFloat(mIvArrow, "rotation", 0, 180).start();
}
}
isOpen = !isOpen;
}
public void doAnimation(int start, int end) {
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.start();
animator.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator value) {
int height = (Integer) value.getAnimatedValue();
LayoutParams params = mContainerDes.getLayoutParams();
params.height = height;
mContainerDes.setLayoutParams(params);
}
});
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="4dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/white"
android:orientation="vertical"
android:padding="5dp" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:text="简介"
android:textColor="@android:color/black"
android:textSize="16sp" />
<TextView
android:id="@+id/app_detail_des_tv_des"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:text="内容"
android:textColor="@android:color/darker_gray"
android:textSize="14sp" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="25dp" >
<TextView
android:id="@+id/app_detail_des_tv_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:text="作者 : "
android:textColor="@android:color/darker_gray"
android:textSize="14sp" />
<ImageView
android:id="@+id/app_detail_des_iv_arrow"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/arrow_down" />
</RelativeLayout>
</LinearLayout>
</FrameLayout>
public class AppDetailDesHolder extends BaseHolder<AppInfoBean> implements OnClickListener {
@ViewInject(R.id.app_detail_des_tv_author)
TextView mTvAuthor;
@ViewInject(R.id.app_detail_des_iv_arrow)
ImageView mIvArrow;
@ViewInject(R.id.app_detail_des_tv_des)
TextView mTvDes;
private boolean isOpen = true;
private int mTvDesMeasuredHeight;
private AppInfoBean mData;
@Override
public View initHolderView() {
View view = View.inflate(UIUtils.getContext(), R.layout.item_app_detail_des, null);
ViewUtils.inject(this, view);
view.setOnClickListener(this);
return view;
}
@Override
public void refreshHolderView(AppInfoBean data) {
mData = data;
mTvAuthor.setText(data.author);
mTvDes.setText(data.des);
mTvDes.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mTvDesMeasuredHeight = mTvDes.getMeasuredHeight();
toggle(false);
mTvDes.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
@Override
public void onClick(View v) {
toggle(true);
}
private void toggle(boolean isAnimation) {
if (isOpen) {
/**
mTvDes高度发生改变
应有的高度-->7行的高度
*/
int start = mTvDesMeasuredHeight;
int end = getShortHeight(7, mData);
if (isAnimation) {
doAnimation(start, end);
} else {
mTvDes.setHeight(end);
}
} else {
int start = getShortHeight(7, mData);
int end = mTvDesMeasuredHeight;
if (isAnimation) {
doAnimation(start, end);
} else {
mTvDes.setHeight(end);
}
}
if (isAnimation) {
if (isOpen) {
ObjectAnimator.ofFloat(mIvArrow, "rotation", 180, 0).start();
} else {
ObjectAnimator.ofFloat(mIvArrow, "rotation", 0, 180).start();
}
}
isOpen = !isOpen;
}
public void doAnimation(int start, int end) {
ObjectAnimator animator = ObjectAnimator.ofInt(mTvDes, "height", start, end);
animator.start();
animator.addListener(new AnimatorListener() {
@Override
public void onAnimationStart(Animator arg0) {
}
@Override
public void onAnimationRepeat(Animator arg0) {
}
@Override
public void onAnimationEnd(Animator arg0) {
ViewParent parent = mTvDes.getParent();
while (true) {
parent = parent.getParent();
if (parent == null) {
break;
}
if (parent instanceof ScrollView) {
((ScrollView) parent).fullScroll(View.FOCUS_DOWN);
break;
}
}
}
@Override
public void onAnimationCancel(Animator arg0) {
}
});
}
/**
* @param i 指定行高
* @param data 指定textView的内容
* @return
*/
private int getShortHeight(int i, AppInfoBean data) {
TextView tempTextView = new TextView(UIUtils.getContext());
tempTextView.setLines(7);
tempTextView.setText(data.des);
tempTextView.measure(0, 0);
int measuredHeight = tempTextView.getMeasuredHeight();
return measuredHeight;
}
}