StaggeredGridLayoutManager
似乎不允许自定义 单元格宽度 或跨越多个列(全跨度除外)以实现垂直方向。
如上所示用于组织单元格的首选 LayoutManager
是什么?
P.S. 我只想知道如何使用 StaggeredGridLayoutManager
自定义 单元格宽度 而不是高度。我知道高度可以按照 sample 中的实现进行自定义.
public class VerticalStaggeredGridFragment extends RecyclerFragment {
public static VerticalStaggeredGridFragment newInstance() {
VerticalStaggeredGridFragment fragment = new VerticalStaggeredGridFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
protected RecyclerView.LayoutManager getLayoutManager() {
return new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
}
@Override
protected RecyclerView.ItemDecoration getItemDecoration() {
return new InsetDecoration(getActivity());
}
@Override
protected int getDefaultItemCount() {
return 100;
}
@Override
protected SimpleAdapter getAdapter() {
return new SimpleStaggeredAdapter();
}
}
适配器
public class SimpleStaggeredAdapter extends SimpleAdapter {
@Override
public void onBindViewHolder(VerticalItemHolder itemHolder, int position) {
super.onBindViewHolder(itemHolder, position);
final View itemView = itemHolder.itemView;
if (position % 4 == 0) {
int height = itemView.getContext().getResources()
.getDimensionPixelSize(R.dimen.card_staggered_height);
itemView.setMinimumHeight(height);
} else {
itemView.setMinimumHeight(0);
}
}
}
itemView.setMinimumWidth(customWidth)
不影响单元格宽度。
为了简化,我将网格布局更新为
与 StaggeredGridLayoutManager
或任何其他布局管理器中的单元格 1 相比,如何增加单元格 0 的宽度?
最佳答案
您可以使用 StaggeredGridLayoutManager.LayoutParams
来更改单元格的宽度和高度,您期望的设计遵循一个简单的模式,如果您为每个单元格分配一个索引(按照 StaggeredGridLayoutManager
默认排列它们)你会得到这个:
index % 4 == 3 ---> full span cell
index % 8 == 0, 5 ---> half span cell
index % 8 == 1, 2, 4, 6 ---> quarter span cell
首先在adapter中声明一些常量来定义span类型:
private static final int TYPE_FULL = 0;
private static final int TYPE_HALF = 1;
private static final int TYPE_QUARTER = 2;
然后像这样覆盖适配器中的 getItemViewType
方法:
@Override
public int getItemViewType(int position) {
final int modeEight = position % 8;
switch (modeEight) {
case 0:
case 5:
return TYPE_HALF;
case 1:
case 2:
case 4:
case 6:
return TYPE_QUARTER;
}
return TYPE_FULL;
}
您需要做的就是考虑 holder
的 viewType
更改布局参数:
@Override
public MyHolder onCreateViewHolder(final ViewGroup parent, final int viewType) {
final View itemView =
LayoutInflater.from(mContext).inflate(R.layout.items, parent, false);
itemView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
final int type = viewType;
final ViewGroup.LayoutParams lp = itemView.getLayoutParams();
if (lp instanceof StaggeredGridLayoutManager.LayoutParams) {
StaggeredGridLayoutManager.LayoutParams sglp =
(StaggeredGridLayoutManager.LayoutParams) lp;
switch (type) {
case TYPE_FULL:
sglp.setFullSpan(true);
break;
case TYPE_HALF:
sglp.setFullSpan(false);
sglp.width = itemView.getWidth() / 2;
break;
case TYPE_QUARTER:
sglp.setFullSpan(false);
sglp.width = itemView.getWidth() / 2;
sglp.height = itemView.getHeight() / 2;
break;
}
itemView.setLayoutParams(sglp);
final StaggeredGridLayoutManager lm =
(StaggeredGridLayoutManager) ((RecyclerView) parent).getLayoutManager();
lm.invalidateSpanAssignments();
}
itemView.getViewTreeObserver().removeOnPreDrawListener(this);
return true;
}
});
MyHolder holder = new MyHolder(itemView);
return holder;
}
我的适配器总是返回 50 的项目计数(只是一个测试),我使用了一个简单的项目布局文件,它包含一个 LinearLayout
和一个 TextView
来显示持有人的位置,请记住,由于您的设计,您应该为 spanCount
(int the StaggeredGridLayoutManager
构造函数)传递 2。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView rv = (RecyclerView) findViewById(R.id.rv);
StaggeredGridLayoutManager lm =
new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
rv.setLayoutManager(lm);
rv.setAdapter(new MyAdapter(this));
}
附言:
对于像我这样的懒人来说,这可能是一种更简单的方法,而不是扩展我的自定义 LayoutManager
,但我确信有更好的方法来实现这一点。
更新:
您的问题的更新部分更简单,您可以使用 GridLayoutManager
:
GridLayoutManager glm = new GridLayoutManager(this, 3);
glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
if (position % 3 == 2) {
return 3;
}
switch (position % 4) {
case 1:
case 3:
return 1;
case 0:
case 2:
return 2;
default:
//never gonna happen
return -1 ;
}
}
});
rv.setLayoutManager(glm);
通过这种方式,您将默认跨度大小设置为 3,然后考虑跨度的位置,每个项目占用 1、2 或 3 个跨度,如下所示:
Item0.width == 2 X Item1.width
Item2.width == 3 X Item1.width
Item0.width == 2/3 X Item1.width
关于android - 具有不同单元格宽度的 RecyclerView Grid 的 LayoutManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36514887/