Skip to content

Commit

Permalink
Merge pull request h6ah4i#409 from h6ah4i/feature/improve_drag_effect…
Browse files Browse the repository at this point in the history
…_for_grid_layout

Improve drag & drop behavior for grid layout (related: h6ah4i#393)
  • Loading branch information
h6ah4i authored Aug 1, 2017
2 parents 4f5adaa + 0a90b7f commit fe6df0c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class DraggingItemDecorator extends BaseDraggableItemDecorator {
private boolean mIsScrolling;
private ItemDraggableRange mRange;
private int mLayoutOrientation;
private int mLayoutType;
private DraggingItemInfo mDraggingItemInfo;
private Paint mPaint;
private long mStartMillis;
Expand Down Expand Up @@ -147,18 +148,15 @@ public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state)
final float rotation = getInterpolation(mRotationInterpolator, t) * mTargetDraggingItemRotation;

if (scaleX > 0.0f && scaleY > 0.0f && alpha > 0.0f) {
final int w = mDraggingItemImage.getWidth();
final int h = mDraggingItemImage.getHeight();
final int iw = w - mShadowPadding.left - mShadowPadding.right;
final int ih = h - mShadowPadding.top - mShadowPadding.bottom;

mPaint.setAlpha((int) (alpha * 255));

int savedCount = c.save(Canvas.MATRIX_SAVE_FLAG);

c.translate(mTranslationX + mDraggingItemInfo.grabbedPositionX, mTranslationY + mDraggingItemInfo.grabbedPositionY);
c.scale(scaleX, scaleY);
c.translate((mTranslationX + 0.5f * iw) / scaleX, (mTranslationY + 0.5f * ih) / scaleY);
c.rotate(rotation);
c.translate(-(0.5f * w), -(0.5f * h));
c.translate(-(mShadowPadding.left + mDraggingItemInfo.grabbedPositionX), -(mShadowPadding.top + mDraggingItemInfo.grabbedPositionY));

c.drawBitmap(mDraggingItemImage, 0, 0, mPaint);
c.restoreToCount(savedCount);
}
Expand Down Expand Up @@ -196,6 +194,7 @@ public void start(DraggingItemInfo draggingItemInfo, int touchX, int touchY) {
mTranslationLeftLimit = mRecyclerView.getPaddingLeft();
mTranslationTopLimit = mRecyclerView.getPaddingTop();
mLayoutOrientation = CustomRecyclerViewUtils.getOrientation(mRecyclerView);
mLayoutType = CustomRecyclerViewUtils.getLayoutType(mRecyclerView);

mInitialDraggingItemScaleX = ViewCompat.getScaleX(itemView);
mInitialDraggingItemScaleY = ViewCompat.getScaleY(itemView);
Expand Down Expand Up @@ -391,8 +390,10 @@ private void updateTranslationOffset() {
mTranslationX = mTouchPositionX - mDraggingItemInfo.grabbedPositionX;
mTranslationY = mTouchPositionY - mDraggingItemInfo.grabbedPositionY;

mTranslationX = clip(mTranslationX, mTranslationLeftLimit, mTranslationRightLimit);
mTranslationY = clip(mTranslationY, mTranslationTopLimit, mTranslationBottomLimit);
if (CustomRecyclerViewUtils.isLinearLayout(mLayoutType)) {
mTranslationX = clip(mTranslationX, mTranslationLeftLimit, mTranslationRightLimit);
mTranslationY = clip(mTranslationY, mTranslationTopLimit, mTranslationBottomLimit);
}
}

private static int toSpanAlignedPosition(int position, int spanCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1613,7 +1613,7 @@ private void performSwapItems(RecyclerView rv, @Nullable RecyclerView.ViewHolder
final View fromView = (draggingItemHolder != null) ? draggingItemHolder.itemView : null;
final View toView = swapTargetHolder.itemView;
final View firstView = CustomRecyclerViewUtils.findViewByPosition(layoutManager, firstVisible);
final int rootFromPosition = draggingItemHolder.getLayoutPosition();
final int rootFromPosition = (draggingItemHolder != null) ? draggingItemHolder.getLayoutPosition() : RecyclerView.NO_POSITION;
final int rootToPosition = swapTargetHolder.getLayoutPosition();
final Integer fromOrigin = getItemViewOrigin(fromView, isVertical);
final Integer toOrigin = getItemViewOrigin(toView, isVertical);
Expand Down Expand Up @@ -1798,44 +1798,7 @@ private static RecyclerView.ViewHolder findSwapTargetItemForStaggeredGridLayoutM
}

private static RecyclerView.ViewHolder findSwapTargetItemForGridLayoutManagerInternal1(FindSwapTargetContext fc) {
final int gap = (int) (fc.rv.getContext().getResources().getDisplayMetrics().density * 4);

int cx = fc.overlayItemLeftNotClipped;
int cy = fc.overlayItemTopNotClipped;

cx += (int) (fc.draggingItemInfo.width * 0.5f);
cy += (int) (fc.draggingItemInfo.height * 0.5f);

if (fc.vertical) {
cx = Math.max(cx, fc.rv.getPaddingLeft() + (2 * gap) + 1);
cx = Math.min(cx, fc.rv.getWidth() - fc.rv.getPaddingRight() - (2 * gap) - 1);
} else {
cy = Math.max(cy, fc.rv.getPaddingTop() + (2 * gap) + 1);
cy = Math.min(cy, fc.rv.getHeight() - fc.rv.getPaddingBottom() - (2 * gap) - 1);
}

RecyclerView.ViewHolder vh1 = CustomRecyclerViewUtils.findChildViewHolderUnderWithoutTranslation(fc.rv, cx - gap, cy - gap);
if (vh1 == null || vh1 == fc.draggingItem) {
return vh1;
}
RecyclerView.ViewHolder vh2 = CustomRecyclerViewUtils.findChildViewHolderUnderWithoutTranslation(fc.rv, cx + gap, cy - gap);
if (vh2 == null || vh2 == fc.draggingItem) {
return vh2;
}
RecyclerView.ViewHolder vh3 = CustomRecyclerViewUtils.findChildViewHolderUnderWithoutTranslation(fc.rv, cx - gap, cy + gap);
if (vh3 == null || vh3 == fc.draggingItem) {
return vh3;
}
RecyclerView.ViewHolder vh4 = CustomRecyclerViewUtils.findChildViewHolderUnderWithoutTranslation(fc.rv, cx + gap, cy + gap);
if (vh4 == null || vh4 == fc.draggingItem) {
return vh4;
}

if (!(vh1 == vh2 && vh1 == vh3 && vh1 == vh4)) {
return null;
}

return vh1;
return CustomRecyclerViewUtils.findChildViewHolderUnderWithoutTranslation(fc.rv, fc.lastTouchX, fc.lastTouchY);
}

private static RecyclerView.ViewHolder findSwapTargetItemForGridLayoutManagerInternal2(FindSwapTargetContext fc) {
Expand All @@ -1850,19 +1813,26 @@ private static RecyclerView.ViewHolder findSwapTargetItemForGridLayoutManagerInt
final int columnWidth = (width - paddingLeft - paddingRight) / spanCount;
final int rowHeight = (height - paddingTop - paddingBottom) / spanCount;

final int cx = fc.overlayItemLeft + fc.draggingItemInfo.width / 2;
final int cy = fc.overlayItemTop + fc.draggingItemInfo.height / 2;
final int cx = fc.lastTouchX;
final int cy = fc.lastTouchY;

final int rangeStartIndex = fc.rootAdapterRange.getStart();
final int rangeEndIndex = fc.rootAdapterRange.getEnd();
int scanStartIndex = (int) ((fc.vertical)
? (float) (cx - paddingLeft) / columnWidth
: (float) (cy - paddingTop) / rowHeight);

scanStartIndex = Math.min(Math.max(scanStartIndex, 0), (spanCount - 1));

for (int i = spanCount - 1; i >= 0; i--) {
for (int i = scanStartIndex; i >= 0; i--) {
final int cx2 = (fc.vertical) ? (paddingLeft + (columnWidth * i) + (columnWidth / 2)) : cx;
final int cy2 = (!fc.vertical) ? (paddingTop + (rowHeight * i) + (rowHeight / 2)) : cy;
final RecyclerView.ViewHolder vh2 = CustomRecyclerViewUtils.findChildViewHolderUnderWithoutTranslation(fc.rv, cx2, cy2);

if (vh2 != null) {
final int rangeEndIndex = fc.rootAdapterRange.getEnd();
final int pos = vh2.getAdapterPosition();

if ((pos != RecyclerView.NO_POSITION) && pos == rangeEndIndex) {
if ((pos != RecyclerView.NO_POSITION) && pos >= rangeStartIndex && pos <= rangeEndIndex) {
return vh2;
}
break;
Expand Down

0 comments on commit fe6df0c

Please sign in to comment.