觉得ExpendableListView挺好用,但是就是代码复杂了点,我一时半会理解不了,于是就直接自己写个效果来实现。先来看一下expendableListView中展开的动画效果:
然后我模仿此效果,建立如下的item布局:
android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp">
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
android:id="@+id/titleTextView"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:minHeight="48dp"
android:textSize="20sp"
/>
android:id="@+id/favorBtn"
android:background="@null"
android:minHeight="48dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/favor_normal"/>
android:padding="5dp"
android:layout_margin="5dp"
android:id="@+id/contentTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20sp"
android:visibility="gone"
/>
一个显示的TextView用来显示英文,一个隐藏的TextView用于显示中文,在此ListView的item单击时,显示/隐藏那个中文的TextView。动画效果如下:
public static void animateExpanding(final TextView view) {
view.setVisibility(View.VISIBLE);
//测量高宽
final int widthSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.EXACTLY);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthSpec, heightSpec);
//根据测量结果 创建属性动画
ValueAnimator animator = createHeightAnimator(view, 0, view.getMeasuredHeight());
animator.start();
}
/**
*创建属性动画
**/
public static ValueAnimator createHeightAnimator(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 value = (Integer) valueAnimator.getAnimatedValue();
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = value;
view.setLayoutParams(layoutParams);
}
});
return animator;
}
本来觉得挺简单的效果,但是悲催的发现,如下:
Item一展开,就不知道为啥高度会那么大,如果在测量的时候,对宽度也使用UNSPECIFIED,则会导致中文的的TextView始终为一行,多余的字符不能显示出来。
最终查阅一下,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.EXACTLY);
对于代码中的0所代表的参数是建议宽度,于是尝试将父级view的宽度传入,结果居然好了:
public static void animateExpanding(View parentView,final View view) {
view.setVisibility(View.VISIBLE);
//设置建议宽度为父级view的宽度
final int widthSpec = View.MeasureSpec.makeMeasureSpec(parentView.getWidth(), View.MeasureSpec.EXACTLY);
final int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
view.measure(widthSpec, heightSpec);
// Log.i("SSSS",view.getText().toString()+"||"+view.getLineCount());
// Log.i("SSSS", "Mheight:::" + view.getMeasuredHeight() + "h:" + view.getHeight() + "mW:" + view.getMeasuredWidth() + "w:" + view.getWidth());
ValueAnimator animator = createHeightAnimator(view, 0, view.getMeasuredHeight());
animator.start();
}
于是效果如下:
到这时,大部分的中文都能显示出来正常了,但是仍然有部分的没有换行,所以尝试将传入的View更改为视图中的英文的TextView,并在测量高度时的建议高度设置为英文TextView的高度,终于解决了。
final int heightSpec = View.MeasureSpec.makeMeasureSpec(v.getHeight(), View.MeasureSpec.UNSPECIFIED);