我在一个应用程序的工作,有一个回收视图,你可以向上和向下滚动,但你希望。
数据项是从服务器加载的,所以如果你要到达底部或顶部,应用程序会在那里显示新的数据。
为了避免奇怪的滚动行为并保持在当前项上,我使用'diffutil.callback',重写'get oldlistsize'、'get newlistsize'、'are itemsthesame'、'are contentsthesame'。
由于Internet连接可能会很慢,在这个RecycerView中有一个页眉项和页脚项,它们只是有一个特殊的进度视图,以显示您已经到达边缘,它将很快被加载。
页眉和页脚始终存在于列表中,它们不从服务器接收。它纯粹是UI的一部分,只是为了显示即将加载的东西。
事情是,就像其他项一样,它需要由diffutil.callback处理,所以对于areItemsTheSame
和areContentsTheSame
,如果旧页眉是新页眉,旧页脚是新页脚,我只返回true:
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
when {
oldItem.itemType != newItem.itemType -> return false
oldItem.itemType == ItemType.TYPE_FOOTER || oldItem.itemType == AgendaItem.TYPE_HEADER -> return true
...
}
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldItems[oldItemPosition]
val newItem = newItems[newItemPosition]
return when {
oldItem.itemType == ItemType.TYPE_FOOTER || oldItem.itemType == ItemType.TYPE_HEADER -> true
...
}
}
}
因此,如果您停留在标题上,服务器向您发送了新列表,您仍然可以看到标题,并在新项下面,而看不到旧项。它为你滚动而不是停留在相同的位置上。
这里有一张草图显示了这个问题。黑色矩形显示列表的可见部分。
我在想一些变通办法,但每一种都有自己的缺点:
>
一个NestedScrollView(或RecycerView),它将把页眉和页脚以及RecycerView放在中间,但这可能会导致一些滚动问题,特别是由于我已经有了一个依赖于RecycerView的复杂布局(视图的折叠等)。
也许在普通项目的布局中,我也可以把页眉和页脚的布局(或者只是页眉,因为这个是有问题的)。但这对性能来说是一件坏事,因为它徒劳地膨胀了额外的视图。另外,它要求我切换隐藏和查看新视图。
是否有方法告诉diffutil.callback
:“这些项(页眉和页脚)不是要滚动到的实际项,而这些项(实际数据项)应该是”?
我会试着解释一下我认为解决你问题的办法:
步骤1:移除页脚和页眉视图的所有代码。
步骤2:添加这些方法,根据用户滚动方向在adapter中添加和移除虚拟模型项:
/**
* Adds loader item in the adapter based on the given boolean.
*/
public void addLoader(boolean isHeader) {
if (!isLoading()) {
ArrayList<Model> dataList = new ArrayList<>(this.oldDataList);
if(isHeader) {
questions.add(0, getProgressModel());
else {
questions.add(getProgressModel());
setData(dataList);
}
}
/**
* Removes loader item from the UI.
*/
public void removeLoader() {
if (isLoading() && !dataList.isEmpty()) {
ArrayList<Model> dataList = new ArrayList<>(this.oldDataList);
dataList.remove(getDummyModel());
setData(questions);
}
}
public MessageDetail getChatItem() {
return new Model(0, 0, 0, "", "", "")); // Here the first value is id which is set as zero.
}
下面是适配器逻辑的其余部分,您需要确定该项是加载器项还是实际数据项:
@Override
public int getItemViewType(int position) {
return dataList.get(position).getId() == 0 ? StaticConstants.ItemViewTypes.PROGRESS : StaticConstants.ItemViewTypes.CONTENT;
}
根据视图类型,可以在适配器中添加进度条视图持有人。
步骤3:在数据加载逻辑中使用这些方法:
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy < 0) { //This is top scroll, so add a loader as the header.
recyclerViewAdapter.addLoader(true);
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
if (!recyclerViewAdapter.isLoading(true)) {
if (linearLayoutManager.findFirstCompletelyVisibleItemPosition() <= 2) {
callFetchDataApi();
}
}
}
} else {
if (!recyclerViewAdapter.isLoading(false)) {
if (linearLayoutManager.findLastCompletelyVisibleItemPosition() >= linearLayoutManager.getItemCount() - 2) {
callFetchDataApi();
}
}
});
private void onGeneralApiSuccess(ResponseModel responseModel) {
myStreamsDashboardAdapter.removeLoader();
if (responseModel.getStatus().equals(SUCCESS)) {
// Manage your pagination and other data loading logic here.
dataList.addAll(responseModel.getDataList());
recyclerViewAdapter.setData(dataList);
}
}
public boolean isLoading(boolean isFromHeader) {
if (isFromHeader) {
return dataList.isEmpty() || dataList.get(0).getId() == 0;
} else {
return dataList.isEmpty() || dataList.get(dataList.size() -1).getId() == 0;
}
}
也许以前有人问过这个问题,但我似乎找不到一个准确的答案或解决办法。我开始使用RecycerView,并使用LinearLayoutManager实现了它。现在,我想添加自定义的页眉和页脚项,这些项不同于RecycerView中的其他项。页眉和页脚不应该粘,我希望他们滚动与其余的项目。有人能指出一些例子如何做到这一点或只是分享想法。我会非常感激的。THX
我花了一点时间试图找到一种方法来向添加一个标头,但没有成功。 这是我目前得到的: 似乎是处理项的对象。由于我找不到任何方法,所以我决定使用的方法,并在第一个位置添加header视图以充当header。 这就是事情变得更丑陋的地方: 在创建活动的不同时刻,尝试调用的几次(也尝试在设置好所有内容后添加视图,甚至适配器的数据)之后,我意识到我不知道这是否是正确的方法(而且看起来并不正确)。 PS:另外,
问题内容: 如何使用itext从html源向pdf添加标头? 当前,我们扩展了PdfPageEventHelper并覆盖了这些方法。工作正常,但是当我进入2个以上页面时,它将引发RuntimeWorkerException。 问题答案: 通常, 禁止 在事件中添加内容。这是 禁止 添加内容到的对象。您应该使用而 不是 文档在方法中添加页眉和页脚。此外:通过一遍又一遍地解析HTML,您正在浪费大量C
使用iTextSharp,您可以通过将事件附加到PDF来向PDF添加页眉/页脚,如本SO答案中所述:https://stackoverflow.com/a/19004392 我怎样才能用 iText 7 做同样的事情? 这个链接有Java代码示例,但看起来不像它使用的页面事件。
问题内容: 我真的不喜欢在每个控制器中编写代码: 是否可以这样做,将自动包含页眉和页脚,如果需要更改它,我们也可以这样做吗?你怎么处理?还是您认为这不是问题?谢谢。 问题答案: 这是我的工作: 对于CI 3.x: 然后,在您的控制器中,这就是您要做的一切:
我正在开发一个Spring MVC应用程序,它将FreeMarker用于我的视图。 我对FreeMarker非常陌生,我有以下问题:在我的projct中,有3个文件必须被组装到一个页面中。 所以我有: 1) 标题。ftl表示我所有页面的标题,类似于: 2)footer.ftl代表我所有页面的页脚: 3) 然后我有了我的特定页面(名为myPage.ftl),它只表示内容,如下所示: 标题。ftl和页