SwipeToLoadLayout
SwipeToLoadLayout copied to clipboard
请教个 CoordinatorLayout 和 AppBarLayout 提早下拉刷新的问题
先看布局
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".android.core.activities.MainActivity">
<include layout="@layout/include_app_bar_layout"/>
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</FrameLayout>
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.DrawerLayout>
上面 <include layout="@layout/include_app_bar_layout"/> 就是下面的 AppBarLayout。
中间的 FrameLayout 是主内容,是给Fragment的,Fragment的布局就是你的SwipeToLoadLayout
AppBarLayout
<android.support.design.widget.AppBarLayout
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:animateLayoutChanges="true"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="@dimen/toolbar_height"
android:layout_gravity="center"
android:layout_marginEnd="@dimen/toolbar_margin"
android:layout_marginLeft="@dimen/toolbar_margin"
android:layout_marginRight="@dimen/toolbar_margin"
android:layout_marginStart="@dimen/toolbar_margin"
android:paddingTop="@dimen/toolbar_padding_top_basic"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay">
<include layout="@layout/include_toolbar_basic_light"/>
<include layout="@layout/include_toolbar_basic_dark"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
SwipeToLoadLayout
<com.aspsine.swipetoloadlayout.SwipeToLoadLayout
android:id="@+id/refresh_layout"
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="match_parent">
<!--
Don't add anything nor change the view id, SwipeToLoadLayout hard coded
the view id, and only accept max 3 child views.
-->
<cn.com.cityweekend.android.utils.views.RefreshHeaderView
android:id="@+id/swipe_refresh_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:indicator_color="@color/colorPrimary"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/swipe_target"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
<cn.com.cityweekend.android.utils.views.LoadMoreFooterView
android:id="@+id/swipe_load_more_footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:indicator_color="@color/colorPrimary"/>
</com.aspsine.swipetoloadlayout.SwipeToLoadLayout>
再看截图
这是初始状态

上面蓝色区域整个都是 AppBarLayout,里面就是自己加了几个image和button。 蓝色区域下面就是你的SwipeToLoadLayout。
初始状态下下拉当然是没有问题的,如下图

当屏幕往上滚动的时候,AppBarLayout 整个会一起滚上去,然后往下滚动的时候,AppBarLayout 会马上出现,等 AppBarLayout 全部出现后,然后列表(RecyclerView)才开始滚动,这是 CoordinatorLayout 和 AppBarLayout 组合的效果。
问题就在于,如果滚动状态停在 AppBarLayout 出现一半的时间,松手,然后在往下滚动的时候,会出现下拉刷新,如下图

这样 AppBarLayout 就显示不全了,必须要先往上滚动一下,不松手,再往下滚动,就是正常的效果。
这就是我所谓的“提早下拉刷新的问题”,我稍后录个频帮助理解。
意思是,当AppbarLayout处于缩起状态时,下拉先让其展开,完全展开后再触发刷新吧?
对是的
录屏在此

请问有什么进展吗
@tsunamilx 抱歉,最近比较忙,你可以先尝试自己修复一下。
@tsunamilx 我也遇到这问题,临时找到个解决办法,你可以试试 @Aspsine 作者有没有计划解决这个问题 🙏🙏🙏🙏🙏
public class MainHomeFragment extends BaseFragment implements AppBarLayout.OnOffsetChangedListener{
@Bind(R.id.app_bar_layout)
AppBarLayout app_bar_layout;
@Bind(R.id.swipeToLoadView)
SwipeToLoadView swipeToLoadView;
private void initDisplay() {
app_bar_layout.addOnOffsetChangedListener(this);
}
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
// i == 0 就代表AppBarLayout展开了
if (!swipeToLoadView.isRefreshing())
swipeToLoadView.setRefreshEnabled(i==0);
}
}
让子Fragment实现接口SwipeChildListener
public interface SwipeChildListener {
/**
* 启用下拉刷新功能
*
* @see SwipeLayout#enableRefresh()
*/
void enableRefresh();
/**
* 禁用下拉刷新功能
*
* @see SwipeLayout#disableRefresh()
*/
void disableRefresh();
}
然后在添加AppBarLayout滚动的监听事件
// 监听头部滚动状态
mAppBarLayout.addOnOffsetChangedListener(this);
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
float alpha = (appBarLayout.getTotalScrollRange() + verticalOffset) * 1.0f / appBarLayout.getTotalScrollRange();
// 全面展开状态,在一定范围内
boolean fullExpanded = verticalOffset > -10;
Fragment fragment = mAdapter.mFragmentList.get(mPager.getCurrentItem());
if (fragment != null && fragment instanceof SwipeChildListener) {
SwipeChildListener listener = (SwipeChildListener) fragment;
// 只有在全面展开状态时才允许子页面开启刷新功能以防止手势冲突
if (fullExpanded) {
listener.enableRefresh();
} else {
listener.disableRefresh();
}
}
}
子Fragment实现接口方法:
@Override
public void enableRefresh() {
mSwipeLayout.setRefreshEnabled(true);;
}
@Override
public void disableRefresh() {
mSwipeLayout.setRefreshEnabled(false);
}
还是你们厉害,我是直接修改了SwipeToLoadLayout,把Toolbar塞进了SwipeToLoadLayout里面,然后在onCheckCanRefresh()方法里判断了Toolbar的可见高度来判定是否开始刷新。
@act262 还需要再接口中补充一个isRefreshing的方法,否则在刷新状态时,往上轻轻一推,refresh header会收不回去
public interface SwipeChildListener {
boolean isRefreshing();
void enableRefresh();
void disableRefresh();
}
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
@Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
float alpha = (appBarLayout.getTotalScrollRange() + verticalOffset) * 1.0f / appBarLayout.getTotalScrollRange();
if(!swipeChildListener.isRefreshing()){
// 全面展开状态,在一定范围内
boolean fullExpanded = verticalOffset > -10;
// 只有在全面展开状态时才允许子页面开启刷新功能以防止手势冲突
if (fullExpanded) {
swipeChildListener.enableRefresh();
} else {
swipeChildListener.disableRefresh();
}
}
}
});
是的,还有加载footer的2个方法也需要放到接口处理一下,可以处理子页面内容在没有充满父布局导致的问题