1. 程式人生 > >Android-->RecyclerView分組懸浮標題(分割線)

Android-->RecyclerView分組懸浮標題(分割線)

RecyclerView中實現分組功能, 和 實現分割線 使用的是相同原理. 就是手動繪製資訊.

都是繼承RecyclerView.ItemDecoration

1:為分組資訊騰出空間

//這個方法就是用來描述是否需要給第二個引數view的上下左右騰出空間.
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
    final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();//佈局管理器
if (!(layoutManager instanceof LinearLayoutManager)) { throw new IllegalArgumentException("暫不支援 " + layoutManager.getClass().getSimpleName()); } if (mGroupCallBack == null) { return; } final RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams(); final
int adapterPosition = layoutParams.getViewAdapterPosition(); if (adapterPosition == 0) { //第一個位置, 肯定是有分組資訊的 //我這裡需要支援橫向和豎向,所以加了方向判斷.可以取消掉. if (((LinearLayoutManager) layoutManager).getOrientation() == LinearLayoutManager.HORIZONTAL) { //為左邊騰出空間 outRect.set(mGroupCallBack.getGroupHeight(), 0
, 0, 0); } else { //為上邊騰出空間 outRect.set(0, mGroupCallBack.getGroupHeight(), 0, 0); } } else { //上一個分組資訊 String preGroupText = mGroupCallBack.getGroupText(adapterPosition - 1); //當前的分組資訊 String groupText = mGroupCallBack.getGroupText(adapterPosition); if (!TextUtils.equals(preGroupText, groupText)) { //如果和上一個分組資訊不相等 if (((LinearLayoutManager) layoutManager).getOrientation() == LinearLayoutManager.HORIZONTAL) { outRect.set(mGroupCallBack.getGroupHeight(), 0, 0, 0); } else { outRect.set(0, mGroupCallBack.getGroupHeight(), 0, 0); } } } }

2:空間已經給出來了,那麼就是繪製你想要的資訊了

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
  if (mGroupCallBack == null) {
      return;
  }

//需要注意的就是, 繪製是從螢幕上佈局了多少個子View開始的.
//也就是說, 你並不需要考慮不在螢幕上View的情況.
//通過parent.getChildCount()拿到的就是螢幕上佈局了多少個子View的數量
  for (int i = 0; i < parent.getChildCount(); i++) {
      final View view = parent.getChildAt(i);
      final RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
      final int adapterPosition = layoutParams.getViewAdapterPosition();
      if (adapterPosition == 0) {
          //第一個位置, 肯定是有分組資訊的
          mGroupCallBack.onGroupDraw(c, view, adapterPosition);
      } else {
          //上一個分組資訊
          String preGroupText = mGroupCallBack.getGroupText(adapterPosition - 1);
          //當前的分組資訊
          String groupText = mGroupCallBack.getGroupText(adapterPosition);
          if (!TextUtils.equals(preGroupText, groupText)) {
              //如果和上一個分組資訊不相等
              mGroupCallBack.onGroupDraw(c, view, adapterPosition);
          }
      }
  }
}

通過以上2個方法, 已經可以實現分割線了.

如果需要懸停效果, 那麼就繼續往下看.

3:懸停效果
onDrawOver方法和onDraw方法完全一樣. 只不過名字不一樣而已.
你完全可以在onDraw方法中, 實現.
但是官方竟然給了我們這種方法, 而且名字都取得那麼好…我們又有什麼理由不使用呢?

@Override
 public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {
     if (mGroupCallBack == null || parent.getChildCount() <= 0) {
         return;
     }

     boolean isHorizontal = ((LinearLayoutManager) parent.getLayoutManager()).getOrientation() == LinearLayoutManager.HORIZONTAL;

     final View view = parent.getChildAt(0);
     final RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) view.getLayoutParams();
     final int adapterPosition = layoutParams.getViewAdapterPosition();
     if (adapterPosition == 0) {
         //第一個位置, 肯定是有分組資訊的
         if ((isHorizontal ? view.getLeft() : view.getTop()) <= 0) {
             mGroupCallBack.onGroupOverDraw(c, view, adapterPosition, 0);
         } else {
             mGroupCallBack.onGroupOverDraw(c, view, adapterPosition, mGroupCallBack.getGroupHeight() - (isHorizontal ? view.getLeft() : view.getTop()));
         }
     } else {
         if (parent.getLayoutManager().getItemCount() > adapterPosition + 1) {
             //下一個分組資訊
             String nextGroupText = mGroupCallBack.getGroupText(adapterPosition + 1);
             //當前的分組資訊
             String groupText = mGroupCallBack.getGroupText(adapterPosition);

             final View nextView = parent.getChildAt(1);
             if (!TextUtils.equals(nextGroupText, groupText)) {
                 if ((isHorizontal ? nextView.getLeft() : nextView.getTop()) <= 0) {
                     mGroupCallBack.onGroupOverDraw(c, view, adapterPosition, 0);
                 } else {
                     mGroupCallBack.onGroupOverDraw(c, view, adapterPosition,
                             Math.max(0, 2 * mGroupCallBack.getGroupHeight() - (isHorizontal ? nextView.getLeft() : nextView.getTop())));
                 }
             } else {
                 mGroupCallBack.onGroupOverDraw(c, view, adapterPosition, 0);
             }
         } else {
             mGroupCallBack.onGroupOverDraw(c, view, adapterPosition, 0);
         }
     }
 }

至此: 文章就結束了,如有疑問: QQ群 Android:274306954 Swift:399799363 歡迎您的加入.