美文网首页
Recyclerview中Item自动换行及滑动等

Recyclerview中Item自动换行及滑动等

作者: 雄赳赳 | 来源:发表于2017-08-24 14:01 被阅读0次

    publicclassFlowLayoutManagerextendsRecyclerView.LayoutManager{

    privatestaticfinalStringTAG=FlowLayoutManager.class.getSimpleName();

    privateintwidth, height;

    privateintleft, top, right;

    //最大容器的宽度

    privateintusedMaxWidth;

    //竖直方向上的偏移量

    privateintverticalScrollOffset=0;

    //计算显示的内容的高度

    privateinttotalHeight=0;

    privateRowrow=newRow();

    publicFlowLayoutManager() {

    setAutoMeasureEnabled(true);//此处重点注意,,无需自己去测量

    }

    publicclassItem{

    intuseHeight;

    Viewview;

    publicItem(intuseHeight,Viewview) {

    this.useHeight=useHeight;

    this.view=view;

    }

    }

    publicclassRow{

    publicvoidsetCuTop(floatcuTop) {

    this.cuTop=cuTop;

    }

    publicvoidsetMaxHeight(floatmaxHeight) {

    this.maxHeight=maxHeight;

    }

    floatcuTop;

    floatmaxHeight;

    Listviews=newArrayList<>();

    publicvoidaddViews(Itemview) {

    views.add(view);

    }

    publicvoidclear() {

    cuTop=0;

    maxHeight=0;

    views.clear();

    }

    }

    @Override

    publicRecyclerView.LayoutParamsgenerateDefaultLayoutParams() {

    returnnewRecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);

    }

    @Override

    publicvoidonLayoutChildren(RecyclerView.Recyclerrecycler,RecyclerView.Statestate) {

    if(state.isPreLayout()) {

    return;

    }

    detachAndScrapAttachedViews(recycler);

    width=getWidth();

    height=getHeight();

    totalHeight=0;

    left=getPaddingLeft();

    right=getPaddingRight();

    top=getPaddingTop();

    usedMaxWidth=width-left-right;

    intcuLineTop=top;

    //当前行使用的宽度

    intcuLineWidth=0;

    intitemLeft;

    intitemTop;

    intmaxHeightItem=0;

    row.clear();

    for(inti=0; i

    ViewchildAt=recycler.getViewForPosition(i);

    addView(childAt);

    if(View.GONE==childAt.getVisibility()) {

    continue;

    }

    measureChildWithMargins(childAt,0,0);

    intchildWidth=getDecoratedMeasuredWidth(childAt);

    intchildHeight=getDecoratedMeasuredHeight(childAt);

    Log.d(TAG,"childHeight:"+childHeight);

    intchildUseWidth=childWidth;

    intchildUseHeight=childHeight;

    //如果加上当前的item还小于最大的宽度的话

    if(cuLineWidth+childUseWidth<=usedMaxWidth) {

    itemLeft=left+cuLineWidth;

    itemTop=cuLineTop;

    layoutDecoratedWithMargins(childAt, itemLeft, itemTop, itemLeft+childWidth, itemTop+childHeight);

    cuLineWidth+=childUseWidth;

    maxHeightItem=Math.max(maxHeightItem, childUseHeight);

    row.addViews(newItem(childUseHeight, childAt));

    row.setCuTop(cuLineTop);

    row.setMaxHeight(maxHeightItem);

    }else{

    //换行

    formatAboveRow();

    cuLineTop+=maxHeightItem;

    totalHeight+=maxHeightItem;

    itemTop=cuLineTop;

    itemLeft=left;

    layoutDecoratedWithMargins(childAt, itemLeft, itemTop, itemLeft+childWidth, itemTop+childHeight);

    cuLineWidth=childUseWidth;

    maxHeightItem=childUseHeight;

    row.addViews(newItem(childUseHeight, childAt));

    row.setCuTop(cuLineTop);

    row.setMaxHeight(maxHeightItem);

    }

    //不要忘了最后一行进行刷新下布局

    if(i==getItemCount()-1) {

    formatAboveRow();

    totalHeight+=maxHeightItem;

    }

    }

    totalHeight=Math.max(totalHeight, getVerticalSpace());

    }

    /**

    * 计算每一行没有居中的viewgroup,让居中显示

    */

    privatevoidformatAboveRow() {

    Listviews=row.views;

    for(inti=0; i

    Viewview=views.get(i).view;

    if(views.get(i).useHeight

    layoutDecoratedWithMargins(view, getDecoratedLeft(view),

    (int) (row.cuTop+(row.maxHeight-getDecoratedMeasuredHeight(view))/2), getDecoratedRight(view),

    (int) (row.cuTop+(row.maxHeight-getDecoratedMeasuredHeight(view))/2+getDecoratedMeasuredHeight(view)));

    }

    }

    row.clear();

    }

    /**

    * 竖直方向需要滑动的条件

    *

    * @return

    */

    @Override

    publicbooleancanScrollVertically() {

    returntrue;

    }

    //监听竖直方向滑动的偏移量

    @Override

    publicintscrollVerticallyBy(intdy,RecyclerView.Recyclerrecycler,

    RecyclerView.Statestate) {

    //实际要滑动的距离

    inttravel=dy;

    //如果滑动到最顶部

    if(verticalScrollOffset+dy<0) {//限制滑动到顶部之后,不让继续向上滑动了

    travel=-verticalScrollOffset;//verticalScrollOffset=0

    }elseif(verticalScrollOffset+dy>totalHeight-getVerticalSpace()) {//如果滑动到最底部

    travel=totalHeight-getVerticalSpace()-verticalScrollOffset;//verticalScrollOffset=totalHeight - getVerticalSpace()

    }

    //将竖直方向的偏移量+travel

    verticalScrollOffset+=travel;

    //平移容器内的item

    offsetChildrenVertical(-travel);

    returntravel;

    }

    privateintgetVerticalSpace() {

    returnheight-getPaddingBottom()-getPaddingTop();

    }

    }

    相关文章

      网友评论

          本文标题:Recyclerview中Item自动换行及滑动等

          本文链接:https://www.haomeiwen.com/subject/qdkjdxtx.html