2017-05-12 1 views
4

je besoin d'un RecyclerView comme ceci:RecyclerView - Comment mettre en évidence élément visible central pendant défilement

enter image description here

Il devrait fait:

  • montrent 7 articles par heure (FAITE)

  • centre le RecyclerView sur l'élément central visible (FAIT)

  • quand je défiler à droite/à gauche, l'élément central sera « mis en évidence » (le bouton est sélectionné> couleur bleue) (ont besoin d'aide)

  • lorsque je clique sur un bouton , il sera centré avec un scrool lisse (ont besoin d'aide)

je SnapHelper classe pour centrer le RecyclerView sur les éléments centraux (je récupère l'élément visible central obtenir le plus proche ch ild au centre de l'écran)

MY ADAPTER:

public class RvTrendsGraphAdapter extends RecyclerView.Adapter<RvTrendsGraphAdapter.ViewHolder> { 

    private float deviceWidth; 
    private float itemWidth; 

    private List<RvTrendsGraphModel> models; 
    private Context context; 

    public RvTrendsGraphAdapter(Context context, List<RvTrendsGraphModel> 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); 
    } 

} 

SETUP RECYCLER VIEW:

mLayoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false); 
mRecyclerView.setLayoutManager(mLayoutManager); 

SnapHelper snapHelper = new LinearSnapHelper(); 
snapHelper.attachToRecyclerView(mRecyclerView); 

POPULATE RECYCLER VIEW:

list = new ArrayList<>(); 
/* 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); 

GESTION DES SCROLL:

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); 
       } 
      } 
     }); 

LAYOUT ARTICLE:

<?xml version="1.0" encoding="utf-8"?> 
<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"> 

    <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%"> 

     <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" 
      /> 
    </android.support.percent.PercentRelativeLayout> 

    <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%"> 

     <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"/> 

    </RelativeLayout> 

</android.support.percent.PercentRelativeLayout> 

Répondre

4

Hope this helps -

Notez que ceci est une solution aki, en particulier la mise en évidence sur parchemin. En outre, je n'ai profilé aucune performance. Vous devriez probablement vérifier. J'ai également changé timeLapseButton à TextView depuis la modification de l'arrière-plan sur Button va réduire les autres propriétés de disposition.

Si vous n'aimez pas la solution hacky, vous pouvez consulter quelques bibliothèques de cartes.

ex :) https://github.com/PhilJay/MPAndroidChart

classe Adaptateur

public interface TimeLapseButtonClickListener { 
    void onClick(int position); 
} 

private TimeLapseButtonClickListener timeLapseButtonListener; 

public void setTimeLapseButtonClickListener(TimeLapseButtonClickListener listener) { 
    this.timeLapseButtonListener = listener; 
} 

private void setTimeLapseButton(Button button, String text, final int position) { 
    button.setText(text); 

    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      this.timeLapseButtonListener.onClick(position); 
     } 
    }); 
} 

activité ou Fragment où vous avez recyclerView & adaptateur

... 

private int prevCenterPos; // Keep track the previous pos to dehighlight 

... 

// Click and smooth scroll to get clicked item in the middle 
adapter.setListener(new RvTrendsGraphAdapter.TimeLapseButtonClickListener() { 
    @Override 
    public void onClick(int position) { 
     View view = mRecyclerView.getLayoutManager().findViewByPosition(position); 
     int middle = mRecyclerView.getWidth()/2; 
     mRecyclerView.smoothScrollBy(view.getLeft() - middle, 0, new AccelerateDecelerateInterpolator()); 
    } 
}); 

// Highlight view in the middle on scroll 
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { 

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

     int center = mRecyclerView.getWidth()/2; 
     View centerView = mRecyclerView.findChildViewUnder(center, mRecyclerView.getTop()); 
     int centerPos = mRecyclerView.getChildAdapterPosition(centerView); 

     if (prevCenterPos != centerPos) { 
      // dehighlight the previously highlighted view 
      View prevView = mRecyclerView.getLayoutManager().findViewByPosition(prevCenterPos); 
      if (prevView != null) { 
       View button = prevView.findViewById(R.id.rv_trends_graph_button); 
       int white = ContextCompat.getColor(context, R.color.white); 
       button.setBackgroundColor(white); 
      } 

      // highlight view in the middle 
      if (centerView != null) { 
       View button = centerView.findViewById(R.id.rv_trends_graph_button); 
       int highlightColor = ContextCompat.getColor(context, R.color.colorAccent); 
       button.setBackgroundColor(highlightColor); 
      } 

      prevCenterPos = centerPos; 
     } 
    } 
}); 
+0

Je vais essayer :) vous faire savoir – eldivino87

+0

Vous avez fait ma journée !!! Cela fonctionne parfaitement – eldivino87