Android 瀑布流简单实现

瀑布流布局在图像、新闻等应用中广泛使用,它可以让多个不同高度的元素以流式布局展示出来,能够更好地利用空间,提高了用户体验。本文将介绍一种简单实现瀑布流布局的方式。
实现思路:
1. 创建一个 RecyclerView 控件,设置为纵向布局;
2. 自定义一个 RecyclerView.ItemDecoration,重写 getItemOffsets() 方法,来设置各个 item 之间的间距;
3. 编写 Adapter,在 onBindViewHolder() 方法中动态设置每个 item 的高度,以实现瀑布流布局效果。
具体步骤:
1. 在 build.gradle 中添加依赖
```java
implementation 'com.android.support:recyclerview-v7:28.0.0'
```
2. 在布局文件中添加 RecyclerView
```java
android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/colorPrimary" android:padding="10dp" android:clipToPadding="false" android:scrollbars="none" /> ``` 3. 自定义 RecyclerView.ItemDecoration ```java public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration { private int spanCount; private int spacing; private boolean includeEdge; public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) { this.spanCount = spanCount; this.spacing = spacing; this.includeEdge = includeEdge; } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int position = parent.getChildAdapterPosition(view); int column = position % spanCount; if (includeEdge) { outRect.left = spacing - column * spacing / spanCount; outRect.right = (column + 1) * spacing / spanCount; if (position < spanCount) { outRect.top = spacing; } outRect.bottom = spacing; } else { outRect.left = column * spacing / spanCount; outRect.right = spacing - (column + 1) * spacing / spanCount; if (position >= spanCount) { outRect.top = spacing; } } } } ``` 4. 编写 Adapter,并在 onBindViewHolder() 方法中设置每个 item 的高度 ```java public class ItemAdapter extends RecyclerView.Adapter private List private List public ItemAdapter(List mData = data; mHeights = new ArrayList<>(); for (int i = 0; i < mData.size(); i++) { mHeights.add((int) (200 + Math.random() * 400)); } } @NonNull @Override public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false); return new ItemViewHolder(view); } @Override public void onBindViewHolder(@NonNull ItemViewHolder holder, int position) { ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams(); layoutParams.height = mHeights.get(position); holder.itemView.setLayoutParams(layoutParams); holder.mTextView.setText(mData.get(position)); } @Override public int getItemCount() { return mData.size(); } static class ItemViewHolder extends RecyclerView.ViewHolder { TextView mTextView; ItemViewHolder(View itemView) { super(itemView); mTextView = itemView.findViewById(R.id.tv_item); } } } ``` 5. 在 Activity 中设置 RecyclerView 的 LayoutManager、ItemDecoration 和 Adapter ```java public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private List private ItemAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initData(); initView(); } private void initData() { mData = new ArrayList<>(); for (int i = 0; i < 100; i++) { mData.add("item " + i); } } private void initView() { mRecyclerView = findViewById(R.id.recyclerView); mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL)); mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(3, 10, true)); mAdapter = new ItemAdapter(mData); mRecyclerView.setAdapter(mAdapter); } } ``` 总结: 通过自定义 ItemDecoration 和 Adapter,能够快速实现瀑布流布局效果。实现过程中,需要注意每个 item 的高度是动态设置的,需要在 onBindViewHolder() 方法中进行设置。