欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Fragment + RecyclerView瀑布流布局

程序员文章站 2022-06-08 16:30:36
...

1、瀑布流效果图

2、使用RecyclerView实现瀑布流布局

Android Fragment + RecyclerView瀑布流布局

2.1 RecyclerView的用法

RecyclerView与ListView 类似,都使用Adapter(适配器)来生成列表项,不同的是RecyclerView 使用的是改进的RecyclerView.Adapter,RecyclerView.Adapter需要实现三种方法。

2.1.1 onCreteViewHolder(ViewGroup viewGroup,int i);

此方法用于创建列表项组件。

2.1.2 onBindViewHolder(ViewHolder viewHolder,int i);

此方法用于负责为列表项组件绑定数据,每次组件重新显示出来都会重新执行该方法。

2.1.3 getItemCount();

该方法的返回值决定包含多少个列表项。

2.2 Adapter代码示例

public class StaggeredGridAdater extends RecyclerView.Adapter<StaggeredGridAdater.HomeViewHolder> {

    private Context mContext;
    private List<Home> homeList = new ArrayList<>();

    public StaggeredGridAdater(Context context,List<Home> homeList){
        this.mContext = context;
        this.homeList = homeList;
    }

    //创建列表组件
    @NonNull
    @Override
    public StaggeredGridAdater.HomeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_item,null);
        return new StaggeredGridAdater.HomeViewHolder(view,this);
    }

    //绑定数据
    @Override
    public void onBindViewHolder(@NonNull HomeViewHolder holder, int position) {
        holder.imageIdIv.setImageResource(homeList.get(position).getImageId());
        holder.nameTv.setText(homeList.get(position).getName());
    }

    //返回列表数据总数
    @Override
    public int getItemCount() {
        return homeList.size();
    }


    public class HomeViewHolder extends RecyclerView.ViewHolder{
        TextView nameTv;
        ImageView imageIdIv;
        private RecyclerView.Adapter adapter;
        public HomeViewHolder(@NonNull View itemView,RecyclerView.Adapter adapter) {
            super(itemView);
            this.nameTv = itemView.findViewById(R.id.home_item_text);
            this.imageIdIv = itemView.findViewById(R.id.home_item_mage);
            this.adapter = adapter;
        }
    }
}

为了有效管理列表项所包含的子组件,额外定义了一个HomeViewHolder类。通过onCreateViewHolder()创建列表项
传入。

2.3 Fragment(或Activity)代码

public class HomeFragment extends Fragment {

    private RecyclerView recyclerView;
    private List<Home> homeList = new ArrayList<>();

    public View onCreateView(@NonNull LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {
        View root = inflater.inflate(R.layout.fragment_home, container, false);

        recyclerView = root.findViewById(R.id.home_recycler);
        //设置RecyclerView保持固定大小,这样可以优化RecyclerView的性能
        recyclerView.setHasFixedSize(true);

        initData();

        //设置瀑布流布局为2列,垂直方向滑动
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));

        StaggeredGridAdater staggeredGridAdater = new StaggeredGridAdater(this.getActivity(),homeList);

        //创建分割线对象
        recyclerView.addItemDecoration(new MyDecoration());

        recyclerView.setAdapter(staggeredGridAdater);

        return root;
    }

    //数据源
    private void initData() {
        String[] names = new String[]{"车位查询","车位预定","与车间距","防盗警报","停车时长","车位查询","车位预定","与车间距","防盗警报","停车时长"};
        int[] ImageId = new int[]{R.drawable.car1,R.drawable.car2,R.drawable.car3,R.drawable.car4,R.drawable.car5,R.drawable.car1,R.drawable.car2,R.drawable.car3,R.drawable.car4,R.drawable.car5};
        for(int i = 0 ;i < names.length ; i++){
            this.homeList.add(new Home(names[i],ImageId[i]));
        }
    }

    //分割线的类
    class MyDecoration extends RecyclerView.ItemDecoration{
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state){
            super.getItemOffsets(outRect,view ,parent,state);
            int gap = getResources().getDimensionPixelSize(R.dimen.dividerHeight);//5dp
            outRect.set(gap,gap,gap,gap);
        }
    }

}

2.4 Home类

public class Home {
    private String name;
    private int ImageId;

    public Home(String name,int ImageId){
        this.name = name;
        this.ImageId = ImageId;
    }

    public int getImageId() {
        return ImageId;
    }

    public void setImageId(int imageId) {
        ImageId = imageId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.5 主布局xml代码

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

    <!--android:divider 分割线-->
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/home_recycler"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="56dp"
        android:background="@color/colorWhite">
    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>

2.6 item子布局

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

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/home_item_mage"
        android:scaleType="centerCrop"/>

    <TextView
        android:id="@+id/home_item_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="2dp"
        android:layout_gravity="left|bottom"
        android:padding="12dip"
        android:background="#85000000"
        android:textColor="#ffffffff"
        android:text="Golden Gate"
        android:textStyle="bold"/>
</FrameLayout>