自定义动画实现折叠布局效果(类似于多级列表单个item的效果)

功能简介

已实现的功能点:

1. 子视图显示时,点击父控件,子视图向上折叠消失,箭头向下;

2.子视图不显示时,点击父控件,子视图向下折叠展开,箭头向上;

效果图

输入图片说明

外部调用

外部调用代码

elType = (ExpandableLayout)findViewById(R.id.ex_layout_type);
flType= (LinearLayout) findViewById(R.id.father_llayout_type);
clType = (LinearLayout) findViewById(R.id.child_content_llayout_type);
ivDropType = (ImageView) findViewById(R.id.iv_drop_icon_type);
		
//步骤: 先后台请求数据,请求成功后,再调用init 方法
elType.init(flType, clType, ivDropType);//参数依次为:父布局,子布局,显示箭头的imageView控件

代码

package com.example.cp.mileager.View;


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 com.example.cp.mileager.R;

/**
 * 可折叠布局
 */
public class ExpandableLayout extends LinearLayout {

	private Context mContext;
	private LinearLayout mHandleView;
	private LinearLayout mContentView;
	private ImageView mIconExpand;
	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;
	}

	public void setListIndex(int index){
		this.index = index;
	}

/**
 * 获取视图宽高
 */
	@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) {
		this.mHandleView = mHandleView;
		this.mContentView = mContentView;
		this.mIconExpand = mIconExpand;

		this.mHandleView.setOnClickListener(new ExpandListener());
		isExpand = true;
	}

	public boolean isExpand(){
		return  isExpand;
	}

	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); // SUPPRESS CHECKSTYLE
		}
		startAnimation(animationDown);

		mIconExpand.setImageResource(R.drawable.update_detail_up);
		isExpand = true;
	}

	public void closeWithAnim(){
		isExpand = false;
		if (animationUp == null) {
			animationUp = new DropDownAnim(mContentView,
					mContentHeight, false);
			animationUp.setDuration(300); // SUPPRESS CHECKSTYLE
		}
		startAnimation(animationUp);
		mIconExpand.setImageResource(R.drawable.update_detail_down);
	}

	public void close(){
		if(mContentView != null){
		    mContentView.setVisibility(View.GONE);
			isExpand = false;
		}
	}

	/**
	 * 自定义动画
	 */
	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;
		}
	}

	public static void  setExpandableLayoutListener(ExpandableLayoutListener exListener){
		listener = exListener;
	}

	public interface ExpandableLayoutListener {
		/**
		 *  点击了list中哪个布局
		 * @param index  本布局所在list 的下标
		 */
		public void onExpandableClick(int index);
	}

}


转载于:https://my.oschina.net/fltsp/blog/1528475

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YCExpandView01.该库介绍02.效果展示03.如何使用04.注意要点05.优化问题06.部分代码逻辑01.该库介绍自定义折叠和展开布局,在不用改变原控件的基础上,就可以实现折叠展开功能,入侵性极低。主要的思路是,设置一个折叠时的布局高度,设置一个内容展开时的高度,然后利用属性动画去动态改变布局的高度。可以设置折叠和展开的监听事件,方便开发者拓展其他需求。可以设置动画的时间。可以支持支持常见的文本折叠,流失布局标签折叠,或者RecyclerView折叠等功能。十分方便,思路也比较容易理解,代码不超过300行……02.效果展示03.如何使用设置文本控件      如何切换展开和折叠//初始化操作 expand.initExpand(false ,mHeight); //设置动画时间 expand.setAnimationDuration(300); //折叠或者展开操作后的监听 expand.setOnToggleExpandListener(new ExpandLayout.OnToggleExpandListener() {     @Override     public void onToggleExpand(boolean isExpand) {         if (isExpand){             ivExpand.setBackgroundResource(R.mipmap.icon_btn_collapse);         }else {             ivExpand.setBackgroundResource(R.mipmap.icon_btn_expand);         }     } }); //折叠view expand.collapse(); //展开view expand.expand(); //查看控件是折叠还是展开状态 expand.isExpand(); //这个是置反操作 expand.toggleExpand();04.注意要点05.优化问题1.在从折叠状态到伸展状态,或者反之。只要是在动画过程中,则执行动画的过程中屏蔽事件传递2.当控件销毁后,在onDetachedFromWindow方法中,手动销毁动画3.针对折叠和伸展状态之间切换,如果动画在执行中,即使调用多次toggleExpand()方法,避免频繁调用collapse或者expand4.如果开发者使用该折叠控件时,设置折叠时的高度为0,则会抛出异常
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值