简体   繁体   中英

Vertical Indicator for Recycler View

Please see this i have similar vertical recycler view but i want an effect similar to smart tab layout link below on scroll I have two recyclerviews both vertical. I am scrolling Recycler View 1 to next position whenever I scroll 10 items in Recycler view 2.

using this

rec2.addOnScrollListener(new RecyclerView.OnScrollListener() {


        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);

            int currFirstPos = mLayoutManager4.findFirstCompletelyVisibleItemPosition();
            int currLastPos = mLayoutManager4.findLastCompletelyVisibleItemPosition();
            if (oldFirstPos==-1){
                totalItemsViewed = totalItemsViewed+currLastPos - currFirstPos + 1;
            }
            else{
                if (dy>0){
                    totalItemsViewed= totalItemsViewed+currLastPos - oldLastPos;
                 //   Toast.makeText(getContext(), "total item viewed"+totalItemsViewed, Toast.LENGTH_SHORT).show();
                    changeState(totalItemsViewed,"up");
                }else {
                    totalItemsViewed=totalItemsViewed+currFirstPos - oldFirstPos;
                 //   Toast.makeText(getContext(), "total item viewed"+totalItemsViewed, Toast.LENGTH_SHORT).show();
                    changeState(totalItemsViewed,"down");
                }
            }
            oldLastPos = currLastPos;
            oldFirstPos = currFirstPos;
        }
    });

change state method to scroll the imageRecycler view to a position and change the image to show the selected Image in the recycler view.

private void changeState(int position,String direction){
    if (position<7){
        adapter.changeImage(1);
        catImageRec.scrollToPosition(1);
    }
  // and the rest of the code 
}

I want to create a Vertical Indicator for my Recycler View1 to achieve this sort of effect. ![Indicator] https://raw.githubusercontent.com/ogaclejapan/SmartTabLayout/master/art/demo4.gif

So I thought of using item decorations and found this code here but it's for horizontal indicators and also it's not showing indicator inside the viewholder but over the recycler view

public class CirclePagerIndicatorDecoration extends RecyclerView.ItemDecoration {
private int colorActive = 0xDE000000;
private int colorInactive = 0x33000000;

private static final float DP = Resources.getSystem().getDisplayMetrics().density;

/**
 * Height of the space the indicator takes up at the bottom of the view.
 */
private final int mIndicatorHeight = (int) (DP * 16);

/**
 * Indicator stroke width.
 */
private final float mIndicatorStrokeWidth = DP * 4;

/**
 * Indicator width.
 */
private final float mIndicatorItemLength = DP * 4;
/**
 * Padding between indicators.
 */
private final float mIndicatorItemPadding = DP * 8;

/**
 * Some more natural animation interpolation
 */
private final Interpolator mInterpolator = new AccelerateDecelerateInterpolator();

private final Paint mPaint = new Paint();

public CirclePagerIndicatorDecoration() {

    mPaint.setStrokeWidth(mIndicatorStrokeWidth);
    mPaint.setStyle(Paint.Style.STROKE);
    mPaint.setAntiAlias(true);
}

@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
    super.onDrawOver(c, parent, state);

    int itemCount = parent.getAdapter().getItemCount();

    // center horizontally, calculate width and subtract half from center
    float totalLength = mIndicatorItemLength * itemCount;
    float paddingBetweenItems = Math.max(0, itemCount - 1) * mIndicatorItemPadding;
    float indicatorTotalWidth = totalLength + paddingBetweenItems;
    float indicatorStartX = (parent.getWidth() - indicatorTotalWidth) / 2F;

    // center vertically in the allotted space
    float indicatorPosY = parent.getHeight() - mIndicatorHeight / 2F;

    drawInactiveIndicators(c, indicatorStartX, indicatorPosY, itemCount);

    // find active page (which should be highlighted)
    LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
    int activePosition = layoutManager.findFirstVisibleItemPosition();
    if (activePosition == RecyclerView.NO_POSITION) {
        return;
    }

    // find offset of active page (if the user is scrolling)
    final View activeChild = layoutManager.findViewByPosition(activePosition);
    int left = activeChild.getLeft();
    int width = activeChild.getWidth();
    int right = activeChild.getRight();

    // on swipe the active item will be positioned from [-width, 0]
    // interpolate offset for smooth animation
    float progress = mInterpolator.getInterpolation(left * -1 / (float) width);

    drawHighlights(c, indicatorStartX, indicatorPosY, activePosition, progress);
}

private void drawInactiveIndicators(Canvas c, float indicatorStartX, float indicatorPosY, int itemCount) {
    mPaint.setColor(colorInactive);

    // width of item indicator including padding
    final float itemWidth = mIndicatorItemLength + mIndicatorItemPadding;

    float start = indicatorStartX;
    for (int i = 0; i < itemCount; i++) {

        c.drawCircle(start, indicatorPosY, mIndicatorItemLength / 2F, mPaint);

        start += itemWidth;
    }
}

private void drawHighlights(Canvas c, float indicatorStartX, float indicatorPosY,
                            int highlightPosition, float progress) {
    mPaint.setColor(colorActive);

    // width of item indicator including padding
    final float itemWidth = mIndicatorItemLength + mIndicatorItemPadding;

    if (progress == 0F) {
        // no swipe, draw a normal indicator
        float highlightStart = indicatorStartX + itemWidth * highlightPosition;

        c.drawCircle(highlightStart, indicatorPosY, mIndicatorItemLength / 2F, mPaint);

    } else {
        float highlightStart = indicatorStartX + itemWidth * highlightPosition;
        // calculate partial highlight
        float partialLength = mIndicatorItemLength * progress + mIndicatorItemPadding*progress;

        c.drawCircle(highlightStart + partialLength, indicatorPosY, mIndicatorItemLength / 2F, mPaint);
    }
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    super.getItemOffsets(outRect, view, parent, state);
    outRect.bottom = mIndicatorHeight;
}

}

try this way

<android.support.v7.widget.RecyclerView
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:scrollbars="vertical" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM