流式布局+recyclerview的简单使用

如果可以帮助到你,可以给我点个赞吗?

接口

 String BASE_URL = "https://www.wanandroid.com/";
/**
     * 获取体系数据
     *
     * @return
     */
    @GET("tree/json")
    Observable<TreeBean> getTree();

1.fragment (根据自己需求修改成activity)

package wanandroid.two.com.wanandroid.ui.fragment;


import android.content.Intent;
import android.os.Bundle;
import android.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import wanandroid.two.com.wanandroid.R;
import wanandroid.two.com.wanandroid.base.BaseFragment;
import wanandroid.two.com.wanandroid.bean.TreeBean;
import wanandroid.two.com.wanandroid.bean.TreeListBean;
import wanandroid.two.com.wanandroid.mvp.p.TreePre;
import wanandroid.two.com.wanandroid.mvp.v.TreeView;
import wanandroid.two.com.wanandroid.ui.activity.MainActivity;
import wanandroid.two.com.wanandroid.ui.activity.TreeEssayActivity;
import wanandroid.two.com.wanandroid.ui.adapter.MyTreeAdapter;

/**
 * A simple {@link Fragment} subclass.
 */
public class MyTreeFragment extends BaseFragment<TreeView,TreePre> implements TreeView{


    @BindView(R.id.Mrv)
    RecyclerView Mrv;
    private MyTreeAdapter mTreeAdapter;
    private ArrayList<TreeBean.DataBean> mList;



    public MyTreeFragment() {
        // Required empty public constructor
    }

    @Override
    protected TreePre Getpreseter() {
        return new TreePre();
    }

    @Override
    protected int GetId() {
        return R.layout.fragment_my_tree;
    }

    @Override
    protected void initView(View inflate) {
        Mrv.setLayoutManager(new LinearLayoutManager(getActivity()));
        mList = new ArrayList<>();
        mTreeAdapter = new MyTreeAdapter(mList, getActivity());
        Mrv.setAdapter(mTreeAdapter);
        presenter.setTree();

        mTreeAdapter.setOnItemCLick(new MyTreeAdapter.OnItemCLick() {
            @Override
            public void onItemClick(TreeBean.DataBean bean) {
                Intent intent = new Intent(getActivity(), TreeEssayActivity.class);
                intent.putExtra("bean",bean);
                startActivity(intent);
            }
        });
    }

    @Override
    public void getTree(TreeBean treeBean) {
        List<TreeBean.DataBean> data = treeBean.getData();
        mList.clear();
        mList.addAll(data);
        mTreeAdapter.notifyDataSetChanged();
    }

    @Override
    public void getTreeList(TreeListBean tree) {

    }

    @Override
    public void setError(String error) {

    }
}

2.主页面布局只需一个recyclerview就行

3.自定义view

package com.example.tolovepy.everywheretrip.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import java.util.ArrayList;
import java.util.List;

public class FlowLayout extends ViewGroup {

   private List<Line> mLines   = new ArrayList<Line>(); // 用来记录描述有多少行View
   private Line        mCurrrenLine;   // 用来记录当前已经添加到了哪一行
   private int         mHorizontalSpace    = 40;
   private int         mVerticalSpace      = mHorizontalSpace;
   private int mMaxLines = -1;

   public int getMaxLines() {
       return mMaxLines;
   }

   public void setMaxLines(int maxLines) {
       mMaxLines = maxLines;
   }

   public FlowLayout(Context context, AttributeSet attrs) {
       super(context, attrs);
   }

   public FlowLayout(Context context) {
       super(context);
   }

   public void setSpace(int horizontalSpace, int verticalSpace) {
       this.mHorizontalSpace = horizontalSpace;
       this.mVerticalSpace = verticalSpace;
   }

   public void clearAll(){
       mLines.clear();
   }

   @Override
   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
       // 清空
       mLines.clear();
       mCurrrenLine = null;

       int layoutWidth = MeasureSpec.getSize(widthMeasureSpec);

       // 获取行最大的宽度
       int maxLineWidth = layoutWidth - getPaddingLeft() - getPaddingRight();

       // 测量孩子
       int count = getChildCount();
       for (int i = 0; i < count; i++)
       {
           View view = getChildAt(i);

           // 如果孩子不可见
           if (view.getVisibility() == View.GONE)
           {
               continue;
           }

           // 测量孩子
           measureChild(view, widthMeasureSpec, heightMeasureSpec);

           // 往lines添加孩子
           if (mCurrrenLine == null)
           {
               // 说明还没有开始添加孩子
               mCurrrenLine = new Line(maxLineWidth, mHorizontalSpace);

               // 添加到 Lines中
               mLines.add(mCurrrenLine);

               // 行中一个孩子都没有
               mCurrrenLine.addView(view);
           }
           else
           {
               // 行不为空,行中有孩子了
               boolean canAdd = mCurrrenLine.canAdd(view);
               if (canAdd) {
                   // 可以添加
                   mCurrrenLine.addView(view);
               }
               else {
                   // 不可以添加,装不下去
                   // 换行
                   if (mMaxLines >0){
                       if (mLines.size()<mMaxLines){
                           // 新建行
                           mCurrrenLine = new Line(maxLineWidth, mHorizontalSpace);
                           // 添加到lines中
                           mLines.add(mCurrrenLine);
                           // 将view添加到line
                           mCurrrenLine.addView(view);
                       }
                   }else {
                       // 新建行
                       mCurrrenLine = new Line(maxLineWidth, mHorizontalSpace);
                       // 添加到lines中
                       mLines.add(mCurrrenLine);
                       // 将view添加到line
                       mCurrrenLine.addView(view);
                   }
               }
           }
       }

       // 设置自己的宽度和高度
       int measuredWidth = layoutWidth;
       // paddingTop + paddingBottom + 所有的行间距 + 所有的行的高度

       float allHeight = 0;
       for (int i = 0; i < mLines.size(); i++)
       {
           float mHeigth = mLines.get(i).mHeigth;

           // 加行高
           allHeight += mHeigth;
           // 加间距
           if (i != 0)
           {
               allHeight += mVerticalSpace;
           }
       }

       int measuredHeight = (int) (allHeight + getPaddingTop() + getPaddingBottom() + 0.5f);
       setMeasuredDimension(measuredWidth, measuredHeight);
   }

   @Override
   protected void onLayout(boolean changed, int l, int t, int r, int b)
   {
       // 给Child 布局---> 给Line布局

       int paddingLeft = getPaddingLeft();
       int offsetTop = getPaddingTop();
       for (int i = 0; i < mLines.size(); i++)
       {
           Line line = mLines.get(i);

           // 给行布局
           line.layout(paddingLeft, offsetTop);

           offsetTop += line.mHeigth + mVerticalSpace;
       }
   }

   class Line
   {
       // 属性
       private List<View>  mViews  = new ArrayList<View>();    // 用来记录每一行有几个View
       private float       mMaxWidth;                          // 行最大的宽度
       private float       mUsedWidth;                     // 已经使用了多少宽度
       private float       mHeigth;                            // 行的高度
       private float       mMarginLeft;
       private float       mMarginRight;
       private float       mMarginTop;
       private float       mMarginBottom;
       private float       mHorizontalSpace;                   // View和view之间的水平间距

       // 构造
       public Line(int maxWidth, int horizontalSpace) {
           this.mMaxWidth = maxWidth;
           this.mHorizontalSpace = horizontalSpace;
       }

       // 方法
       /**
        * 添加view,记录属性的变化
        * 
        * @param view
        */
       public void addView(View view)
       {
           // 加载View的方法

           int size = mViews.size();
           int viewWidth = view.getMeasuredWidth();
           int viewHeight = view.getMeasuredHeight();
           // 计算宽和高
           if (size == 0)
           {
               // 说还没有添加View
               if (viewWidth > mMaxWidth)
               {
                   mUsedWidth = mMaxWidth;
               }
               else
               {
                   mUsedWidth = viewWidth;
               }
               mHeigth = viewHeight;
           }
           else
           {
               // 多个view的情况
               mUsedWidth += viewWidth + mHorizontalSpace;
               mHeigth = mHeigth < viewHeight ? viewHeight : mHeigth;
           }

           // 将View记录到集合中
           mViews.add(view);
       }

       /**
        * 用来判断是否可以将View添加到line中
        * 
        * @param view
        * @return
        */
       public boolean canAdd(View view)
       {
           // 判断是否能添加View

           int size = mViews.size();

           if (size == 0) { return true; }

           int viewWidth = view.getMeasuredWidth();

           // 预计使用的宽度
           float planWidth = mUsedWidth + mHorizontalSpace + viewWidth;

           if (planWidth > mMaxWidth)
           {
               // 加不进去
               return false;
           }

           return true;
       }

       /**
        * 给孩子布局
        * 
        * @param offsetLeft
        * @param offsetTop
        */
       public void layout(int offsetLeft, int offsetTop)
       {
           // 给孩子布局

           int currentLeft = offsetLeft;

           int size = mViews.size();
           // 判断已经使用的宽度是否小于最大的宽度
           float extra = 0;
           float widthAvg = 0;
           if (mMaxWidth > mUsedWidth)
           {
               extra = mMaxWidth - mUsedWidth;
               widthAvg = extra / size;
           }

           for (int i = 0; i < size; i++)
           {
               View view = mViews.get(i);
               int viewWidth = view.getMeasuredWidth();
               int viewHeight = view.getMeasuredHeight();

               // 判断是否有富余
               if (widthAvg != 0)
               {
                   // 改变宽度,变为不改变,避免最后一行因label不足,单个label变宽
                   //int newWidth = (int) (viewWidth + widthAvg + 0.5f);
                   int newWidth = viewWidth;
                   int widthMeasureSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
                   int heightMeasureSpec = MeasureSpec.makeMeasureSpec(viewHeight, MeasureSpec.EXACTLY);
                   view.measure(widthMeasureSpec, heightMeasureSpec);

                   viewWidth = view.getMeasuredWidth();
                   viewHeight = view.getMeasuredHeight();
               }

               // 布局
               int left = currentLeft;
               int top = (int) (offsetTop + (mHeigth - viewHeight) / 2 +
                           0.5f);
               // int top = offsetTop;
               int right = left + viewWidth;
               int bottom = top + viewHeight;
               view.layout(left, top, right, bottom);

               currentLeft += viewWidth + mHorizontalSpace;
           }
       }
   }

}

