android纵向列表菜单栏实现,RecyclerView实现常见的列表菜单

在很多地方我们都会用到纵向列表样式的菜单,比如微信首页的我、发现页面,微博的首页的我页面,QQ的动态页面等等等等,大多数的应用中都会存在这样的页面。我们怎样实现这种页面比较好呢?

布局方案

完成这样的页面,常见的布局方案有:

1. 用ScrollView+LinearLayout很容易的暴力布局出来,但是这样得到的布局太固定了,如果条目多一点,加载起来很耗时。

2. 用ListView来实现,这种方案比方案一要好上不少,起码数据多点的时候,加载时不会太耗时。但是分割线和中间空白在要求差异化的时候,不太好绘制,用View的话又觉得大材小用。

3. 用RecyclerView来实现。RecyclerView做纵向布局相比ListView在很多方面也更灵活,无论是动画还是分割线上。

实现效果

7fa6d245a68c16304dbad2182b63a563.png

cc6fdca2bedf6c58d004c6d7d2948206.png

7a84efec2ccd4408543063335244140c.png

三个图片中分割线样式都是比较常见的。

使用起来当然是希望以最简单粗暴的方式去使用,比如:

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

具体实现

实现这样的效果,如果不考虑分割线的话,那么稍微用过RecyclerView的应该都能显示这样的功能,所以重点还是在分割线上了。

RecyclerView有一个增加分割线的方法addItemDecoration,当然,这个方法并不是只能用来增加分割线。类似微信中通讯录按照ABCD顺序排列,并分组同样可以用这个方法来实现。

直接贴上自定义的分割线的代码,在代码中解释:

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

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

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的高度:

public void addGap(int height){

mGap.put(mData.size()-1,height);

}

这样分割线和空白的问题就解决了。其他的就是RecyclerView的简单使用了,为了使用方便,我们对RecyclerView和其Adapter简单封装一下,就能实现用addMenu的方式增加菜单项了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值