dkzwm / SmoothRefreshLayout

一款支持上下拉刷新、越界回弹、二级刷新、横向刷新、拉伸回弹、平滑滚动、嵌套滚动的多功能刷新控件
MIT License
1.3k stars 218 forks source link

这样子下拉刷新和上拉刷新会有问题 #101

Closed jack-laowang closed 4 years ago

jack-laowang commented 4 years ago

<?xml version="1.0" encoding="utf-8"?> <me.dkzwm.widget.srl.SmoothRefreshLayout android:id="@+id/smoothRefreshLayout_test_base_recyclerView_adapter" 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" android:orientation="vertical">

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView_test_base_recyclerView_adapter"
    android:layout_width="match_parent"
    android:nestedScrollingEnabled="false"
    android:layout_height="match_parent"/>
</androidx.core.widget.NestedScrollView>

</me.dkzwm.widget.srl.SmoothRefreshLayout>

jack-laowang commented 4 years ago

就是下拉刷新完成了,然后再去上拉加载更多,就看不到上拉加载更多 你的demo里面,以上代码 上拉加载更多,第二次就上拉不了了

dkzwm commented 4 years ago

@MinchinWang TestBaseRecyclerViewAdapterActivity的加载更多能力是使用的BRVA的加载更多实现,不是SRL的上拉加载实现,

dkzwm commented 4 years ago

@MinchinWang 我个人是不是很理解这样嵌套的意义,个人比较倾向于界面直接使用RecyclerView进行实现,这样嵌套添加数据后为保证RecyclerView高度能得到正确计算,请手动调用requestLayout触发重布局。

dkzwm commented 4 years ago

或者请不要设置RecyclerView的setHasFixedSize(true),这样每次数据变动都会进行重计算

jack-laowang commented 4 years ago

RecyclerView的setHasFixedSize(true) 一样的,因为我外出弄一个NestedScrollView初衷是以下布局

<me.dkzwm.widget.srl.SmoothRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/smoothRefreshLayout_test_base_recyclerView_adapter" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:sr_content="@+id/recyclerView_test_base_recyclerView_adapter">

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="2" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="3" />

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView_test_base_recyclerView_adapter"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
</androidx.core.widget.NestedScrollView>

</me.dkzwm.widget.srl.SmoothRefreshLayout>

dkzwm commented 4 years ago

@MinchinWang 我这边模拟同样的布局,去掉recyclerView.setHasFixedSize(true)后或者在Adapter设置数据后手动调用requestLayout均能正常使用

dkzwm commented 4 years ago
<?xml version="1.0" encoding="utf-8"?>
<me.dkzwm.widget.srl.SmoothRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/smoothRefreshLayout_test_base_recyclerView_adapter"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="@string/app_name"
                android:textSize="18sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:text="@string/app_name"
                android:textSize="18sp" />

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyclerView_test_base_recyclerView_adapter"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</me.dkzwm.widget.srl.SmoothRefreshLayout>
package me.dkzwm.widget.srl.sample.ui;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.MenuItem;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import java.util.List;
import me.dkzwm.widget.srl.RefreshingListenerAdapter;
import me.dkzwm.widget.srl.SmoothRefreshLayout;
import me.dkzwm.widget.srl.extra.header.ClassicHeader;
import me.dkzwm.widget.srl.sample.R;
import me.dkzwm.widget.srl.sample.adapter.LoadMoreRecyclerViewAdapter;
import me.dkzwm.widget.srl.sample.utils.DataUtil;

/**
 * Created by dkzwm on 2017/8/8.
 *
 * @author dkzwm
 */
public class TestBaseRecyclerViewAdapterActivity extends AppCompatActivity {
    private SmoothRefreshLayout mRefreshLayout;
    private RecyclerView mRecyclerView;
    private BaseQuickAdapter<String, BaseViewHolder> mAdapter;
    private Handler mHandler = new Handler();
    private int mCount = 0;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setTitle(R.string.test_base_recyclerView_adapter);
        setContentView(R.layout.activity_test_base_recyclerview_adapter);
        mRefreshLayout = findViewById(R.id.smoothRefreshLayout_test_base_recyclerView_adapter);
        ClassicHeader classicHeader = new ClassicHeader(this);
        classicHeader.setLastUpdateTimeKey("header_last_update_time");
        mRefreshLayout.setHeaderView(classicHeader);
        mRefreshLayout.setDisableLoadMore(false);
        mRefreshLayout.setOnRefreshListener(
                new RefreshingListenerAdapter() {
                    @Override
                    public void onRefreshing() {
                        mHandler.postDelayed(
                                new Runnable() {
                                    @Override
                                    public void run() {
                                        List<String> list = DataUtil.createList(mCount, 20);
                                        mCount = list.size();
                                        mAdapter.setNewData(list);
                                        mRefreshLayout.refreshComplete();
                                    }
                                },
                                2000);

                    }

                    @Override
                    public void onLoadingMore() {
                        mHandler.postDelayed(
                                new Runnable() {
                                    @Override
                                    public void run() {
                                        List<String> list = DataUtil.createList(mCount, 20);
                                        mCount += list.size();
                                        mAdapter.addData(list);
                                        mAdapter.loadMoreComplete();
                                        mRefreshLayout.refreshComplete();
                                    }
                                },
                                2000);
                    }
                });
        mAdapter = new LoadMoreRecyclerViewAdapter(this);
        mRefreshLayout.autoRefresh(true);
        mRecyclerView = findViewById(R.id.recyclerView_test_base_recyclerView_adapter);
        mRecyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setAdapter(mAdapter);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                onBackPressed();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public void onBackPressed() {
        startActivity(new Intent(TestBaseRecyclerViewAdapterActivity.this, MainActivity.class));
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacksAndMessages(null);
    }
}

