效果如下
代码如下
package com.zjh.baseutillib.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.zjh.baseutillib.R;
/**
* 展开收起布局
* Created by ZJH
* on 2019-05-22
*/
public class ExpandableLayout extends LinearLayout {
private Context mContext;
//点击展开收起的布局
private LinearLayout mHandleView;
//显示隐藏的布局
private LinearLayout mContentView;
//下拉箭头imageView
private ImageView mIconExpand;
//需要改变文字的Text
private TextView mExpandTv;
//内容高度
int mContentHeight = 0;
//点击布局的高度
int mTitleHeight = 0;
//是否展开
private boolean isExpand;
private Animation animationDown;
private Animation animationUp;
//布局下标
private int index;
public static ExpandableLayoutListener listener;
public ExpandableLayout(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext = context;
}
/**
* 获取视图宽高
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mContentView != null && mHandleView != null) {
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);
}
/**
* 初始化
*
* @param mHandleView 点击展开收起的布局
* @param mContentView 内容布局
* @param mIconExpand 显示下拉箭头的imageView
*/
public void init(LinearLayout mHandleView, LinearLayout mContentView,
ImageView mIconExpand, TextView mExpandTv) {
this.mHandleView = mHandleView;
this.mContentView = mContentView;
this.mIconExpand = mIconExpand;
this.mExpandTv = mExpandTv;
//给需要点击展开收起的布局添加点击事件
this.mHandleView.setOnClickListener(new ExpandListener());
isExpand = false;
}
private class ExpandListener implements View.OnClickListener {
@Override
public final void onClick(View paramView) {
//clearAnimation是view的方法
clearAnimation();
if (!isExpand) {
//显示
openWithAnim();
if (listener != null) {
listener.onExpandableClick(index);
}
} else {
//隐藏
closeWithAnim();
}
}
}
/**
* 展开布局
*/
public void openWithAnim() {
if (animationDown == null) {
//初始化动画
animationDown = new DropDownAnim(mContentView,
mContentHeight, true);
animationDown.setDuration(300); //动画时间
}
startAnimation(animationDown);
//更换图片和问题
mIconExpand.setImageResource(R.drawable.update_detail_up);
mExpandTv.setText("收起");
isExpand = true;
}
/**
* 隐藏布局
*/
public void closeWithAnim() {
isExpand = false;
if (animationUp == null) {
//初始化动画
animationUp = new DropDownAnim(mContentView,
mContentHeight, false);
animationUp.setDuration(300); //动画时间
}
startAnimation(animationUp);
//更换图片和图片
mIconExpand.setImageResource(R.drawable.update_detail_down);
mExpandTv.setText("展开");
}
/**
* 自定义动画
*/
class DropDownAnim extends Animation {
/**
* 目标的高度
*/
private int targetHeight;
/**
* 目标view
*/
private View view;
/**
* 是否向下展开
*/
private boolean down;
/**
* 构造方法
*
* @param targetView 需要被展现的view
* @param viewHeight 目的高
* @param isDown true:向下展开,false:收起
*/
DropDownAnim(View targetView, int viewHeight, boolean isDown) {
this.view = targetView;
this.targetHeight = viewHeight;
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;
}
}
/**
* 是否展开
*
* @return isExpand
*/
public boolean isExpand() {
return isExpand;
}
/**
* 收起布局
*/
public void close() {
if (mContentView != null) {
mContentView.setVisibility(View.GONE);
isExpand = false;
}
}
/**
* list中使用
* @param index 下标
*/
public void setListIndex(int index) {
this.index = index;
}
public static void setExpandableLayoutListener(ExpandableLayoutListener exListener) {
listener = exListener;
}
public interface ExpandableLayoutListener {
/**
* 点击了list中哪个布局
*
* @param index 本布局所在list 的下标
*/
public void onExpandableClick(int index);
}
}
代码中使用
/**
* 初始化
*
* @param mHandleView 点击展开收起的布局
* @param mContentView 内容布局
* @param mIconExpand 显示下拉箭头的imageView
* @param mExpandTv 需要更改的文字
*/
public void init(LinearLayout mHandleView, LinearLayout mContentView,
ImageView mIconExpand, TextView mExpandTv) {
this.mHandleView = mHandleView;
this.mContentView = mContentView;
this.mIconExpand = mIconExpand;
this.mExpandTv = mExpandTv;
//给需要点击展开收起的布局添加点击事件
this.mHandleView.setOnClickListener(new ExpandListener());
isExpand = false;
}
@Bind(R.id.content_layout)
LinearLayout contentLayout;
@Bind(R.id.show_layout)
LinearLayout showLayout;
@Bind(R.id.expandable_layout)
ExpandableLayout expandableLayout;
@Bind(R.id.show_img)
ImageView showImg;
@Bind(R.id.show_tv)
TextView showTv;
expandableLayout.init(showLayout, contentLayout, showImg, showTv);