Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add dots under horizontal RecyclerView?

I have RecyclerView which show images as i want

    RecyclerView detailsRecycleImage = (RecyclerView) view.findViewById(R.id.detailsRcycleImage);
     RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(
      getActivity().getApplicationContext(),
      LinearLayoutManager.HORIZONTAL,
      false
    );

    detailsRecycleImage.setLayoutManager(mLayoutManager);
    ImagesAdapter imgAdapter = new 
    ImagesAdapter(getActivity(),contactsData.getContactImages());
    detailsRecycleImage.setAdapter(imgAdapter);  

And my adapter code is

     public class ImagesAdapter extends  RecyclerView.Adapter<ImagesAdapter.MyViewHolder>{
  private Context cnt;
  public ArrayList<String> imgsUrls;
  public ImagesAdapter(Context cnt, ArrayList<String> imgsUrls) {
    this.cnt=cnt;
    this.imgsUrls=imgsUrls;
  }

  @Override
  public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_img,parent,false);

    return new MyViewHolder(itemView);
  }

  @Override
  public void onBindViewHolder(final MyViewHolder holder, int position) {
    String singleImg = imgsUrls.get(position);
    Picasso.with(cnt).load(singleImg).into(holder.img);
  }

  @Override
  public int getItemCount() {
    return imgsUrls.size();
  }


  public class MyViewHolder extends RecyclerView.ViewHolder {
    public ImageView img;

    public MyViewHolder(View view) {
      super(view);
      img = (ImageView) view.findViewById(R.id.img);
    }
  }
}

And my layout is

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

        <ImageView
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:id="@+id/img"
          />
</RelativeLay

I just need to add dots under the recyclerview as an indicator as this image enter image description here enter image description here
Is there any way to add something to my code and get this view ?

like image 944
ahmed saber Avatar asked Apr 27 '17 11:04

ahmed saber


People also ask

How do I add a separator in RecyclerView?

Unlike ListView , the RecyclerView class doesn't have any divider-related parameters. Instead, you need to extend ItemDecoration , a RecyclerView 's inner class: An ItemDecoration allows the application to add a special drawing and layout offset to specific item views from the adapter's data set.

Can RecyclerView be horizontal?

We can make Horizontal RecyclerView or Horizontal Scrolling in RecyclerView in Android using LinearLayoutManager. If you've used LinearLayout, you might have noticed that you can set the layout orientation to both horizontal and vertical.

What is PagerSnapHelper?

OnFlingListener . LinearSnapHelper or PagerSnapHelper are concrete implementations of SnapHelper . They offer most of the functionality needed to implement your custom SnapHelper . Consider extending one of these to suit your needs. For example, LinearSnapHelper snaps to the view closest to the middle of the parent.


1 Answers

I slightly change LinePagerIndicatorDecoration to make it DotsIndicatorDecoration and to support both GridLayoutManager and LinearLayoutManager

public class DotsIndicatorDecoration extends RecyclerView.ItemDecoration {

    private final int indicatorHeight;
    private final int indicatorItemPadding;
    private final int radius;

    private final Paint inactivePaint = new Paint();
    private final Paint activePaint = new Paint();

    public DotsIndicatorDecoration(int radius, int padding, int indicatorHeight, @ColorInt int colorInactive, @ColorInt int colorActive) {
        float strokeWidth = Resources.getSystem().getDisplayMetrics().density * 1;
        this.radius = radius;
        inactivePaint.setStrokeCap(Paint.Cap.ROUND);
        inactivePaint.setStrokeWidth(strokeWidth);
        inactivePaint.setStyle(Paint.Style.STROKE);
        inactivePaint.setAntiAlias(true);
        inactivePaint.setColor(colorInactive);

        activePaint.setStrokeCap(Paint.Cap.ROUND);
        activePaint.setStrokeWidth(strokeWidth);
        activePaint.setStyle(Paint.Style.FILL);
        activePaint.setAntiAlias(true);
        activePaint.setColor(colorActive);

        this.indicatorItemPadding = padding;
        this.indicatorHeight = indicatorHeight;
    }

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

        final RecyclerView.Adapter adapter = parent.getAdapter();

        if (adapter == null) {
            return;
        }

        int itemCount = adapter.getItemCount();

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

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

        drawInactiveDots(c, indicatorStartX, indicatorPosY, itemCount);

        final int activePosition;

        if (parent.getLayoutManager() instanceof GridLayoutManager) {
            activePosition = ((GridLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
        } else if (parent.getLayoutManager() instanceof LinearLayoutManager) {
            activePosition = ((LinearLayoutManager) parent.getLayoutManager()).findFirstVisibleItemPosition();
        } else {
            // not supported layout manager
            return;
        }

        if (activePosition == RecyclerView.NO_POSITION) {
            return;
        }

        // find offset of active page if the user is scrolling
        final View activeChild = parent.getLayoutManager().findViewByPosition(activePosition);
        if (activeChild == null) {
            return;
        }

        drawActiveDot(c, indicatorStartX, indicatorPosY, activePosition);
    }

    private void drawInactiveDots(Canvas c, float indicatorStartX, float indicatorPosY, int itemCount) {
        // width of item indicator including padding
        final float itemWidth = this.radius * 2 + indicatorItemPadding;

        float start = indicatorStartX + radius;
        for (int i = 0; i < itemCount; i++) {
            c.drawCircle(start, indicatorPosY, radius, inactivePaint);
            start += itemWidth;
        }
    }

    private void drawActiveDot(Canvas c, float indicatorStartX, float indicatorPosY,
                               int highlightPosition) {
        // width of item indicator including padding
        final float itemWidth = this.radius * 2 + indicatorItemPadding;
        float highlightStart = indicatorStartX + radius + itemWidth * highlightPosition;
        c.drawCircle(highlightStart, indicatorPosY, radius, activePaint);
    }

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

Usage:

        RecyclerView recyclerView = resourceLayout.getSuccessView().findViewById(R.id.cardsRecyclerView);
        recyclerView.setNestedScrollingEnabled(false);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false));
        recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(manageCardGenericAdapter);
        final int radius = getResources().getDimensionPixelSize(R.dimen.radius);
        final int dotsHeight = getResources().getDimensionPixelSize(R.dimen.dots_height);
        final int color = ContextCompat.getColor(getContext(), R.color.primaryBlue);
        recyclerView.addItemDecoration(new DotsIndicatorDecoration(radius, radius * 4, dotsHeight, color, color));
        new PagerSnapHelper().attachToRecyclerView(recyclerView);
like image 151
Alexey Avatar answered Oct 06 '22 23:10

Alexey