//主要代码
public class CustomStackLayout extends FrameLayout {
private Adapter mAdapter = Adapter.EMPTY;
private int mCurrentItem;//当前显示的position
private View mParent;
public CustomStackLayout(@NonNull Context context) {
this(context, null, 0);
}
public CustomStackLayout(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomStackLayout(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
mParent = this;
}
public void setAdapter(Adapter adapter) {
mAdapter = adapter;
dataChanged(adapter);
changeCardStyle();
}
//数据更新
private void dataChanged(Adapter adapter) {
for (int i = getmCurrentItem(); i < adapter.getItemCount(); i++) {
if (adapter.getViewHolder(this, i) != null) {
ViewHolder viewHolder = adapter.getViewHolder(CustomStackLayout.this, i);
if (viewHolder.itemView != null) {
addView(viewHolder.itemView, 0);//frameLayout 叠加
}
}
}
}
private void changeCardStyle() {
int offset = -0;
for (int i = getmCurrentItem(); i < this.getChildCount(); i++) {
if (getChildAt(i) != null) {
getChildAt(i).setTranslationY(offset=offset-10);
getChildAt(i).setScaleX(0.8f+0.01f*i);
getChildAt(i).setScaleY(0.8f-0.01f*i);
Log.i("left",""+getChildAt(i).getLeft());
}
}
}
public static abstract class Adapter<VH extends ViewHolder> {
public static Adapter<?> EMPTY = new Adapter<ViewHolder>() {
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int pos) {
return null;
}
@Override
public void onBindViewHolder(ViewHolder viewHolder, int pos) {
}
@Override
public int getItemCount() {
return 0;
}
};
public abstract VH onCreateViewHolder(ViewGroup parent, int pos);
public abstract void onBindViewHolder(VH vh, int pos);
public abstract int getItemCount();
private VH getViewHolder(ViewGroup parent, int position) {
VH viewHolder = onCreateViewHolder(parent, position);
if (viewHolder != null) {
onBindViewHolder(viewHolder, position);
ViewHolder.setPosition(viewHolder.itemView, position);// 标记当前item的index
return viewHolder;
} else {
throw new IllegalArgumentException("viewHolder is null");
}
}
}
public static abstract class ViewHolder {
public View itemView = null;
public ViewHolder(View itemView) {
if (itemView == null) {
throw new IllegalArgumentException("item view may not is null");
}
this.itemView = itemView;
}
private static void setPosition(View view, int pos) {
view.setTag(R.id.pos_tg, pos);
}
public static int getPosition(View view) {
return (int) view.getTag(R.id.pos_tg);
}
}
public void setmCurrentItem(int mCurrentItem) {
this.mCurrentItem = mCurrentItem;
}
public int getmCurrentItem() {
return mCurrentItem;
}
public ViewDragHelper mViewDragHelper = ViewDragHelper.create(this, new ViewDragHelper.Callback() {
@Override
public boolean tryCaptureView(View child, int pointerId) {
return mViewDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE && ViewHolder.getPosition(child) == getmCurrentItem();
}
//捕捉拖动view的left位置
@Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
return left;
}
// 捕捉拖动view的top位置
@Override
public int clampViewPositionVertical(View child, int top, int dy) {
return top;
}
@Override
public int getViewHorizontalDragRange(View child) {
Log.i("parent width",""+mParent.getWidth());
return mParent.getWidth();
}
@Override
public int getViewVerticalDragRange(View child) {
return mParent.getHeight();
}
@Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
int movePercent = left / getWidth();// 向左(-1,0); 向右(0,1)
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
if (Math.abs(releasedChild.getLeft()) < getWidth()/2){
mViewDragHelper.smoothSlideViewTo(releasedChild,0,0);
ViewCompat.postOnAnimation(releasedChild,new SettleRunnable(releasedChild, new Callback() {
@Override
public void onComplete(View view) {
//复位
}
}));
}else{
mViewDragHelper.smoothSlideViewTo(releasedChild,(releasedChild.getLeft() < 0?-1:1)*getWidth(),releasedChild.getTop());
ViewCompat.postOnAnimation(releasedChild,new SettleRunnable(releasedChild, new Callback() {
@Override
public void onComplete(View view) {
//移除
setmCurrentItem(getmCurrentItem()+1);
removeView(view);
}
}));
}
}
});
public ViewDragHelper getDragViewHelper() {
return mViewDragHelper;
}
private class SettleRunnable implements Runnable {
private final View mView;
private final Callback mScrollCallback;
public SettleRunnable(View view, Callback scrollCallback) {
mView = view;
mScrollCallback = scrollCallback;
}
@Override
public void run() {
if (mViewDragHelper != null){
if(mViewDragHelper.continueSettling(true)) {
ViewCompat.postOnAnimation(mView, this); //递归调用
}else{
if(mScrollCallback != null)
mScrollCallback.onComplete(mView);
}
}
}
}
public interface Callback{
void onComplete(View view);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return getDragViewHelper().shouldInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
getDragViewHelper().processTouchEvent(event);
return true;
}
}
下载http://download.csdn.net/detail/u011057161/9914161
本文介绍了一种自定义的堆叠布局实现方法,通过继承FrameLayout并利用ViewDragHelper来实现卡片式的堆叠效果。文章详细展示了如何通过Adapter模式管理布局中的视图,并提供了触摸拖动交互的实现细节。

1065

被折叠的 条评论
为什么被折叠?



