最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RecyclerView實(shí)現(xiàn)常見(jiàn)的列表菜單

 更新時(shí)間:2016年12月19日 08:50:53   作者:湖廣午王  
這篇文章主要為大家詳細(xì)介紹了用RecyclerView實(shí)現(xiàn)移動(dòng)應(yīng)用中常見(jiàn)的列表菜單,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

在很多地方我們都會(huì)用到縱向列表樣式的菜單,比如微信首頁(yè)的我、發(fā)現(xiàn)頁(yè)面,微博的首頁(yè)的我頁(yè)面,QQ的動(dòng)態(tài)頁(yè)面等等等等,大多數(shù)的應(yīng)用中都會(huì)存在這樣的頁(yè)面。我們?cè)鯓訉?shí)現(xiàn)這種頁(yè)面比較好呢?

布局方案

完成這樣的頁(yè)面,常見(jiàn)的布局方案有:
1. 用ScrollView+LinearLayout很容易的暴力布局出來(lái),但是這樣得到的布局太固定了,如果條目多一點(diǎn),加載起來(lái)很耗時(shí)。
2. 用ListView來(lái)實(shí)現(xiàn),這種方案比方案一要好上不少,起碼數(shù)據(jù)多點(diǎn)的時(shí)候,加載時(shí)不會(huì)太耗時(shí)。但是分割線(xiàn)和中間空白在要求差異化的時(shí)候,不太好繪制,用View的話(huà)又覺(jué)得大材小用。
3. 用RecyclerView來(lái)實(shí)現(xiàn)。RecyclerView做縱向布局相比ListView在很多方面也更靈活,無(wú)論是動(dòng)畫(huà)還是分割線(xiàn)上。

實(shí)現(xiàn)效果

左空白

無(wú)空白

微信樣式

三個(gè)圖片中分割線(xiàn)樣式都是比較常見(jiàn)的。

使用起來(lái)當(dāng)然是希望以最簡(jiǎn)單粗暴的方式去使用,比如:

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,"菜單三","發(fā)現(xiàn)更好的自己",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,"菜單八","開(kāi)心才是最重要的",true);

具體實(shí)現(xiàn)

實(shí)現(xiàn)這樣的效果,如果不考慮分割線(xiàn)的話(huà),那么稍微用過(guò)RecyclerView的應(yīng)該都能顯示這樣的功能,所以重點(diǎn)還是在分割線(xiàn)上了。
RecyclerView有一個(gè)增加分割線(xiàn)的方法addItemDecoration,當(dāng)然,這個(gè)方法并不是只能用來(lái)增加分割線(xiàn)。類(lèi)似微信中通訊錄按照ABCD順序排列,并分組同樣可以用這個(gè)方法來(lái)實(shí)現(xiàn)。
直接貼上自定義的分割線(xiàn)的代碼,在代碼中解釋?zhuān)?/p>

class MenuDecoration extends RecyclerView.ItemDecoration{

 //onDraw在每次重繪時(shí)都會(huì)調(diào)用,比如滑動(dòng)RecyclerView
 //gap線(xiàn)為從左到右的完整線(xiàn)條,在最開(kāi)始的item上,最后的item下,或者空白區(qū)域的上下
 //cut線(xiàn)為兩個(gè)緊密挨著的兩個(gè)item之間的線(xiàn)條
 @Override
 public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
  super.onDraw(c, parent, state);
  //當(dāng)?shù)谝粋€(gè)Item可見(jiàn)的時(shí)候,給第一個(gè)Item頂上繪一條Gap線(xiàn)
  //不用完整可見(jiàn)才繪制,考慮設(shè)置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;
  //所有可見(jiàn)的Item下面畫(huà)線(xiàn)
  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且不是最好一個(gè)Item的時(shí)候,繪制Cut線(xiàn),否則繪制gap線(xiàn)
   if(gap==0&&position!=end){ 
    //繪制cut線(xiàn)的左邊線(xiàn)條
    if(leftPaddingLine!=0){
     paint.setColor(foreLineColor);
     c.drawLine(parent.getLeft(),startY,parent.getLeft()+leftPaddingLine,startY,paint);
    }
    //繪制cut線(xiàn)的右邊線(xiàn)條
    if(rightPaddingLine!=0){
     paint.setColor(foreLineColor);
     c.drawLine(parent.getRight()-rightPaddingLine,startY,parent.getRight(),startY,paint);
    }
    //繪制cut線(xiàn)的中間線(xiàn)條
    paint.setColor(cutLineColor);
    c.drawLine(parent.getLeft()+leftPaddingLine,startY,parent.getRight()-rightPaddingLine,startY,paint);
   }else{
    paint.setColor(gapLineColor);
    //繪制gap上面的一條線(xiàn)
    c.drawLine(parent.getLeft(),child.getBottom()+halfLineHeight,parent.getRight(),child.getBottom()+halfLineHeight,paint);
    //如果不是最后一個(gè)item,繪制gap下面的一條線(xiàn)
    if(position<end){
     c.drawLine(parent.getLeft(),child.getBottom()+gap+halfLineHeight,parent.getRight(),child.getBottom()+gap+halfLineHeight,paint);
    }
   }
  }
 }

 //在每個(gè)item加載時(shí)調(diào)用,用來(lái)判斷設(shè)置每個(gè)item上下左邊的空白區(qū)域,設(shè)置內(nèi)容分別設(shè)置到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);
  //如果是第一個(gè)Item,則設(shè)置上線(xiàn)條高度,否則不設(shè)置上線(xiàn)條高度
  //為每個(gè)item設(shè)置下邊線(xiàn)條+gap(如果有的話(huà),沒(méi)有就為0)的高度
  //四個(gè)參數(shù)分別為左邊空白區(qū)域,上方空白區(qū)域,右邊空白區(qū)域,下方空白區(qū)域
  outRect.set(0, position != 0 ? 0 : (int)(halfLineHeight * 2+0.5f),0,(int)(halfLineHeight*2+0.5f)+mGap.get(position));
 }
}

這樣我們就得到了一個(gè)用來(lái)繪制分割線(xiàn)的類(lèi)了。在需要插入空白的地方addGap,并傳入gap的高度:

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

這樣分割線(xiàn)和空白的問(wèn)題就解決了。其他的就是RecyclerView的簡(jiǎn)單使用了,為了使用方便,我們對(duì)RecyclerView和其Adapter簡(jiǎn)單封裝一下,就能實(shí)現(xiàn)用addMenu的方式增加菜單項(xiàng)了。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

云梦县| 宝兴县| 大宁县| 祁连县| 常山县| 新密市| 隆昌县| 镇康县| 永川市| 辉南县| 大厂| 尼玛县| 道真| 道孚县| 清远市| 宁南县| 耿马| 天峻县| 封丘县| 亚东县| 静海县| 襄城县| 安庆市| 舟山市| 龙里县| 瑞昌市| 乌拉特后旗| 陆良县| 安吉县| 南宫市| 郸城县| 手机| 江永县| 彝良县| 贵定县| 阿克陶县| 宁国市| 鹤壁市| 隆子县| 蕉岭县| 新田县|