您的位置:首页 > 移动开发 > Android开发

使用StaggeredGridLayoutManager实现交错式网格布局

2017-08-03 16:43 2006 查看
一直在想着怎么描述这样的布局,毕竟用的是瀑布流的布局管理器,但是呢效果基本就是个网格布局,只是每列之间是上下错开的,还是觉得叫交错式网格布局吧。先看个效果。



效果看起来应该很好实现的。这里仅仅是记录下自己实现的思路,然后贴出一些重要的代码。

基本思路就是运用StaggeredGridLayoutManager管理器来实现这种布局,在Recyclerview适配器中的onBindViewHolder中设置,将第一行和第三行上的首张图片设置一个margin值,距离顶部一个距离,这样既可实现该种布局。

其实还有一种思路也是运用瀑布流管理器,在自定义分割线中,根据position不同设置不同间隔距离,应该是可以的。

这里就用第一个思路,首先是Recyclerview的用法,这个相信大家都很熟悉了,管理器官方的有三种,线性管理器LinearLayoutManager,网格管理器GridLayoutManager,瀑布流管理器StaggeredGridLayoutManager,这里用的是瀑布流管理器:

mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
final StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);//定义瀑布流管理器,第一个参数是列数,第二个是方向。
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);//不设置的话,图片闪烁错位,有可能有整列错位的情况。
mRecyclerView.setLayoutManager(layoutManager);//设置瀑布流管理器
mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(40));//边距和分割线,需要自己定义
mRecyclerView.setAdapter(new MyAdapter(this));//设置适配器
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
layoutManager.invalidateSpanAssignments();//这行主要解决了当加载更多数据时,底部需要重绘,否则布局可能衔接不上。
}
});


上面的代码就是Recyclerview的使用了。接下来看适配器中的代码。

class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private Context context;
private LayoutInflater inflater;
public MyAdapter(Context context){
this.context = context;
inflater = LayoutInflater.from(context);
}
public final String[] imageUrls = new String[] {。。。}//这里是从网上加载的图片的链接组成的字符串数组。我这里是从《第一行代码》作者郭霖大神的http://blog.csdn.net/guolin_blog/article/details/10470797讲述瀑布流的文章中偷过来的。哈哈。不过都是网上的图片地址。

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View inflate = inflater.inflate(R.layout.item_main, parent, false);//单个item的布局
return new MyViewHolder(inflate);
}

@Override
public int getItemCount() {
return imageUrls.length;
}

@Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
holder.textView.setText("风景" + position);
//用了Glide加载图片,这是一款不错的图片加载框架,毕竟属于Google亲儿子了吧,不会用的也可以用picasso,这个框架参考picasso的,基本跟picasso一模一样。
Glide.with(context)
.load(imageUrls[position])
.asBitmap()
.centerCrop()
.diskCacheStrategy(DiskCacheStrategy.NONE)//这里设置了不做任何缓存
.placeholder(R.drawable.kobe)//这是占位图。加载图片的一瞬间可以用来填充,万一网络不行还可以有个好的视觉效果。毕竟什么都不显示让人很绝望呀。。。
.into(new BitmapImageViewTarget(holder.imageView){
@Override
protected void setResource(Bitmap resource) {
super.setResource(resource);
//这里用来进行图片转换,转成圆形的图。
RoundedBitmapDrawable circleBitmap = RoundedBitmapDrawableFactory.create(context.getResources(),resource);
circleBitmap.setCircular(true);
holder.imageView.setImageDrawable(circleBitmap);
}
});
//这里就是让我们最终的效果跟Gridview不同的原因了,我们把第一列和第三列的首张图片设置距离顶部一个距离,这样布局错落有致,就是我们要的效果了
if (position == 0 || position ==2) {
Linea
4000
rLayout.LayoutParams lp = new LinearLayout.LayoutParams(holder.imageView.getLayoutParams());
lp.setMargins(0,100,0,0);
holder.imageView.setLayoutParams(lp);
} else {
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(holder.imageView.getLayoutParams());
lp.setMargins(0,0,0,0);
holder.imageView.setLayoutParams(lp);
}
}

class MyViewHolder extends RecyclerView.ViewHolder{
private ImageView imageView;
private TextView textView;
public MyViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.iv);
textView = (TextView) itemView.findViewById(R.id.tv);
}
}
}


以上就可以得到文章开始的效果了。。。

大家有什么疑问或者有什么建议,欢迎留言交流。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息