测试没有发现不能使用刷新和加载更多能力的问题。

jack-laowang commented 4 years ago

作者你好,demo TestBaseRecyclerViewAdapterActivity 这个类里面的布局改成我发的那样子 下拉不行,可以试试看

dkzwm commented 4 years ago

@MinchinWang 你的布局有问题指定了app:sr_content="@+id/recyclerView_test_base_recyclerView_adapter" ,不需要指定,因为滚动视图是NestedScrollView而不是RecyclerView

jack-laowang commented 4 years ago

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" android:background="@color/transparent" android:orientation="vertical">

<ImageView
    android:layout_width="match_parent"
    android:layout_height="210dp"
    android:scaleType="fitXY"
    android:src="@mipmap/bg_bhs_home" />

<me.dkzwm.widget.srl.SmoothRefreshLayout
    android:id="@+id/refreshLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/layout_title">

    <android.support.design.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.design.widget.AppBarLayout
            android:id="@+id/layout_app_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/transparent"
            android:elevation="0dp"
            app:elevation="0dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                app:layout_scrollFlags="scroll|snap">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical">

                    <com.bisinuolan.app.base.widget.traviewpager.UltraViewPager
                        android:id="@+id/banner"
                        android:layout_width="match_parent"
                        android:layout_height="130dp" />

                    <android.support.v7.widget.RecyclerView
                        android:id="@+id/rec_classify"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content" />

                </LinearLayout>
            </LinearLayout>

            <com.ogaclejapan.smarttablayout.SmartTabLayout
                android:id="@+id/smartlayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/white"
                android:gravity="center"
                app:stl_customTabTextLayoutId="@layout/item_bhs_tab"
                app:stl_customTabTextViewId="@+id/custom_text"
                app:stl_defaultTabTextMinWidth="40dp"
                app:stl_dividerThickness="0dp"
                app:stl_indicatorColor="@color/colorAccent"
                app:stl_indicatorCornerRadius="10dp"
                app:stl_indicatorInterpolation="linear"
                app:stl_indicatorThickness="0dp"
                app:stl_indicatorWidth="19dp"
                app:stl_underlineThickness="0dp" />

        </android.support.design.widget.AppBarLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:orientation="vertical"
            android:layout_height="match_parent"
            android:background="@color/act_bg_shadow"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">

            <android.support.v4.view.ViewPager
                android:id="@+id/view_pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_margin="5dp"
                android:overScrollMode="never" />

        </FrameLayout>

    </android.support.design.widget.CoordinatorLayout>
</me.dkzwm.widget.srl.SmoothRefreshLayout>

以上是XML布局

//设置属性 refreshLayout.setEnableOverScroll(false); refreshLayout.setDisableLoadMore(true); refreshLayout.setDisableWhenAnotherDirectionMove(true);

问题描述 fragment 是用BaseRecyclerViewAdapterHelper的加载更多使用,但是滑到viewpager 2、3、4...位置然后再加载更多几次,上拉到顶部不能上拉刷新 要返回viewpager 0的位置 上拉加载更多在上拉才有出现,后面滑到2、3、4..位置加载更多在返回头部就上拉不来

dkzwm commented 4 years ago

上拉加载还是下拉刷新,看你描述比较混乱,不是很懂你描述的意思😵

dkzwm commented 4 years ago

这边Android Support库对应版本已经停止更新了的,我看了下代码布局和demo中的TestNestedWithViewPagerActivity大体一致,你可以尝试打开setEnableDynamicEnsureTargetView(true),让Srl根据手指按下动态判断内部滚动视图

dkzwm commented 4 years ago

如果仍然无法使用,那么你需要手动定义下边界判断逻辑

        mRefreshLayout.setOnHeaderEdgeDetectCallBack(new SmoothRefreshLayout.OnHeaderEdgeDetectCallBack() {
            @Override
            public boolean isNotYetInEdgeCannotMoveHeader(SmoothRefreshLayout parent, @Nullable View child, @Nullable IRefreshView header) {
                return false;
            }
        });
        mRefreshLayout.setOnFooterEdgeDetectCallBack(new SmoothRefreshLayout.OnFooterEdgeDetectCallBack() {
            @Override
            public boolean isNotYetInEdgeCannotMoveFooter(SmoothRefreshLayout parent, @Nullable View child, @Nullable IRefreshView footer) {
                return false;
            }
        });

具体代码实现可以参考AppBarUtil

jack-laowang commented 4 years ago

我这边的xml布局就是拿 TestNestedWithViewPagerActivity的布局来的 setEnableDynamicEnsureTargetView(true)还是不行 还有AppBarUtil这个类demo没找到

dkzwm commented 4 years ago

AppBarUtilcore资源包me.dkzwm.widget.srl.util包名下 这边配置边界判断逻辑,需要组合判断AppBarLayout的展开状态和ViewPager内当前item所对应的滚动视图是否到顶或者是否到底