@Override public void getItemOffsets( Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (parent.getChildPosition(view) != 0) { outRect.left = devideSpace; } }
@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent event) { childView = view.findChildViewUnder(event.getX(), event.getY()); childViewPosition = view.getChildPosition(childView); return childView != null && gestureDetector.onTouchEvent(event); }
@Override public void getItemOffsets(Rect outRect, View view, RecyclerView rv, RecyclerView.State state) { super.getItemOffsets(outRect, view, rv, state); debugLog("getItemOffsets"); debugLog("View top = " + view.getTop()); if (selectedDragItemPos != -1) { int itemPos = rv.getChildPosition(view); debugLog("itemPos =" + itemPos); if (!canDragOver(itemPos)) { return; } // Movement of finger float totalMovement = fingerY - fingerAnchorY; if (itemPos == selectedDragItemPos) { view.setVisibility(View.INVISIBLE); } else { // Make view visible incase invisible view.setVisibility(View.VISIBLE); // Find middle of the floatingItem float floatMiddleY = floatingItemBounds.top + floatingItemBounds.height() / 2; // Moving down the list // These will auto-animate if the device continually sends touch motion events // if (totalMovment>0) { if ((itemPos > selectedDragItemPos) && (view.getTop() < floatMiddleY)) { float amountUp = (floatMiddleY - view.getTop()) / (float) view.getHeight(); // amountUp *= 0.5f; if (amountUp > 1) amountUp = 1; outRect.top = -(int) (floatingItemBounds.height() * amountUp); outRect.bottom = (int) (floatingItemBounds.height() * amountUp); } } // Moving up the list // else if (totalMovment < 0) { if ((itemPos < selectedDragItemPos) && (view.getBottom() > floatMiddleY)) { float amountDown = ((float) view.getBottom() - floatMiddleY) / (float) view.getHeight(); // amountDown *= 0.5f; if (amountDown > 1) amountDown = 1; outRect.top = (int) (floatingItemBounds.height() * amountDown); outRect.bottom = -(int) (floatingItemBounds.height() * amountDown); } } } } else { outRect.top = 0; outRect.bottom = 0; // Make view visible incase invisible view.setVisibility(View.VISIBLE); } }
private void updateOnScreenCheckedViews() { final int count = mRecyclerView.getChildCount(); for (int i = 0; i < count; i++) { final View child = mRecyclerView.getChildAt(i); final int position = mRecyclerView.getChildPosition(child); setViewChecked(child, mCheckedStates.get(position)); } }
@Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { View child = rv.findChildViewUnder(e.getX(), e.getY()); if (child != null && clickListener != null && gestureDetector.onTouchEvent(e)) { clickListener.onClick(child, rv.getChildPosition(child)); } return false; }
@Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) { View childView = view.findChildViewUnder(e.getX(), e.getY()); if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) { mListener.onItemClick(childView, view.getChildPosition(childView)); } return false; }
public void addViewToActionMode(final View view) { if (mActionMode == null) { mActionMode = mActivity.startSupportActionMode(this); } final int position = mRecyclerView.getChildPosition(view); if (!mActivatedPositions.contains(position)) { toggleViewActivatedState(view); } }
@Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent event) { View child = rv.findChildViewUnder(event.getX(), event.getY()); if (null != child && null != clickListener && gestureDetector.onTouchEvent(event)) { child.onTouchEvent(event); clickListener.onClick(child, rv.getChildPosition(child)); } return false; }
@Override public boolean onInterceptTouchEvent(android.support.v7.widget.RecyclerView rv, MotionEvent e) { View child = rv.findChildViewUnder(e.getX(), e.getY()); RecyclerView.ViewHolder finalChild = rv.findViewHolderForAdapterPosition(rv.getChildAdapterPosition(child)); if (child != null && clickListener != null && gestureDetector.onTouchEvent(e) == true) { clickListener.onClick(finalChild, rv.getChildPosition(child)); } return false; }
@Override public void getItemOffsets( Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { if (mLeftSpace != -1) outRect.left = (int) mLeftSpace; if (mRightSpace != -1) outRect.right = (int) mRightSpace; if (mBottomSpace != -1) outRect.bottom = (int) mBottomSpace; // Add top margin only for the first item to avoid double space between items if (parent.getChildPosition(view) == 0 && mTopSpace != -1) outRect.top = (int) mTopSpace; }
/* * Detects touch/motion event and fires click listener if onSingleTapUp return true. */ @Override public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent event) { /* * We get the recycler item view on that position because we can't get the view by the index position * due to the logic of the recycler view... because it recycles views... */ View item = view.findChildViewUnder(event.getX(), event.getY()); int res = this.getResult(event); if (item != null && res != PairedDeviceItemClickListener.GESTURE_NONE) { /* * We handle each event. */ if (res == PairedDeviceItemClickListener.GESTURE_TAP_UP) { this.listener.onItemClick(item, view.getChildPosition(item)); } else if (res == PairedDeviceItemClickListener.GESTURE_LONG_PRESS) { this.listener.onItemLongClick(item, view.getChildPosition(item)); } } return false; }
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); LinearLayoutManager lm = (LinearLayoutManager) recyclerView.getLayoutManager(); if (mCenterPivot == 0) { mCenterPivot = lm.getOrientation() == LinearLayoutManager.HORIZONTAL ? (recyclerView.getLeft() + recyclerView.getRight()) : (recyclerView.getTop() + recyclerView.getBottom()); } if (!mAutoSet) { if (newState == RecyclerView.SCROLL_STATE_IDLE) { View view = findCenterView(lm); int position = recyclerView.getChildPosition(view); Log.i("CenterLockListener", "list-position" + position); Toast.makeText(context, "list-position" + position, Toast.LENGTH_SHORT).show(); int viewCenter = lm.getOrientation() == LinearLayoutManager.HORIZONTAL ? (view.getLeft() + view.getRight()) / 2 : (view.getTop() + view.getBottom()) / 2; int scrollNeeded = viewCenter - mCenterPivot; if (lm.getOrientation() == LinearLayoutManager.HORIZONTAL) { recyclerView.smoothScrollBy(scrollNeeded, 0); } else { recyclerView.smoothScrollBy(0, (int) (scrollNeeded)); } mAutoSet = true; } } if (newState == RecyclerView.SCROLL_STATE_DRAGGING || newState == RecyclerView.SCROLL_STATE_SETTLING) { mAutoSet = false; } }
@Override public void getItemOffsets( Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (mDivider == null) { return; } if (parent.getChildPosition(view) < 1) { return; } if (getOrientation(parent) == LinearLayoutManager.VERTICAL) { outRect.top = mDivider.getIntrinsicHeight(); } else { outRect.left = mDivider.getIntrinsicWidth(); } }
private void toggleViewActivatedState(final View view) { final int position = mRecyclerView.getChildPosition(view); if (position == RecyclerView.NO_POSITION) { return; } if (mSelectionMode == SelectionMode.SINGLE) { final boolean checked = mActivatedPositions.contains(position); view.setActivated(!checked); mRecyclerView.getAdapter().notifyItemChanged(position); if (mActivatedPositions.size() > 0) { final int previous = mActivatedPositions.iterator().next(); mActivatedPositions.remove(previous); mRecyclerView.getAdapter().notifyItemChanged(previous); } if (checked) { mActivatedPositions.remove(position); } else { mActivatedPositions.add(position); } onCheckedStateChanged(mActionMode, position, !checked); if (mActivatedPositions.isEmpty()) { finish(); } } else if (mSelectionMode == SelectionMode.MULTIPLE) { final boolean checked = mActivatedPositions.contains(position); view.setActivated(!checked); mRecyclerView.getAdapter().notifyItemChanged(position); if (checked) { mActivatedPositions.remove(position); } else { mActivatedPositions.add(position); } onCheckedStateChanged(mActionMode, position, !checked); if (mActivatedPositions.isEmpty()) { finish(); } } }
/** * Find the new position by scanning through the items on screen and finding the positional * relationship. This *seems* to work, another method would be to use getItemOffsets, but I think * that could miss items?.. */ private int getNewPostion(RecyclerView rv) { int itemsOnScreen = rv.getLayoutManager().getChildCount(); float floatMiddleY = floatingItemBounds.top + floatingItemBounds.height() / 2; int above = 0; int below = Integer.MAX_VALUE; for (int n = 0; n < itemsOnScreen; n++) // Scan though items on screen, however they may not { // be in order! View view = rv.getLayoutManager().getChildAt(n); if (view.getVisibility() != View.VISIBLE) continue; int itemPos = rv.getChildPosition(view); if (itemPos == selectedDragItemPos) // Don't check against itself! continue; float viewMiddleY = view.getTop() + view.getHeight() / 2; if (floatMiddleY > viewMiddleY) // Is above this item { if (itemPos > above) above = itemPos; } else if (floatMiddleY <= viewMiddleY) // Is below this item { if (itemPos < below) below = itemPos; } } debugLog("above = " + above + " below = " + below); if (below != Integer.MAX_VALUE) { if (below < selectedDragItemPos) // Need to count itself below++; return below - 1; } else { if (above < selectedDragItemPos) above++; return above; } }
public void update(RecyclerView referenceList, float dx, float dy) { if (indexList != null && indexList.getChildCount() > 2) { show(); updatePosBasedOnReferenceList(referenceList); View firstVisibleView = indexList.getChildAt(0); View secondVisibleView = indexList.getChildAt(1); TextView firstRowIndex = (TextView) firstVisibleView.findViewById(R.id.section_title); TextView secondRowIndex = (TextView) secondVisibleView.findViewById(R.id.section_title); int visibleRange = indexList.getChildCount(); int actual = indexList.getChildPosition(firstVisibleView); int next = actual + 1; int last = actual + visibleRange; // RESET STICKY LETTER INDEX stickyIndex.setText(String.valueOf(getIndexContext(firstRowIndex)).toUpperCase()); stickyIndex.setVisibility(TextView.VISIBLE); ViewCompat.setAlpha(firstRowIndex, 1); if (dy > 0) { // USER SCROLLING DOWN THE RecyclerView if (next <= last) { if (isHeader(firstRowIndex, secondRowIndex)) { stickyIndex.setVisibility(TextView.INVISIBLE); firstRowIndex.setVisibility(TextView.VISIBLE); ViewCompat.setAlpha( firstRowIndex, (1 - (Math.abs(ViewCompat.getY(firstVisibleView)) / firstRowIndex.getHeight()))); secondRowIndex.setVisibility(TextView.VISIBLE); } else { firstRowIndex.setVisibility(TextView.INVISIBLE); stickyIndex.setVisibility(TextView.VISIBLE); } } } else if (dy < 0) { // USER IS SCROLLING UP THE RecyclerVIew if (next <= last) { // RESET FIRST ROW STATE firstRowIndex.setVisibility(TextView.INVISIBLE); if ((isHeader(firstRowIndex, secondRowIndex) || (getIndexContext(firstRowIndex) != getIndexContext(secondRowIndex))) && isHeader(firstRowIndex, secondRowIndex)) { stickyIndex.setVisibility(TextView.INVISIBLE); firstRowIndex.setVisibility(TextView.VISIBLE); ViewCompat.setAlpha( firstRowIndex, 1 - (Math.abs(ViewCompat.getY(firstVisibleView) / firstRowIndex.getHeight()))); secondRowIndex.setVisibility(TextView.VISIBLE); } else { secondRowIndex.setVisibility(TextView.INVISIBLE); } } } if (stickyIndex.getVisibility() == TextView.VISIBLE) { firstRowIndex.setVisibility(TextView.INVISIBLE); } } else { hide(); } }
@Override public void getItemOffsets( Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { outRect.right = space; if (parent.getChildPosition(view) == 0) outRect.left = space; }
private boolean handleTouchEvent(MotionEvent motionEvent) { if (mViewWidth < 2) { mViewWidth = mRecyclerView.getWidth(); } switch (motionEvent.getActionMasked()) { case MotionEvent.ACTION_DOWN: { if (mPaused) { break; } // Find the child view that was touched (perform a hit test) Rect rect = new Rect(); int childCount = mRecyclerView.getChildCount(); int[] listViewCoords = new int[2]; mRecyclerView.getLocationOnScreen(listViewCoords); int x = (int) motionEvent.getRawX() - listViewCoords[0]; int y = (int) motionEvent.getRawY() - listViewCoords[1]; View child; for (int i = 0; i < childCount; i++) { child = mRecyclerView.getChildAt(i); child.getHitRect(rect); if (rect.contains(x, y)) { mDownView = child; break; } } if (mDownView != null && mAnimatingPosition != mRecyclerView.getChildPosition(mDownView)) { mAlpha = mDownView.getAlpha(); mDownX = motionEvent.getRawX(); mDownY = motionEvent.getRawY(); mDownPosition = mRecyclerView.getChildPosition(mDownView); if (mSwipeListener.canSwipe(mDownPosition)) { mVelocityTracker = VelocityTracker.obtain(); mVelocityTracker.addMovement(motionEvent); } else { mDownView = null; } } break; } case MotionEvent.ACTION_CANCEL: { if (mVelocityTracker == null) { break; } if (mDownView != null && mSwiping) { // cancel mDownView .animate() .translationX(0) .alpha(mAlpha) .setDuration(mAnimationTime) .setListener(null); } mVelocityTracker.recycle(); mVelocityTracker = null; mDownX = 0; mDownY = 0; mDownView = null; mDownPosition = ListView.INVALID_POSITION; mSwiping = false; break; } case MotionEvent.ACTION_UP: { if (mVelocityTracker == null) { break; } mFinalDelta = motionEvent.getRawX() - mDownX; mVelocityTracker.addMovement(motionEvent); mVelocityTracker.computeCurrentVelocity(1000); float velocityX = mVelocityTracker.getXVelocity(); float absVelocityX = Math.abs(velocityX); float absVelocityY = Math.abs(mVelocityTracker.getYVelocity()); boolean dismiss = false; boolean dismissRight = false; if (Math.abs(mFinalDelta) > mViewWidth / 2 && mSwiping) { dismiss = true; dismissRight = mFinalDelta > 0; } else if (mMinFlingVelocity <= absVelocityX && absVelocityX <= mMaxFlingVelocity && absVelocityY < absVelocityX && mSwiping) { // dismiss only if flinging in the same direction as dragging dismiss = (velocityX < 0) == (mFinalDelta < 0); dismissRight = mVelocityTracker.getXVelocity() > 0; } if (dismiss && mDownPosition != mAnimatingPosition && mDownPosition != ListView.INVALID_POSITION) { // dismiss final View downView = mDownView; // mDownView gets null'd before animation ends final int downPosition = mDownPosition; ++mDismissAnimationRefCount; mAnimatingPosition = mDownPosition; mDownView .animate() .translationX(dismissRight ? mViewWidth : -mViewWidth) .alpha(0) .setDuration(mAnimationTime) .setListener( new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { performDismiss(downView, downPosition); } }); } else { // cancel mDownView .animate() .translationX(0) .alpha(mAlpha) .setDuration(mAnimationTime) .setListener(null); } mVelocityTracker.recycle(); mVelocityTracker = null; mDownX = 0; mDownY = 0; mDownView = null; mDownPosition = ListView.INVALID_POSITION; mSwiping = false; break; } case MotionEvent.ACTION_MOVE: { if (mVelocityTracker == null || mPaused) { break; } mVelocityTracker.addMovement(motionEvent); float deltaX = motionEvent.getRawX() - mDownX; float deltaY = motionEvent.getRawY() - mDownY; if (!mSwiping && Math.abs(deltaX) > mSlop && Math.abs(deltaY) < Math.abs(deltaX) / 2) { mSwiping = true; mSwipingSlop = (deltaX > 0 ? mSlop : -mSlop); } if (mSwiping) { mDownView.setTranslationX(deltaX - mSwipingSlop); mDownView.setAlpha( Math.max(0f, Math.min(mAlpha, mAlpha * (1f - Math.abs(deltaX) / mViewWidth)))); return true; } break; } } return false; }
@Override public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { debugLog("onInterceptTouchEvent"); // if (e.getAction() == MotionEvent.ACTION_DOWN) { View itemView = rv.findChildViewUnder(e.getX(), e.getY()); if (itemView == null) return false; boolean dragging = false; if ((dragHandleWidth > 0) && (e.getX() < dragHandleWidth)) { dragging = true; } else if (viewHandleId != -1) { // Find the handle in the list item View handleView = itemView.findViewById(viewHandleId); if (handleView == null) { Log.e(TAG, "The view ID " + viewHandleId + " was not found in the RecycleView item"); return false; } // View should be visible to drag if (handleView.getVisibility() != View.VISIBLE) { return false; } // We need to find the relative position of the handle to the parent view // Then we can work out if the touch is within the handle int[] parentItemPos = new int[2]; itemView.getLocationInWindow(parentItemPos); int[] handlePos = new int[2]; handleView.getLocationInWindow(handlePos); int xRel = handlePos[0] - parentItemPos[0]; int yRel = handlePos[1] - parentItemPos[1]; Rect touchBounds = new Rect( itemView.getLeft() + xRel, itemView.getTop() + yRel, itemView.getLeft() + xRel + handleView.getWidth(), itemView.getTop() + yRel + handleView.getHeight()); if (touchBounds.contains((int) e.getX(), (int) e.getY())) dragging = true; debugLog("parentItemPos = " + parentItemPos[0] + " " + parentItemPos[1]); debugLog("handlePos = " + handlePos[0] + " " + handlePos[1]); } if (dragging) { debugLog("Started Drag"); setIsDragging(true); floatingItem = createFloatingBitmap(itemView); fingerAnchorY = (int) e.getY(); fingerOffsetInViewY = fingerAnchorY - itemView.getTop(); fingerY = fingerAnchorY; selectedDragItemPos = rv.getChildPosition(itemView); debugLog("selectedDragItemPos = " + selectedDragItemPos); return true; } } return false; }
private void updatePosBasedOnReferenceList(RecyclerView referenceRv) { View firstVisibleView = referenceRv.getChildAt(0); int actual = referenceRv.getChildPosition(firstVisibleView); ((LinearLayoutManager) indexList.getLayoutManager()) .scrollToPositionWithOffset(actual, firstVisibleView.getTop() + 0); }