/** 点击按钮消失动画 */ private void vanishOnBtnClick(int type) { synchronized (obj1) { View animateView = viewList.get(0); if (animateView.getVisibility() != View.VISIBLE || releasedViewList.contains(animateView)) { return; } int finalX = 0; if (type == VANISH_TYPE_LEFT) { finalX = -childWith; } else if (type == VANISH_TYPE_RIGHT) { finalX = allWidth; } if (finalX != 0) { releasedViewList.add(animateView); if (mDragHelper.smoothSlideViewTo(animateView, finalX, initCenterViewY + allHeight)) { ViewCompat.postInvalidateOnAnimation(this); } } if (type >= 0 && cardSwitchListener != null) { cardSwitchListener.onCardVanish(isShowing, type); } } }
/** * 本来想写成Adapter适配,想想还是算了,这种比较简单 * * @param dataList 数据 */ public void fillData(List<CardDataItem> dataList) { this.dataList = dataList; int num = viewList.size(); for (int i = 0; i < num; i++) { CardItemView itemView = (CardItemView) viewList.get(i); itemView.fillData(dataList.get(i)); itemView.setVisibility(View.VISIBLE); } if (null != cardSwitchListener) { cardSwitchListener.onShow(0); } }
/** 对View重新排序 */ private void orderViewStack() { synchronized (obj1) { if (releasedViewList.size() == 0) { return; } CardItemView changedView = (CardItemView) releasedViewList.get(0); if (changedView.getLeft() == initCenterViewX) { return; } // 1. 消失的卡片View位置重置 changedView.offsetLeftAndRight(initCenterViewX - changedView.getLeft()); changedView.offsetTopAndBottom(initCenterViewY - changedView.getTop() + yOffsetStep * 2); float scale = 1.0f - SCALE_STEP * 2; changedView.setScaleX(scale); changedView.setScaleY(scale); // 2. 卡片View在ViewGroup中的顺次调整 int num = viewList.size(); for (int i = num - 1; i > 0; i--) { View tempView = viewList.get(i); tempView.bringToFront(); } // 3. changedView填充新数据 int newIndex = isShowing + 4; if (newIndex < dataList.size()) { CardDataItem dataItem = dataList.get(newIndex); changedView.fillData(dataItem); } else { changedView.setVisibility(View.INVISIBLE); } // 4. viewList中的卡片view的位次调整 viewList.remove(changedView); viewList.add(changedView); releasedViewList.remove(0); // 5. 更新showIndex、接口回调 if (isShowing + 1 < dataList.size()) { isShowing++; } if (null != cardSwitchListener) { cardSwitchListener.onShow(isShowing); } } }
/** * 松手时处理滑动到边缘的动画 * * @param xvel X方向上的滑动速度 */ private void animToSide(View changedView, float xvel, float yvel) { int finalX = initCenterViewX; int finalY = initCenterViewY; int flyType = -1; // 1. 下面这一坨计算finalX和finalY,要读懂代码需要建立一个比较清晰的数学模型才能理解,不信拉倒 int dx = changedView.getLeft() - initCenterViewX; int dy = changedView.getTop() - initCenterViewY; if (dx == 0) { // 由于dx作为分母,此处保护处理 dx = 1; } if (xvel > X_VEL_THRESHOLD || dx > X_DISTANCE_THRESHOLD) { finalX = allWidth; finalY = dy * (childWith + initCenterViewX) / dx + initCenterViewY; flyType = VANISH_TYPE_RIGHT; } else if (xvel < -X_VEL_THRESHOLD || dx < -X_DISTANCE_THRESHOLD) { finalX = -childWith; finalY = dy * (childWith + initCenterViewX) / (-dx) + dy + initCenterViewY; flyType = VANISH_TYPE_LEFT; } // 如果斜率太高,就折中处理 if (finalY > allHeight) { finalY = allHeight; } else if (finalY < -allHeight / 2) { finalY = -allHeight / 2; } // 如果没有飞向两侧,而是回到了中间,需要谨慎处理 if (finalX != initCenterViewX) { releasedViewList.add(changedView); } // 2. 启动动画 if (mDragHelper.smoothSlideViewTo(changedView, finalX, finalY)) { ViewCompat.postInvalidateOnAnimation(this); } // 3. 消失动画即将进行,listener回调 if (flyType >= 0 && cardSwitchListener != null) { cardSwitchListener.onCardVanish(isShowing, flyType); } }