4.使用recyclerview适配器

package wanandroid.two.com.wanandroid.ui.adapter;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import wanandroid.two.com.wanandroid.R;
import wanandroid.two.com.wanandroid.bean.TreeBean;
import wanandroid.two.com.wanandroid.widget.FlowLayout;

public class MyTreeAdapter extends RecyclerView.Adapter<MyTreeAdapter.ViewHolder> {

    private List<TreeBean.DataBean> mList;
    private Context context;

    public MyTreeAdapter(List<TreeBean.DataBean> list, Context context) {
        mList = list;
        this.context = context;
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View inflate = LayoutInflater.from(context).inflate(R.layout.item_tree, null);
        ViewHolder viewHolder = new ViewHolder(inflate);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        viewHolder.mFl.removeAllViews();
        final TreeBean.DataBean bean = mList.get(i);
        //获取标题
        String name = bean.getName();
        //获取相关信息标题
        List<TreeBean.DataBean.ChildrenBean> list = bean.getChildren();
        //添加
        viewHolder.mTvTitle.setText(name);
        for (int j = 0; j < list.size(); j++) {
            TextView inflate = (TextView) LayoutInflater.from(context).inflate(R.layout.item_label, null);
            String s = list.get(j).getName();
            inflate.setText(s);
            viewHolder.mFl.addView(inflate);
        }

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mOnItemCLick!=null){
                    mOnItemCLick.onItemClick(bean);
                }
            }
        });

    }

    @Override
    public int getItemCount() {
        return mList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.mTv_Title)
        TextView mTvTitle;
        @BindView(R.id.mFl)
        FlowLayout mFl;
        @BindView(R.id.mIv_jump)
        ImageView mIvJump;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    private OnItemCLick mOnItemCLick;

    public void setOnItemCLick(OnItemCLick onItemCLick) {
        mOnItemCLick = onItemCLick;
    }

    public interface OnItemCLick{
        void onItemClick(TreeBean.DataBean bean);
    }

}

5.item布局

<--item_tree-->

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/mTv_Title"
            android:layout_marginTop="@dimen/dp_10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/c_636363"
            android:layout_marginLeft="@dimen/dp_10"
            android:textSize="@dimen/sp_20" />

        <wanandroid.two.com.wanandroid.widget.FlowLayout
            android:id="@+id/mFl"
            android:layout_marginLeft="@dimen/dp_10"
            android:layout_marginTop="@dimen/dp_10"
            android:layout_marginBottom="@dimen/dp_10"
            android:layout_marginRight="@dimen/dp_60"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

        </wanandroid.two.com.wanandroid.widget.FlowLayout>

        <View
            android:background="@color/c_666"
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_1"/>

    </LinearLayout>

    <ImageView
        android:id="@+id/mIv_jump"
        android:src="@drawable/u"
        android:layout_alignParentRight="true"
        android:layout_marginRight="@dimen/dp_20"
        android:layout_centerInParent="true"
        android:layout_width="@dimen/dp_20"
        android:layout_height="@dimen/dp_20" />


</RelativeLayout>
<--item_label-->

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:maxLines="1"
    android:ellipsize="end"
    android:gravity="center"
    android:text="@string/app_name"
    android:textColor="@color/c_B6B2B2"
    android:textSize="@dimen/sp_14"/>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。