答案 0 :(得分:0)
我想我已经找到了可能适合您的解决方案。我在这里使用Kotlin,但是我敢肯定,在Java中也可以实现同样的目的。
GridLayoutManager
假设您有一个List<Thing>
作为数据源。
您有0..n个事物。
所述Thing
具有通过类型标识的手段。 aka:aThing.type
。
假设您有两种类型:
正常和AD。
enum Type { Normal, AD }
(例如)。
因此您可以这样做:
if (thing.type == Type.AD)
现在,我假设您从存储库中收到Thing
的列表。
您有不同的选择(我将只探讨一种,而其他的作为练习留给读者,主要是因为我没有那么多时间,而且还因为每种最佳解决方案确实取决于上下文。我在这里没有太多上下文)。我的要求很简单:让广告覆盖整个网格。
一个简单的解决方案涉及更改存储库提供给您的结果列表(请注意,我不会触摸存储库的数据,进行复制,将复制的副本用于您的适配器)。
因此,当您获取列表时,不要将其直接发送到适配器,而是对其进行修改:
(这是伪代码,假设listOfData
是您要显示的数据,当然已经填充了)
var newList = ArrayList<Thing>()
for ((index, thing) in listOfData.withIndex()) {
// if it's an Ad, insert one, and continue adding items
if (index % 4 == 0) {
newList.add(AdPlaceholder())
} else {
newList.add(thing)
}
}
return newList
因此,我们基于原始列表返回一个newList(这只是一种实现方式,不是唯一的方法,当然也不是所有情况下的最佳方法,它可能不仅仅令人眼花)乱。) / p>
什么是AdPlaceholder()
?
这只是专门的“事物”:)(见下文)。
现在在您的活动/片段中的某个位置,您可能会像这样设置recyclerview :(再次,伪代码,但有效的Kotlin)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
layoutManager = GridLayoutManager(this, 2)
mainRecyclerView.layoutManager = layoutManager
mainRecyclerView.adapter = YourAdapter()
// and somewhere you'll send data to this adapter...
adapter.submitList(repository.getMyListOfThings())
}
这看起来像您的初始网格。
现在,我首先想到的是,如果我们创建一个自定义LayoutManager,它“智能”地显示何时显示广告以及不显示什么。
但是后来我发现GridLayoutManager智能地公开了一个值(并且它可以工作):
spanSizeLookup
:设置源以获取适配器中每个项目占用的跨度数。
这正是我们需要告知网格的内容:嘿,此项目占用N个跨度,而另一个项目占用Y。
所以,我添加了这个:
layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return when (adapter.getItemViewType(position)) {
adapter.normalViewType -> 1
adapter.adViewType -> 2
else -> 1 //default
}
}
}
还有瞧!
由于要处理的工作量很大,因此我创建了a sample project来说明实际情况。它有一个错误,希望您可以发现它(并修复它!):)
请注意,我没有使用任何AD加载库,这取决于您。请注意,广告通常以WebView的形式实现,因此通常会变得缓慢,异步等。准备好在广告尚未加载时显示占位符,等等。 这实际上取决于您如何实现事物的这一方面,而天空是极限。这只是我用来检验理论的简单样本。
我个人认为这将变得更加困难;我证明自己错了。
祝你好运。
答案 1 :(得分:0)
活动中:
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(mAdapter);
在您的回收站 OnCreateViewHolder
中:
switch (viewType) {
...........
case TYPE_AD: {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.AD_ITEM_LAYOUT, parent, false);
final ViewGroup.LayoutParams lp = v.getLayoutParams();
if (lp instanceof StaggeredGridLayoutManager.LayoutParams){
StaggeredGridLayoutManager.LayoutParams sglp = (StaggeredGridLayoutManager.LayoutParams)lp;
sglp.setFullSpan(true);
}
return new AdViewHolder(v);
}
...........
}
并在 getItemViewType
方法中计算服务 TYPE_AD :
@Override
public int getItemViewType(int position) {
.........
if (position % 4 == 0){
return TYPE_AD;
}
.........
}