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) {
}
});
近期评论