CoordinatorLayout+SwipeRefreshLayout+Endless RecyclerView 的奇怪行为
Weird behavior with CoordinatorLayout+SwipeRefreshLayout+Endless RecyclerView
我正在尝试实现一个 CoordinatorLayout
和一个折叠的 ToolBar
。我已经有一个 SwipeRefreshLayout
里面有一个 RecyclerView
。此回收器视图还有一个 onScrollListener
用于加载更多内容,以及一个自定义适配器用于在加载更多内容时显示加载 ViewHolder
。
在我尝试添加 CoordinatorLayout
之前一切正常。现在我有两个问题:
第一次加载项目时,加载 ViewHolder
出现并且位置很好(在 ToolBar
下方)。完成后,将删除加载并添加项目。问题是第一项是隐藏的。这就像第二个项目实际上是第一个。完全不可能看到第一项,即使它比 ToolBar
大。但是当我使用滑动刷新时,该项目被正确放置。我不知道为什么会这样。
当我使用滑动刷新时,它加载了两次项目。第一次是正常加载,第二次是加载更多项目,因为 onScrollListener
。然而,卷轴仍然在列表的顶部。在我滚动之前,回收器视图项目保持不可见(我认为这是因为我只通知新项目的适配器,但我们仍然在列表的顶部)。
但是,我不知道要在侦听器中更改什么来解决此问题。
监听器如下:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(!adapter.isLoading()) {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//position starts at 0
if (layoutManager.findLastCompletelyVisibleItemPosition() >= layoutManager.getItemCount() - 2) {
loadSubmissions(false);
}
}
}
});
我的activity布局:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
我的工具栏:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:elevation="4dp"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
两个问题都已解决。对于第一个,当我删除加载 ViewHolder 时,我实际上是在做 notifyItemInserted
而不是 notifyItemRemoved
.
第二个问题是因为我在滑动刷新的时候调用了notifyDatasetChanged
@Override public void onRefresh() {
adapter.clear();
adapter.notifyDataSetChanged();
loadSubmissions(true);
}
当我通过滑动刷新来清除适配器时,我正在滑动,所以这意味着将调用 onScrollListener。
我更改了侦听器并添加了验证以在没有项目时不加载更多内容。
mRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int current_page) {
// Doesnt load multiples times with the same scroll and doesnt load if there are no items
if(!adapter.isLoading() && adapter.getItemCount() > 0) {
loadSubmissions(false);
}
}
});
我正在尝试实现一个 CoordinatorLayout
和一个折叠的 ToolBar
。我已经有一个 SwipeRefreshLayout
里面有一个 RecyclerView
。此回收器视图还有一个 onScrollListener
用于加载更多内容,以及一个自定义适配器用于在加载更多内容时显示加载 ViewHolder
。
在我尝试添加 CoordinatorLayout
之前一切正常。现在我有两个问题:
第一次加载项目时,加载
ViewHolder
出现并且位置很好(在ToolBar
下方)。完成后,将删除加载并添加项目。问题是第一项是隐藏的。这就像第二个项目实际上是第一个。完全不可能看到第一项,即使它比ToolBar
大。但是当我使用滑动刷新时,该项目被正确放置。我不知道为什么会这样。当我使用滑动刷新时,它加载了两次项目。第一次是正常加载,第二次是加载更多项目,因为
onScrollListener
。然而,卷轴仍然在列表的顶部。在我滚动之前,回收器视图项目保持不可见(我认为这是因为我只通知新项目的适配器,但我们仍然在列表的顶部)。
但是,我不知道要在侦听器中更改什么来解决此问题。
监听器如下:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if(!adapter.isLoading()) {
LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
//position starts at 0
if (layoutManager.findLastCompletelyVisibleItemPosition() >= layoutManager.getItemCount() - 2) {
loadSubmissions(false);
}
}
}
});
我的activity布局:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/contentView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="6dp"
android:paddingTop="6dp"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
我的工具栏:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/colorPrimary"
android:elevation="4dp"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
两个问题都已解决。对于第一个,当我删除加载 ViewHolder 时,我实际上是在做 notifyItemInserted
而不是 notifyItemRemoved
.
第二个问题是因为我在滑动刷新的时候调用了notifyDatasetChanged
@Override public void onRefresh() {
adapter.clear();
adapter.notifyDataSetChanged();
loadSubmissions(true);
}
当我通过滑动刷新来清除适配器时,我正在滑动,所以这意味着将调用 onScrollListener。
我更改了侦听器并添加了验证以在没有项目时不加载更多内容。
mRecyclerView.addOnScrollListener(new EndlessRecyclerOnScrollListener(linearLayoutManager) {
@Override
public void onLoadMore(int current_page) {
// Doesnt load multiples times with the same scroll and doesnt load if there are no items
if(!adapter.isLoading() && adapter.getItemCount() > 0) {
loadSubmissions(false);
}
}
});