title: RecyclerView - How highlight central visible item during scroll
body: <p>I need a RecyclerView like this:</p>
  
  <p><a href="https://i.stack.imgur.com/r9Qz0.png" rel="noreferrer"><img src="https://i.stack.imgur.com/r9Qz0.png" alt="enter image description here"></a></p>
  
  <p>It should does:</p>
  
  <ul>
  <li><p>show 7 items per time (<em>DONE</em>)</p></li>
  <li><p>center the RecyclerView on the central visible item (<em>DONE</em>)</p></li>
  <li><p>when I scroll to right/left, the central item will be "highlighted" (the button is selected > blue color) (<strong>need HELP</strong>)</p></li>
  <li><p>when I click on a button, it will be centered with a smooth scrool (<strong>need HELP</strong>)</p></li>
  </ul>
  
  <p>I used <code>SnapHelper</code> class to center the RecyclerView on the central items (I retrieve the central visible item getting the nearest child to the screen center)</p>
  
  <p><strong>MY ADAPTER:</strong></p>
  
  <pre><code>public class RvTrendsGraphAdapter extends RecyclerView.Adapter&lt;RvTrendsGraphAdapter.ViewHolder&gt; {
  
      private float deviceWidth;
      private float itemWidth;
  
      private List&lt;RvTrendsGraphModel&gt; models;
      private Context context;
  
      public RvTrendsGraphAdapter(Context context, List&lt;RvTrendsGraphModel&gt; models) {
          this.models = models;
          this.context = context;
      }
  
      private Context getContext() {
          return context;
      }
  
      public class ViewHolder extends RecyclerView.ViewHolder {
          @BindView(R.id.rv_trends_graph_layout) PercentRelativeLayout rootLayout;
          @BindView(R.id.rv_trends_graph_layout_superiore) PercentRelativeLayout layoutSuperiore;
          @BindView(R.id.rv_trends_graph_layout_inferiore) RelativeLayout layoutInferiore;
          @BindView(R.id.rv_trends_graph_vertical_progressbar) ProgressBar verticalProgressBar;
          @BindView(R.id.rv_trends_graph_button) Button timeLapseButton;
  
          public ViewHolder(View itemView) {
              super(itemView);
              ButterKnife.bind(this, itemView);
          }
      }
  
  
      @Override
      public RvTrendsGraphAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
          Context context = parent.getContext();
          LayoutInflater inflater = LayoutInflater.from(context);
          View view = inflater.inflate(R.layout.recycler_trends_graph, parent, false);
  
          // Set the width to show 7 elements
          DisplayMetrics displayMetrics = new DisplayMetrics();
          WindowManager windowmanager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
          windowmanager.getDefaultDisplay().getMetrics(displayMetrics);
          deviceWidth = displayMetrics.widthPixels;
          float progressBarWidth = getContext().getResources().getDimension(R.dimen.picker_time_lapse_progressbar_width);
          itemWidth = ((deviceWidth + progressBarWidth) / 8f + 1f);
          view.getLayoutParams().width = (int) itemWidth;
  
          return new ViewHolder(view);
      }
  
      @Override
      public void onBindViewHolder(RvTrendsGraphAdapter.ViewHolder viewHolder, int position) {
          RvTrendsGraphModel model = models.get(position);
  
          PercentRelativeLayout rootLayout = viewHolder.rootLayout;
          ProgressBar verticalProgressBar = viewHolder.verticalProgressBar;
          Button timeLapseButton = viewHolder.timeLapseButton;
  
          verticalProgressBar.setProgress(model.getProgress());
          setTimeLapseButton(timeLapseButton, model.getTimeLapseValue());
      }
  
      @Override
      public int getItemCount() {
          return models.size();
      }
  
      public RvTrendsGraphModel getItem(int position) {
          return models.get(position);
      }
  
      /* UTILS */
  
      private void setTimeLapseButton(Button button, String text) {
          //button.setSelected(false);
          button.setText(text);
      }
  
  }
  </code></pre>
  
  <p><strong>SETUP RECYCLER VIEW:</strong></p>
  
  <pre><code>mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
  mRecyclerView.setLayoutManager(mLayoutManager);
  
  SnapHelper snapHelper = new LinearSnapHelper();
  snapHelper.attachToRecyclerView(mRecyclerView);
  </code></pre>
  
  <p><strong>POPULATE RECYCLER VIEW:</strong></p>
  
  <pre><code>list = new ArrayList&lt;&gt;();
  /* Create foo list... */
  list.add(new RvTrendsGraphModel(75, String.valueOf(list.size())));
  list.add(new RvTrendsGraphModel(33, String.valueOf(list.size())));
  // ...
  
  adapter = new RvTrendsGraphAdapter(getActivity(), list);
  mRecyclerView.setAdapter(adapter);
  adapter.notifyDataSetChanged();
  
  mRecyclerView.smoothScrollToPosition(list.size() - 1);
  </code></pre>
  
  <p><strong>SCROLL MANAGEMENT:</strong></p>
  
  <pre><code>mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
              @Override
              public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                  // Get adapter position of the central item
                  PercentRelativeLayout root = (PercentRelativeLayout) mRecyclerView.findChildViewUnder(centralX, 0);
                  pos = mRecyclerView.getChildAdapterPosition(root);
  
                  // first try (very bad)
                  if (lastPos != pos) {
                      pos = lastPos;
                      adapter.notifyDataSetChanged();
                  }
  
                  // second try (I cannot call notifyitemchanged during the scroll
                  if () {
                      final int pos = mRecyclerView.getChildAdapterPosition(root);
                      adapter.getItem(pos).setCentered(true);
                      adapter.notifyItemChanged(pos);
                  }
              }
          });
  </code></pre>
  
  <p><strong>ITEM LAYOUT:</strong></p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;android.support.percent.PercentRelativeLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/rv_trends_graph_layout"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:ignore="MissingPrefix"&gt;
  
      &lt;android.support.percent.PercentRelativeLayout
          android:id="@+id/rv_trends_graph_layout_superiore"
          android:layout_width="match_parent"
          android:layout_height="0dp"
          app:layout_heightPercent="75%"&gt;
  
          &lt;ProgressBar
              android:id="@+id/rv_trends_graph_vertical_progressbar"
              style="@style/Widget.ProgressBar.Vertical"
              android:layout_width="@dimen/picker_time_lapse_progressbar_width"
              android:layout_height="match_parent"
              android:layout_alignParentBottom="true"
              android:layout_centerHorizontal="true"
              android:progress="50"
              /&gt;
      &lt;/android.support.percent.PercentRelativeLayout&gt;
  
      &lt;RelativeLayout
          android:id="@+id/rv_trends_graph_layout_inferiore"
          android:layout_width="match_parent"
          android:layout_height="0dp"
          android:layout_below="@+id/rv_trends_graph_layout_superiore"
          app:layout_heightPercent="25%"&gt;
  
          &lt;Button
              android:id="@+id/rv_trends_graph_button"
              fontPath="fonts/Roboto-Light.ttf"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerInParent="true"
              android:background="@drawable/picker_time_lapse_selector"
              android:minHeight="0dp"
              android:minWidth="0dp"
              android:textAllCaps="true"
              android:textColor="@color/picker_time_lapse_text_color_selector"
              android:textSize="@dimen/text_size_medium"
              tools:ignore="ContentDescription"
              tools:text="16"/&gt;
  
      &lt;/RelativeLayout&gt;
  
  &lt;/android.support.percent.PercentRelativeLayout&gt;
  </code></pre>