用RecyclerView實現移動應用中常見的列表菜單

  • 摘要:在不少地方咱們都會用到縱向列表樣式的菜單,好比微信首頁的我、發現頁面,微博的首頁的我頁面,QQ的動態頁面等等等等,大多數的應用中都會存在這樣的頁面。咱們怎樣實現這種頁面比較好呢?佈局方案完成這樣的頁面,常見的佈局方案有:1.用ScrollView+LinearLayout很容易的暴力佈局出來,可是這樣獲得的佈局太固定了,若是條目多一點,加載起來很耗時。2.用ListView來實現,這種方案比方案一要好上很多,起碼數據多點的時候,加載時不會太耗時。可是分割線和中間空白在要求差別
  • 在不少地方咱們都會用到縱向列表樣式的菜單,好比微信首頁的我、發現頁面,微博的首頁的我頁面,QQ的動態頁面等等等等,大多數的應用中都會存在這樣的頁面。咱們怎樣實現這種頁面比較好呢?微信

    佈局方案

    完成這樣的頁面,常見的佈局方案有: 
    1. 用ScrollView+LinearLayout很容易的暴力佈局出來,可是這樣獲得的佈局太固定了,若是條目多一點,加載起來很耗時。 
    2. 用ListView來實現,這種方案比方案一要好上很多,起碼數據多點的時候,加載時不會太耗時。可是分割線和中間空白在要求差別化的時候,不太好繪製,用View的話又以爲大材小用。 
    3. 用RecyclerView來實現。RecyclerView作縱向佈局相比ListView在不少方面也更靈活,不管是動畫仍是分割線上。ide

    實現效果佈局

  •  

     

     

     

     

     

    三個圖片中分割線樣式都是比較常見的。學習

使用起來固然是但願以最簡單粗暴的方式去使用好比:動畫

mMenuView.setCutLineLeftPadding(30);
mMenuView.setCutLineRightPadding(30);
mMenuView.setGapLineColor(getResources().getColor(R.color.theme_bg));

MenuBean h=new MenuBean();
//或者直接指定rootView
h.type=R.layout.head_user;
h.menu="美其名曰美";
h.info="天道有常不爲堯存不爲桀亡。";
mMenuView.addMenu(5,h);
mMenuView.addGap(30);
addMenu(11,R.mipmap.ic1,"菜單一","新年新氣象",true);
addMenu(12,R.mipmap.ic2,"菜單二","",false);
addMenu(13,R.mipmap.ic3,"菜單三","發現更好的本身",false);
mMenuView.addGap(30);
addMenu(14,R.mipmap.ic4,"菜單四","",true);
addMenu(15,R.mipmap.ic5,"菜單五","",true);
mMenuView.addGap(30);
addMenu(16,R.mipmap.ic6,"菜單六","",true);
addMenu(17,R.mipmap.ic7,"菜單七","",false);
addMenu(18,R.mipmap.ic8,"菜單八","開心纔是最重要的",true);

具體實現.net

實現這樣的效果若是不考慮分割線的話那麼稍微用過RecyclerView的應該都能顯示這樣的功能因此重點仍是在分割線上了。 
RecyclerView有一個增長分割線的方法addItemDecoration固然這個方法並非只能用來增長分割線。相似微信中通信錄按照ABCD順序排列並分組一樣能夠用這個方法來實現。 
直接貼上自定義的分割線的代碼在代碼中解釋:3d

class MenuDecoration extends RecyclerView.ItemDecoration{

 //onDraw在每次重繪時都會調用好比滑動RecyclerView
 //gap線爲從左到右的完整線條在最開始的item上最後的item下或者空白區域的上下
 //cut線爲兩個緊密挨着的兩個item之間的線條
 @Override
 public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
  super.onDraw(c, parent, state);
  //當第一個Item可見的時候給第一個Item頂上繪一條Gap線
  //不用完整可見才繪製考慮設置paddingTop+clipPadding=false的狀況
  if(mLayout.findFirstVisibleItemPosition()==0){
   int bottom=parent.getChildAt(0).getTop();
   paint.setColor(gapLineColor);
   c.drawLine(parent.getLeft(),bottom-halfLineHeight,parent.getRight(),bottom-halfLineHeight,paint);
  }
  int count=parent.getChildCount();
  int gap;
  int end=mData.size()-1;
  //全部可見的Item下面畫線
  for (int i=0;i<count;i++){
   final View child = parent.getChildAt(i);
   int position=mLayout.getPosition(child);
   gap=mGap.get(position);
   float startY=child.getBottom()+halfLineHeight;
   //View下面不存在gap且不是最好一個Item的時候繪製Cut線不然繪製gap線
   if(gap==0&&position!=end){ 
    //繪製cut線的左邊線條
    if(leftPaddingLine!=0){
     paint.setColor(foreLineColor);
     c.drawLine(parent.getLeft(),startY,parent.getLeft()+leftPaddingLine,startY,paint);
    }
    //繪製cut線的右邊線條
    if(rightPaddingLine!=0){
     paint.setColor(foreLineColor);
     c.drawLine(parent.getRight()-rightPaddingLine,startY,parent.getRight(),startY,paint);
    }
    //繪製cut線的中間線條
    paint.setColor(cutLineColor);
    c.drawLine(parent.getLeft()+leftPaddingLine,startY,parent.getRight()-rightPaddingLine,startY,paint);
   }else{
    paint.setColor(gapLineColor);
    //繪製gap上面的一條線
    c.drawLine(parent.getLeft(),child.getBottom()+halfLineHeight,parent.getRight(),child.getBottom()+halfLineHeight,paint);
    //若是不是最後一個item繪製gap下面的一條線
    if(position<end){
     c.drawLine(parent.getLeft(),child.getBottom()+gap+halfLineHeight,parent.getRight(),child.getBottom()+gap+halfLineHeight,paint);
    }
   }
  }
 }

 //在每一個item加載時調用用來判斷設置每一個item上下左邊的空白區域設置內容分別設置到outRect中
 @Override
 public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
  super.getItemOffsets(outRect, view, parent, state);
  int position=mLayout.getPosition(view);
  //若是是第一個Item則設置上線條高度不然不設置上線條高度
  //爲每一個item設置下邊線條+gap(若是有的話沒有就爲0)的高度
  //四個參數分別爲左邊空白區域上方空白區域右邊空白區域下方空白區域
  outRect.set(0, position != 0 ? 0 : (int)(halfLineHeight * 2+0.5f),0,(int)(halfLineHeight*2+0.5f)+mGap.get(position));
 }
}

這樣咱們就獲得了一個用來繪製分割線的類了。在須要插入空白的地方addGap並傳入gap的高度:blog

public void addGap(int height){
 mGap.put(mData.size()-1,height);
}

這樣分割線和空白的問題就解決了。其餘的就是RecyclerView的簡單使用了爲了使用方便咱們對RecyclerView和其Adapter簡單封裝一下就能實現用addMenu的方式增長菜單項了。圖片

以上就是本文的所有內容但願對你們的學習有所幫助也但願你們多多支持腳本之家。ip

 

https://blog.csdn.net/junzia/article/details/53731586

相關文章
相關標籤/搜索