Android-FoldLayout-可折叠布局
FoldLayout.java
package com.fatapp.toolbox.layout; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import com.fatapp.toolbox.R; import java.util.List; public class FoldLayout extends LinearLayout implements View.OnClickListener { private boolean init; private final int layoutId; private boolean isShow; private LinearLayout content; private ValueAnimator showAnimator; private ValueAnimator hideAnimator; private View defaultView; private OnItemClickListener mOnItemClickListener; public FoldLayout(Context context) { this(context, null); } public FoldLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FoldLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); @SuppressLint("Recycle") TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FoldLayout, defStyleAttr, 0); layoutId = ta.getResourceId(R.styleable.FoldLayout_layoutId, -1); init(context); } private void init(Context context) { setOrientation(VERTICAL); addDefaultLayout(context); } /** * Init */ private void addDefaultLayout(Context context) { defaultView = LayoutInflater.from(context).inflate(layoutId, this, true); defaultView.setOnClickListener(this); content = new LinearLayout(context); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); content.setOrientation(VERTICAL); addView(content, layoutParams); } @Override public void onClick(View v) { if (isShow) { hideItem(); } else { showItem(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); initAnimation(); } /** * Animation */ private void initAnimation() { int contentHeight = content.getMeasuredHeight(); if (!init) { showAnimator = ValueAnimator.ofInt(0, contentHeight); showAnimator.addUpdateListener(animation -> { LayoutParams layoutParams = (LayoutParams) content.getLayoutParams(); layoutParams.height = (int) animation.getAnimatedValue(); content.setLayoutParams(layoutParams); }); showAnimator.addListener(new AnimatorListenerAdapter() { @SuppressLint("UseCompatLoadingForDrawables") public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); //展开动画开始事件 } }); hideAnimator = ValueAnimator.ofInt(contentHeight, 0); hideAnimator.addUpdateListener(animation -> { LayoutParams layoutParams = (LayoutParams) content.getLayoutParams(); layoutParams.height = (int) animation.getAnimatedValue(); content.setLayoutParams(layoutParams); }); hideAnimator.addListener(new AnimatorListenerAdapter() { @SuppressLint("UseCompatLoadingForDrawables") @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); //收起动画结束事件 if (!isShow) { //控制圆角 防止动画BUG } } }); init = true; showItem(); //默认展开 } } /** * Add Item */ public void addItemView(List<View> views) { for (int i = 0; i < views.size(); i++) { final int position = i; content.addView(views.get(i)); views.get(i).setOnClickListener(v -> { if (null != mOnItemClickListener) { mOnItemClickListener.onItemClick(v, position); } }); } } @SuppressLint("UseCompatLoadingForDrawables") public void showItem() { isShow = true; showAnimator.start(); } @SuppressLint("UseCompatLoadingForDrawables") public void hideItem() { isShow = false; hideAnimator.start(); } interface OnItemClickListener { void onItemClick(View view, int position); } public void setOnItemClickListener(OnItemClickListener onItemClickListener) { this.mOnItemClickListener = onItemClickListener; } }
attrs.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="FoldLayout"> <attr name="layoutId" format="integer"/> </declare-styleable> </resources>
main.xml
<com.fatapp.toolbox.layout.FoldLayout android:id="@+id/foldLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:layoutId="@layout/fold_layout_head" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" />
fold_layout_head.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/foldLayoutLinearLayout" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:gravity="center_vertical" > <ImageView android:id="@+id/foldLayoutImageView" android:layout_width="0dp" android:layout_height="20dp" android:layout_weight="1" app:srcCompat="" /> <!-- 设置图标 --> <TextView android:id="@+id/foldLayoutTextView" android:layout_width="0dp" android:layout_height="40dp" android:layout_weight="6" android:gravity="center_vertical" android:textColor="@color/black" android:textSize="18sp" android:text="" /> <!-- 设置标题 --> <ImageView android:id="@+id/arrowIcon" android:layout_width="0dp" android:layout_height="15dp" android:layout_weight="1" app:srcCompat="" /> <!-- 设置右边箭头 --> </LinearLayout>
fold_layout_body.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/layout_item_LinearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/transparent" android:orientation="vertical" android:gravity="center_vertical"> <!-- 内容 --> </LinearLayout>
Activity.java
View foldLayoutBody = getLayoutInflater().inflate(R.layout.fold_layout_body, null); List<View> viewList = new ArrayList<>(); viewList.add(foldLayoutBody); foldLayout.addItemView(viewList);
注册Item点击事件
foldlayout.setOnItemClickListener(new FoldLayout.OnItemClickListener() { @Override public void onItemClick(View view, int position) { } });
近期评论