根据项目位置动态更改 StaggeredGridLayout 的列跨度计数
Change column span count of StaggeredGridLayout dynamically based on item position
我想为 (n) 个项目列表实现此布局:
到目前为止,我可以在两列中显示项目,但如何将两列合并为一个特定位置(即第 7 项)?
我已经尝试过 SO 提供的许多解决方案以及其他解决方案,但其中 none 对我有用。那里提供的解决方案要么使用 LinearLayout 膨胀静态布局,要么为列中的分区提供解决方案。
我也尝试过使用 setSpanLookup
方法,但没有成功..
正如你所说,setSpanLookup
是我认为最好的方法。
试试这个代码:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val layoutManager = GridLayoutManager(this, 2)
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
if (position == 6 || position == 13) return 2
else return 1
}
}
rv.layoutManager = layoutManager
val items = mutableListOf<String>()
for (i in 1..14) {
items.add("item$i")
}
rv.adapter = MyAdapter(items)
}
}
您需要知道返回的值getSpanSize
表示权重,而不是列数。
在项目布局方面,可以在特殊位置使用不同的ViewHolder。
例如:
companion object{
const val NORMAL = 0
const val WIDE = 1
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
...
if (viewType == WIDE) return WideViewHolder(wideView)
else return NormalViewHolder(normalView)
}
override fun getItemViewType(position: Int): Int {
if (position == 6 || position == 13) {
return WIDE
}
return NORMAL
}
只需创建一个 table :
在您的情况下是 8 行和 3 列,设置边界线和边界对齐方式,第 7 项和第 14 项将占用 3 个单元格。这里有一个例子:
private void insertCell(PdfPTable table, String text, int align, int colspan, Font font) {
//create a new cell with the specified Text and Font
PdfPCell cell = new PdfPCell(new Phrase(text.trim(), font));
//set the cell alignment
cell.setHorizontalAlignment(align);
//set the cell column span in case you want to merge two or more cells
cell.setColspan(colspan);
//in case there is no text and you wan to create an empty row
if (text.trim().equalsIgnoreCase("")) {
cell.setMinimumHeight(10f);
}
//add the call to the table
table.addCell(cell);
}
经过艰苦奋斗,终于找到了对我有用的解决方案:
@Override
public void onViewAttachedToWindow(MyViewHolder holder) {
super.onViewAttachedToWindow(holder);
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if(lp != null
&& lp instanceof StaggeredGridLayoutManager.LayoutParams
&& (holder.getLayoutPosition() == 6 || holder.getLayoutPosition() == 13)) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
p.setFullSpan(true);
}
holder.setIsRecyclable(false);
}
希望这对您也有帮助。
我想为 (n) 个项目列表实现此布局:
到目前为止,我可以在两列中显示项目,但如何将两列合并为一个特定位置(即第 7 项)?
我已经尝试过 SO 提供的许多解决方案以及其他解决方案,但其中 none 对我有用。那里提供的解决方案要么使用 LinearLayout 膨胀静态布局,要么为列中的分区提供解决方案。
我也尝试过使用 setSpanLookup
方法,但没有成功..
正如你所说,setSpanLookup
是我认为最好的方法。
试试这个代码:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val layoutManager = GridLayoutManager(this, 2)
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
if (position == 6 || position == 13) return 2
else return 1
}
}
rv.layoutManager = layoutManager
val items = mutableListOf<String>()
for (i in 1..14) {
items.add("item$i")
}
rv.adapter = MyAdapter(items)
}
}
您需要知道返回的值getSpanSize
表示权重,而不是列数。
在项目布局方面,可以在特殊位置使用不同的ViewHolder。
例如:
companion object{
const val NORMAL = 0
const val WIDE = 1
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
...
if (viewType == WIDE) return WideViewHolder(wideView)
else return NormalViewHolder(normalView)
}
override fun getItemViewType(position: Int): Int {
if (position == 6 || position == 13) {
return WIDE
}
return NORMAL
}
只需创建一个 table : 在您的情况下是 8 行和 3 列,设置边界线和边界对齐方式,第 7 项和第 14 项将占用 3 个单元格。这里有一个例子:
private void insertCell(PdfPTable table, String text, int align, int colspan, Font font) {
//create a new cell with the specified Text and Font
PdfPCell cell = new PdfPCell(new Phrase(text.trim(), font));
//set the cell alignment
cell.setHorizontalAlignment(align);
//set the cell column span in case you want to merge two or more cells
cell.setColspan(colspan);
//in case there is no text and you wan to create an empty row
if (text.trim().equalsIgnoreCase("")) {
cell.setMinimumHeight(10f);
}
//add the call to the table
table.addCell(cell);
}
经过艰苦奋斗,终于找到了对我有用的解决方案:
@Override
public void onViewAttachedToWindow(MyViewHolder holder) {
super.onViewAttachedToWindow(holder);
ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
if(lp != null
&& lp instanceof StaggeredGridLayoutManager.LayoutParams
&& (holder.getLayoutPosition() == 6 || holder.getLayoutPosition() == 13)) {
StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
p.setFullSpan(true);
}
holder.setIsRecyclable(false);
}
希望这对您也有帮助。