@Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { boolean needsInvalidate = false; if (mTopGlow != null && !mTopGlow.isFinished()) { final int restore = c.save(); if (getClipToPadding(parent)) { c.translate(parent.getPaddingLeft(), parent.getPaddingTop()); } //noinspection ConstantConditions needsInvalidate |= mTopGlow.draw(c); c.restoreToCount(restore); } if (mBottomGlow != null && !mBottomGlow.isFinished()) { final int restore = c.save(); c.rotate(180); if (getClipToPadding(parent)) { c.translate( -parent.getWidth() + parent.getPaddingRight(), -parent.getHeight() + parent.getPaddingBottom()); } else { c.translate(-parent.getWidth(), -parent.getHeight()); } needsInvalidate |= mBottomGlow.draw(c); c.restoreToCount(restore); } if (needsInvalidate) { ViewCompat.postInvalidateOnAnimation(parent); } }
@Override protected Rect getDividerBound(int position, RecyclerView parent, View child) { Rect bounds = new Rect(0, 0, 0, 0); int transitionX = (int) ViewCompat.getTranslationX(child); int transitionY = (int) ViewCompat.getTranslationY(child); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); bounds.top = parent.getPaddingTop() + mMarginProvider.dividerTopMargin(position, parent) + transitionY; bounds.bottom = parent.getHeight() - parent.getPaddingBottom() - mMarginProvider.dividerBottomMargin(position, parent) + transitionY; int dividerSize = getDividerSize(position, parent); if (mDividerType == DividerType.DRAWABLE) { bounds.left = child.getRight() + params.leftMargin + transitionX; bounds.right = bounds.left + dividerSize; } else { bounds.left = child.getRight() + params.leftMargin + dividerSize / 2 + transitionX; bounds.right = bounds.left; } return bounds; }
/** * build the MiniDrawer * * @param ctx * @return */ public View build(Context ctx) { mContainer = new LinearLayout(ctx); if (mInnerShadow) { if (!mInRTL) { mContainer.setBackgroundResource(R.drawable.material_drawer_shadow_left); } else { mContainer.setBackgroundResource(R.drawable.material_drawer_shadow_right); } } // create and append recyclerView mRecyclerView = new RecyclerView(ctx); mContainer.addView( mRecyclerView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); // set the itemAnimator mRecyclerView.setItemAnimator(new DefaultItemAnimator()); // some style improvements on older devices mRecyclerView.setFadingEdgeLength(0); // set the drawing cache background to the same color as the slider to improve performance // mRecyclerView.setDrawingCacheBackgroundColor(UIUtils.getThemeColorFromAttrOrRes(mActivity, // R.attr.material_drawer_background, R.color.material_drawer_background)); mRecyclerView.setClipToPadding(false); // additional stuff mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx)); // adapter mDrawerAdapter = new DrawerAdapter(); mRecyclerView.setAdapter(mDrawerAdapter); // if the activity with the drawer should be fullscreen add the padding for the statusbar if (mDrawer != null && mDrawer.mDrawerBuilder != null && (mDrawer.mDrawerBuilder.mFullscreen || mDrawer.mDrawerBuilder.mTranslucentStatusBar)) { mRecyclerView.setPadding( mRecyclerView.getPaddingLeft(), UIUtils.getStatusBarHeight(ctx), mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom()); } // if the activity with the drawer should be fullscreen add the padding for the navigationBar if (mDrawer != null && mDrawer.mDrawerBuilder != null && (mDrawer.mDrawerBuilder.mFullscreen || mDrawer.mDrawerBuilder.mTranslucentNavigationBar)) { mRecyclerView.setPadding( mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), UIUtils.getNavigationBarHeight(ctx)); } // set the adapter with the items createItems(); return mContainer; }
@Override public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { if (mDivider == null) { super.onDrawOver(c, parent, state); return; } // Initialization needed to avoid compiler warning int left = 0, right = 0, top = 0, bottom = 0, size; int orientation = mOrientation != -1 ? mOrientation : getOrientation(parent); int childCount = parent.getChildCount(); if (orientation == LinearLayoutManager.VERTICAL) { size = mDivider.getIntrinsicHeight(); left = parent.getPaddingLeft(); right = parent.getWidth() - parent.getPaddingRight(); } else { // horizontal size = mDivider.getIntrinsicWidth(); top = parent.getPaddingTop(); bottom = parent.getHeight() - parent.getPaddingBottom(); } for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getTop() - params.topMargin - size; bottom = top + size; } else { // horizontal left = child.getLeft() - params.leftMargin; right = left + size; } mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } // show last divider if (mShowLastDivider && childCount > 0) { View child = parent.getChildAt(childCount - 1); if (parent.getChildAdapterPosition(child) == (state.getItemCount() - 1)) { RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getBottom() + params.bottomMargin; bottom = top + size; } else { // horizontal left = child.getRight() + params.rightMargin; right = left + size; } mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } }
public void drawHorizontal(Canvas c, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } }
/** * 绘制垂直方向的分割线 * * @param c * @param parent */ private void drawVDeraction(Canvas c, RecyclerView parent) { int top = parent.getPaddingTop(); int bottom = parent.getHeight() - parent.getPaddingBottom(); int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); int left = child.getRight() + layoutParams.rightMargin; int right = left + mDivider.getIntrinsicWidth(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } }
/** * 绘制横向 item 分割线 * * @param canvas * @param parent */ private void drawHorizontal(Canvas canvas, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom(); final int childSize = parent.getChildCount(); for (int i = 0; i < childSize; i++) { final View child = parent.getChildAt(i); RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams(); final int left = child.getRight() + layoutParams.rightMargin; final int right = left + mItemSize; canvas.drawRect(left, top, right, bottom, mPaint); } }
private static void updateGlowSize(RecyclerView rv, EdgeEffectCompat topGlow) { int width = rv.getMeasuredWidth(); int height = rv.getMeasuredHeight(); if (getClipToPadding(rv)) { width -= rv.getPaddingLeft() - rv.getPaddingRight(); height -= rv.getPaddingTop() - rv.getPaddingBottom(); } width = Math.max(0, width); height = Math.max(0, height); topGlow.setSize(width, height); }
@Override public void attach(RecyclerView.OnScrollListener scrollListener, RecyclerView recyclerView) { if (scrollListener != null) { recyclerView.setOnScrollListener( new GroupOnScrollListener(scrollListener, mFloatHeaderScrollListener)); } else { recyclerView.setOnScrollListener(mFloatHeaderScrollListener); } recyclerView.setPadding( recyclerView.getPaddingTop(), mAdditionalAdapterHeight, recyclerView.getPaddingRight(), recyclerView.getPaddingBottom()); mRecyclerViews.add(recyclerView); }
private void drawHorizontal(Canvas canvas, RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); for (int i = 1; i < childCount; i++) { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int size = mDivider.getIntrinsicWidth(); final int left = child.getLeft() - params.leftMargin; final int right = left + size; mDivider.setBounds(left, top, right, bottom); mDivider.draw(canvas); } }
public void drawHorizontal(@NonNull Canvas c, @NonNull RecyclerView parent) { final int top = parent.getPaddingTop(); final int bottom = parent.getHeight() - parent.getPaddingBottom(); final int childCount = parent.getChildCount(); IntStream.range(0, childCount) .forEach( i -> { final View child = parent.getChildAt(i); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); }); }
@Override public View getHeader(RecyclerView parent, int position) { long headerId = mAdapter.getHeaderId(position); View header = mHeaderViews.get(headerId); if (header == null) { // TODO - recycle views RecyclerView.ViewHolder viewHolder = mAdapter.onCreateHeaderViewHolder(parent); mAdapter.onBindHeaderViewHolder(viewHolder, position); header = viewHolder.itemView; if (header.getLayoutParams() == null) { header.setLayoutParams( new ViewGroup.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)); } int widthSpec; int heightSpec; if (mOrientationProvider.getOrientation(parent) == LinearLayoutManager.VERTICAL) { widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY); heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED); } else { widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.UNSPECIFIED); heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.EXACTLY); } int childWidth = ViewGroup.getChildMeasureSpec( widthSpec, parent.getPaddingLeft() + parent.getPaddingRight(), header.getLayoutParams().width); int childHeight = ViewGroup.getChildMeasureSpec( heightSpec, parent.getPaddingTop() + parent.getPaddingBottom(), header.getLayoutParams().height); header.measure(childWidth, childHeight); header.layout(0, 0, header.getMeasuredWidth(), header.getMeasuredHeight()); mHeaderViews.put(headerId, header); } return header; }
@Override public void onDrawOver(Canvas canvas, RecyclerView parent, RecyclerView.State state) { int left = parent.getPaddingLeft(); int right = parent.getWidth() - parent.getPaddingRight(); int top = parent.getPaddingTop(); int bottom = parent.getHeight() - parent.getPaddingBottom(); int orientation = getOrientation(parent); int childCount = parent.getChildCount(); for (int i = showFirstDivider ? 0 : 1; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getTop() - params.topMargin; bottom = top - (size / 2); canvas.drawLine(left, bottom, right, bottom, paint); } else { left = child.getLeft() - params.leftMargin; right = left - (size / 2); canvas.drawLine(right, top, right, bottom, paint); } } if (showLastDivider && childCount > 0) { View child = parent.getChildAt(childCount - 1); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); if (orientation == LinearLayoutManager.VERTICAL) { top = child.getBottom() + params.bottomMargin; bottom = top + size; canvas.drawLine(left, bottom, right, bottom, paint); } else { left = child.getRight() + params.rightMargin; right = left + (size / 2); canvas.drawLine(right, top, right, bottom, paint); } } }
public static boolean canRecyclerViewScroll(RecyclerView view) { if (view == null || view.getAdapter() == null || view.getLayoutManager() == null) return false; final RecyclerView.LayoutManager lm = view.getLayoutManager(); final int count = view.getAdapter().getItemCount(); int lastVisible; if (lm instanceof LinearLayoutManager) { LinearLayoutManager llm = (LinearLayoutManager) lm; lastVisible = llm.findLastVisibleItemPosition(); } else { throw new MaterialDialog.NotImplementedException( "Material Dialogs currently only supports LinearLayoutManager. Please report any new layout managers."); } if (lastVisible == -1) return false; /* We scroll if the last item is not visible */ final boolean lastItemVisible = lastVisible == count - 1; return !lastItemVisible || (view.getChildCount() > 0 && view.getChildAt(view.getChildCount() - 1).getBottom() > view.getHeight() - view.getPaddingBottom()); }
private void updateTranslationOffset() { final RecyclerView rv = mRecyclerView; final int childCount = rv.getChildCount(); if (childCount > 0) { mTranslationLeftLimit = 0; mTranslationRightLimit = rv.getWidth() - mDraggingItemInfo.width; mTranslationTopLimit = 0; mTranslationBottomLimit = rv.getHeight() - mDraggingItemInfo.height; switch (mLayoutOrientation) { case CustomRecyclerViewUtils.ORIENTATION_VERTICAL: { mTranslationLeftLimit += rv.getPaddingLeft(); mTranslationRightLimit -= rv.getPaddingRight(); break; } case CustomRecyclerViewUtils.ORIENTATION_HORIZONTAL: { mTranslationTopLimit += rv.getPaddingTop(); mTranslationBottomLimit -= rv.getPaddingBottom(); break; } } mTranslationRightLimit = Math.max(mTranslationLeftLimit, mTranslationRightLimit); mTranslationBottomLimit = Math.max(mTranslationTopLimit, mTranslationBottomLimit); if (!mIsScrolling) { final int firstVisiblePosition = CustomRecyclerViewUtils.findFirstVisibleItemPosition(rv, true); final int lastVisiblePosition = CustomRecyclerViewUtils.findLastVisibleItemPosition(rv, true); final View firstChild = findRangeFirstItem(rv, mRange, firstVisiblePosition, lastVisiblePosition); final View lastChild = findRangeLastItem(rv, mRange, firstVisiblePosition, lastVisiblePosition); switch (mLayoutOrientation) { case CustomRecyclerViewUtils.ORIENTATION_VERTICAL: { if (firstChild != null) { mTranslationTopLimit = Math.min(mTranslationBottomLimit, firstChild.getTop()); } if (lastChild != null) { mTranslationBottomLimit = Math.min(mTranslationBottomLimit, lastChild.getTop()); } break; } case CustomRecyclerViewUtils.ORIENTATION_HORIZONTAL: { if (firstChild != null) { mTranslationLeftLimit = Math.min(mTranslationLeftLimit, firstChild.getLeft()); } if (lastChild != null) { mTranslationRightLimit = Math.min(mTranslationRightLimit, lastChild.getLeft()); } break; } } } } else { mTranslationRightLimit = mTranslationLeftLimit = rv.getPaddingLeft(); mTranslationBottomLimit = mTranslationTopLimit = rv.getPaddingTop(); } mTranslationX = mTouchPositionX - mDraggingItemInfo.grabbedPositionX; mTranslationY = mTouchPositionY - mDraggingItemInfo.grabbedPositionY; mTranslationX = clip(mTranslationX, mTranslationLeftLimit, mTranslationRightLimit); mTranslationY = clip(mTranslationY, mTranslationTopLimit, mTranslationBottomLimit); }