跟踪 Android ListView 中项目的印象

问题描述 投票:0回答:2

我有一个 ListViewArrayAdapter < CustomListViewItem > 设置为其适配器。我想跟踪每个 CustomListViewItem 项目的展示次数。

每当 ListView 项目进入视图时,都应计为一次展示。当它消失并再次出现时,展示次数就会增加。当用户滚动时,某些项目将消失在视图中,而某些项目将进入视图。我想跟踪进入视图和移出视图的项目。

我尝试过的:

我尝试过的一件事是为列表设置setOnScrollListener 查看并进行跟踪 onScroll(AbsListView视图,intfirstVisibleItem,intvisibleItemCount,inttotalItemCount)回调。

我可以使用 firstVisibleItemvisibleItemCount 来完成这项工作。 在文档中,它说这是在滚动完成时调用的。但当滚动缓慢时,它似乎会被调用很多次。可能在滚动的每个像素之后。这使得滚动非常滞后。

还有其他方法可以做到这一点吗?通过使用某种回调,当每个项目离开视图或进入视图时,都会调用该回调?

我在网上搜索了很多,没有看到任何与此类跟踪相关的帖子。

android listview
2个回答
2
投票

我找不到其他方法来做到这一点。所以,我优化了我已经在做的事情。我想我应该分享这个,因为它可能会帮助其他人。

我使用 onScroll()firstVisibleItemvisibleItemCount 仅回调。我使用两个变量来保存先前 onScroll() 回调的信息。他们是:

prevVisibleStartprevVisibleEnd

让我们举个例子来理解算法。 最初假设在第一个 onScroll() 之后

f第一个可见项 = 0visibleItemCount = 3 => 最后的VisibleItem = 2

这些用于设置我之前的可见状态。

所以,prevVisibleStart = firstVisibleItem = 3prevVisibleEnd = 第一个可见项 + 可见项计数 - 1 = 2

现在如果我向下滚动,我将永远拥有

firstVisibleItem >= prevVisibleStartlastVisibleItem >= prevVisibleEnd

所以,如果之前的范围是 0 到 2。新的范围会有点像 1 到 3。因为,我已经考虑了 0 到 2 的印象。我只会将 3 视为新印象。原因是视图 1、2 仍然在视图中并且没有消失。因此,新印象不计入这些。这有效地给出了考虑展示次数的正确范围,并减少了检查范围。

同样,向上滚动也可以这样做。 假设当前可见项为2-4。 现在,向上滚动后,范围变为(例如)1-3。这意味着1已经进入视野。因此,计算此视图的展示次数。这样 onScroll() 中的操作次数显着减少。

示例代码如下

范围 [i-j) 被视为印象。

private static int prevVisibleStart=-1;
private static int prevVisibleEnd=-1;
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
 if(prevVisibleStart <= firstVisibleItem) {
  // scroll down
  i = Math.max(firstVisibleItem, prevVisibleEnd + 1);
  j = firstVisibleItem + visibleItemCount;
 } else {
  // scroll up
  i = firstVisibleItem;
  j = Math.min(prevVisibleStart, firstVisibleItem + visibleItemCount);
 }
 prevVisibleStart = firstVisibleItem;
 prevVisibleEnd = firstVisibleItem + visibleItemCount - 1;
 // now can use [i-j) to update impressions
}

0
投票

在适配器中定义回调

var onAttachView: ((position: Int) -> Unit)? = null

并在适配器的onViewAttachedToWindow方法中调用它

 override fun onViewAttachedToWindow(holder: ViewHolder) {
    super.onViewAttachedToWindow(holder)
    onAttachView?.invoke(holder.bindingAdapterPosition)
}

如果您只想发送列表中项目的一次印象,您可以将报告的位置临时保存在视图模型或分析存储库中,然后根据您的会话策略将其清除。

© www.soinside.com 2019 - 2024. All rights reserved.