首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在RecyclerView中显示原生广告

在RecyclerView中显示原生广告
EN

Stack Overflow用户
提问于 2019-06-10 19:40:36
回答 2查看 4.1K关注 0票数 2

我正在和RecyclerView一起工作。其中我必须在GridLayout管理器中显示两个项目,跨度计数为2才能以全宽显示原生广告。有人能帮我吗。

EN

回答 2

Stack Overflow用户

发布于 2019-06-10 23:16:20

我想我已经找到了一个可能对你有效的解决方案。我在这里使用的是Kotlin,但我相信在Java中也可以做到这一点。

假设

GridLayoutManager

  • You您正在使用的
  • 要每隔N个项目插入一个"ad“。
  • 您已经实现或有办法确定要显示的数据类型(也称为:根据itemType膨胀不同的"ViewHolders”。
  • 在不可变数据列表中插入占位符没有问题,这样您的RecyclerView适配器就不会充满疯狂的逻辑,而且您的GridLayout也不必是自定义的。

多么?

  • 一个网格布局管理器,根据“跨度”的数量计算布局/度量(我在脑海中称之为列,即使这并不是真正的意思)。
  • 创建GridLayoutManager时,通过提供所述布局将跨越的跨度数(lol?)
  • 可以更改跨度数(?)在网格中进行布局时,视图将跨转。默认情况下,视图将跨越一个跨度(使用跨度已经足够了)。

别再用“跨度”这个词了..。

假设您有一个List<Thing>作为数据源。你有0..n个东西。所述Thing具有通过类型来标识的手段。又名:aThing.type。假设你有两种类型:

正常和AD。

代码语言:javascript
复制
enum Type { Normal, AD }

(例如)。

所以你可以这样做:

代码语言:javascript
复制
if (thing.type == Type.AD)

现在,我假设您从存储库收到了一份Thing列表。

您有不同的选择(我将只探索一个,并将其他选项留给读者作为练习,主要是因为我没有那么多时间,但也因为每个最佳解决方案都将真正取决于上下文。我在这里没有太多的上下文)。我的要求很简单:让广告跨越所有网格。

一个简单的解决方案是修改Repository提供给您的结果列表(注意,我不会接触repo的数据,创建一个副本,将副本用于您的适配器)。

因此,当您获得列表时,请修改它,而不是直接将其发送到适配器:

(这是伪代码,假设listOfData是您想要显示的数据,当然已经填充好了)

代码语言:javascript
复制
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 (这只是一种方法,不是唯一的,当然也不是在所有上下文中都是最好的,可能不仅仅是表面上的)。

什么是AdPlaceholder()

这只是一个特殊的“东西”:) (见下文)。

现在,在您的活动/片段中的某处,您可能会这样设置您的回收视图:(同样,伪代码,但有效的Kotlin)

代码语言:javascript
复制
 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。

因此,我添加了以下内容:

代码语言:javascript
复制
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来实际展示这一点。它有一个bug,希望你能发现它(并修复它!) :)

请注意,我没有使用任何AD加载库,这取决于您。请记住,广告通常是作为WebViews实现的,因此往往是缓慢的,异步的,等等。准备好在广告尚未加载时显示占位符,等等。这将真的取决于你如何实现这一方面的事情,天空是限制。这只是我构建的一个简单的样本来验证我的理论。

我个人认为这会更难;我证明了自己是错的。

祝好运。

票数 4
EN

Stack Overflow用户

发布于 2021-04-25 13:56:07

在活动中:

代码语言:javascript
复制
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(mAdapter);

在您的回收器适配器OnCreateViewHolder中:

代码语言:javascript
复制
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方式对serving TYPE_AD进行计算:

代码语言:javascript
复制
@Override
    public int getItemViewType(int position) {

       .........

       if (position % 4 == 0){
          return TYPE_AD;
       }

       .........
    }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56525682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档