Java 如何在RecyclerView中实现setOnScrollListener

Java 如何在RecyclerView中实现setOnScrollListener,java,android-cardview,android-recyclerview,onscrolllistener,endlessscroll,Java,Android Cardview,Android Recyclerview,Onscrolllistener,Endlessscroll,当用户访问列表中可见的项目时,如何在底部显示进度条 我已经编写了一段代码,其中我使用web服务获取数据,现在我想填充部分记录,因为我的JSON中有大约630条记录 这是我用来从JSON获取数据并填充到RecyclerView的全部代码 下面是我的JSON的外观,但真正的JSON包含600多条记录: http://walldroidhd.com/api.php 有人能指导我在哪里修改代码吗 每当用户使用progressbar滚动到底部时,我想填充更多记录,但我仍然显示所有记录 RecycleS

当用户访问列表中可见的项目时,如何在底部显示进度条

我已经编写了一段代码,其中我使用web服务获取数据,现在我想填充部分记录,因为我的JSON中有大约630条记录

这是我用来从JSON获取数据并填充到RecyclerView的全部代码

下面是我的JSON的外观,但真正的JSON包含600多条记录:

 http://walldroidhd.com/api.php
有人能指导我在哪里修改代码吗

每当用户使用progressbar滚动到底部时,我想填充更多记录,但我仍然显示所有记录

RecycleServicewFragment.java:

public class RecyclerViewFragment extends Fragment {

    RecyclerView mRecyclerView;
    LinearLayoutManager mLayoutManager;
    RecyclerView.Adapter mAdapter;
    ArrayList<NatureItem> actorsList;

    private int previousTotal = 0;
    private boolean loading = true;
    private int visibleThreshold = 5;
    int firstVisibleItem, visibleItemCount, totalItemCount;

    public static RecyclerViewFragment newInstance() {
        return new RecyclerViewFragment();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_recyclerview_advance, container, false);
    }

    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        actorsList = new ArrayList<NatureItem>();

        new JSONAsyncTask().execute("my JSON url");

        mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
        mRecyclerView.setHasFixedSize(true);

        mLayoutManager = new GridLayoutManager(getActivity(), 2);
        mRecyclerView.setLayoutManager(mLayoutManager);

        mRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                visibleItemCount = mRecyclerView.getChildCount();
                totalItemCount = mLayoutManager.getItemCount();
                firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();

                if (loading) {
                    if (totalItemCount > previousTotal) {
                        loading = false;
                        previousTotal = totalItemCount;
                    }
                }
                if (!loading && (totalItemCount - visibleItemCount)
                        <= (firstVisibleItem + visibleThreshold)) {
                    // End has been reached

                    Log.i("...", "end called");

                    // Do something

                    loading = true;
                }
            }
        });

        // mAdapter = new CardAdapter();
        mAdapter = new RecyclerViewMaterialAdapter(new CardAdapter(getActivity(), actorsList), 2);
        mRecyclerView.setAdapter(mAdapter);

        MaterialViewPagerHelper.registerRecyclerView(getActivity(), mRecyclerView, null);

        mRecyclerView.addOnItemTouchListener(
                new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {

                        Toast.makeText(getActivity(), String.valueOf(position), Toast.LENGTH_LONG).show();

                    }
                })
        );

    }

    class JSONAsyncTask extends AsyncTask<String, Void, Boolean> {

        ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            dialog = new ProgressDialog(getActivity());
            dialog.setMessage("Loading, please wait");
            dialog.setTitle("Connecting server");
            dialog.show();
            dialog.setCancelable(false);
        }

        @Override
        protected Boolean doInBackground(String... urls) {
            try {

                //------------------>>
                HttpGet httppost = new HttpGet(urls[0]);
                HttpClient httpclient = new DefaultHttpClient();
                HttpResponse response = httpclient.execute(httppost);

                // StatusLine stat = response.getStatusLine();
                int status = response.getStatusLine().getStatusCode();

                if (status == 200) {
                    HttpEntity entity = response.getEntity();
                    String data = null;
                    try {
                        data = EntityUtils.toString(entity);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }


                    JSONObject jsono = null;
                    try {
                        jsono = new JSONObject(data);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    JSONArray jarray = jsono.getJSONArray("wallpapers");


                    for (int i = 0; i < jarray.length(); i++) {
                        JSONObject object = jarray.getJSONObject(i);

                        NatureItem actor = new NatureItem();

                        actor.setName(object.getString("id"));
                        actor.setThumbnail(object.getString("thumb_url"));

                        actorsList.add(actor);
                    }
                    return true;
                }

                //------------------>>

            } catch (ParseException e1) {
                e1.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                e.printStackTrace();
            }
            return false;
        }

        protected void onPostExecute(Boolean result) {
            dialog.cancel();
            mAdapter.notifyDataSetChanged();
            if (result == false) {
                Toast.makeText(getActivity(), "Unable to fetch data from server", Toast.LENGTH_LONG).show();
            }
            else {

            }

        }
    }
}
public class CardAdapter extends RecyclerView.Adapter<CardAdapter.ViewHolder> {

    private ArrayList<NatureItem> mItems;
    private Context mContext;

    public CardAdapter(Context context, ArrayList<NatureItem> feedItemList) {
        this.mItems = feedItemList;
        this.mContext = context;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext())
                .inflate(R.layout.recycler_view_card_item, viewGroup, false);

        ViewHolder viewHolder = new ViewHolder(v);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(ViewHolder viewHolder, int i) {
        NatureItem nature = mItems.get(i);
        viewHolder.tvNature.setText(nature.getName());

        Picasso.with(mContext).load(nature.getThumbnail())
                .error(R.mipmap.ic_launcher)
                .placeholder(R.mipmap.ic_launcher)
                .into(viewHolder.imgThumbnail);

    }

    @Override
    public int getItemCount() {
        return mItems.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        public ImageView imgThumbnail;
        public TextView tvNature;

        public ViewHolder(View itemView) {
            super(itemView);
            imgThumbnail = (ImageView)itemView.findViewById(R.id.img_thumbnail);
            tvNature = (TextView)itemView.findViewById(R.id.tv_nature);
        }
    }
}

注意:我个人更喜欢使用RecyclerView onScroll功能来完成我的工作。

在onScroll方法中

if (!loading && (totalItemCount - visibleItemCount)
        <= (firstVisibleItem + visibleThreshold)) {
    // End has been reached

    Log.i("...", "end called");

    // Do something
    new JSONAsyncTask().execute("http://walldroidhd.com/api.php");

    loading = true;
}
if(!loading&&(totalItemCount-VisibleTItemCount)

实现更多负载的想法是:


获取一个集合中的所有记录。获取另一个将填充部分记录的集合,例如10条记录。现在,当你到达底部时,填充集合中的下10条记录并通知列表

因此,您的代码如下所示:

ArrayList<NatureItem> tempList; // which holds partial records
tempList = getList(limit, 10);

mAdapter = new RecyclerViewMaterialAdapter(new CardAdapter(getActivity(), tempList), 2);
mRecyclerView.setAdapter(mAdapter);

要显示加载程序/进度,最好使用

这是我如何通过
OnScrollListener
检测
RecyclerView
是否应刷新的,请查看它:

recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
    int ydy = 0;
    @Override
    public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
        super.onScrollStateChanged(recyclerView, newState);

    }

    @Override
    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
        super.onScrolled(recyclerView, dx, dy);
        int offset = dy - ydy;
        ydy = dy;
        boolean shouldRefresh = (linearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0)
                && (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) && offset > 30;
        if (shouldRefresh) {
            //swipeRefreshLayout.setRefreshing(true);
            //Refresh to load data here.
            return;
        }
        boolean shouldPullUpRefresh = linearLayoutManager.findLastCompletelyVisibleItemPosition() == linearLayoutManager.getChildCount() - 1
                && recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING && offset < -30;
        if (shouldPullUpRefresh) {
            //swipeRefreshLayout.setRefreshing(true);
            //refresh to load data here.
            return;
        }
        swipeRefreshLayout.setRefreshing(false);
    }
});

recyclerView.setOnScrollListener(新的recyclerView.OnScrollListener(){
int-ydy=0;
@凌驾
CrollStateChanged上的公共无效(RecyclerView RecyclerView,int newState){
super.onScrollStateChanged(recyclerView、newState);
}
@凌驾
已填空的公共空间(RecyclerView RecyclerView、int dx、int dy){
super.onScrolled(recyclerView、dx、dy);
int offset=dy-ydy;
ydy=dy;
布尔值shouldRefresh=(linearLayoutManager.findFirstCompletelyVisibleItemPosition()==0)
&&(recyclerView.getScrollState()==recyclerView.SCROLL\u状态\u拖动)&偏移量>30;
如果(应刷新){
//swipeRefreshLayout.setRefreshing(true);
//刷新以在此处加载数据。
返回;
}
布尔值shouldPullUpRefresh=linearLayoutManager.findLastCompletelyVisibleItemPosition()==linearLayoutManager.getChildCount()-1
&&recyclerView.getScrollState()==recyclerView.SCROLL\u STATE\u拖动和偏移<-30;
如果(应使用pulluprefresh){
//swipeRefreshLayout.setRefreshing(true);
//刷新以在此处加载数据。
返回;
}
swipeRefreshLayout.setRefreshing(false);
}
});

希望您能有所启发。祝您好运~

在xml布局文件中使用recylcerview的活动类

public class WallpaperActivity extends AppCompatActivity implements OnTaskCompleted {


private static final String TAG = "WallpaperActivity";


private Toolbar toolbar;


private RecyclerView mRecyclerView;
private WallPaperDataAdapter mAdapter;
private LinearLayoutManager mLayoutManager;
// to keep track which pages loaded and next pages to load
public static int pageNumber;

private List<WallPaper> wallpaperImagesList;


protected Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.wallpaper_main);
    toolbar = (Toolbar) findViewById(R.id.toolbar);
    mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
    pageNumber = 1;
    wallpaperImagesList = new ArrayList<WallPaper>();
    handler = new Handler();
    if (toolbar != null) {
        setSupportActionBar(toolbar);
        getSupportActionBar().setTitle("WallPapers");

    }


    // use this setting to improve performance if you know that changes
    // in content do not change the layout size of the RecyclerView
    mRecyclerView.setHasFixedSize(true);


    mLayoutManager = new LinearLayoutManager(this);


    // use a linear layout manager
    mRecyclerView.setLayoutManager(mLayoutManager);


    // create an Object for Adapter
    mAdapter = new WallPaperDataAdapter(wallpaperImagesList, mRecyclerView);

    // set the adapter object to the Recyclerview
    mRecyclerView.setAdapter(mAdapter);


    getWebServiceData();


    mAdapter.setOnLoadMoreListener(new OnLoadMoreListener() {
        @Override
        public void onLoadMore() {
            //add null , so the adapter will check view_type and show progress bar at bottom
            wallpaperImagesList.add(null);
            mAdapter.notifyItemInserted(wallpaperImagesList.size() - 1);
            ++pageNumber;


            getWebServiceData();


        }
    });


}


public void getWebServiceData() {

    BackGroundTask backGroundTask = new BackGroundTask(this, this, pageNumber);
    backGroundTask.execute();

}


@Override
public void onTaskCompleted(String response) {


    parsejosnData(response);

}


public void parsejosnData(String response) {

    try {

        JSONObject jsonObject = new JSONObject(response);

        //    String json = jsonObject.toString();

        JSONArray jsonArray = jsonObject.getJSONArray("wallpapers");


        if (jsonArray != null) {
            // looping through All albums


            if (pageNumber > 1) {
                wallpaperImagesList.remove(wallpaperImagesList.size() - 1);
                mAdapter.notifyItemRemoved(wallpaperImagesList.size());
            }

            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject c = jsonArray.getJSONObject(i);

                // Storing each json item values in variable
                String id = c.getString("id");
                String orig_url = c.getString("orig_url");
                String thumb_url = c.getString("thumb_url");
                String downloads = c.getString("downloads");
                String fav = c.getString("fav");

                // Creating object for each product
                WallPaper singleWall = new WallPaper(id, orig_url, thumb_url, downloads, fav);

                // adding HashList to ArrayList
                wallpaperImagesList.add(singleWall);


                handler.post(new Runnable() {
                    @Override
                    public void run() {
                       mAdapter.notifyItemInserted(wallpaperImagesList.size());


                    }
                });


            }


            mAdapter.setLoaded();


        } else {
            Log.d("Wallpapers: ", "null");
        }

    } catch (JSONException e) {
        e.printStackTrace();
    }

}


}
用于了解从asynctask加载的web服务数据的接口

public interface OnTaskCompleted{

    void onTaskCompleted(String response);
}
请让我知道这是否有效或对您有任何问题。 最好使用Volley或okHttp库进行联网

对于图像加载,我使用了库。

另一个示例。在底部设置进度条,并根据滚动/加载和记录更改其可见性。注意:需要调用notifyDataSetChanged();方法向适配器添加/刷新数据

  recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int total = linearLayoutManager.getItemCount();
                int firstVisibleItemCount = linearLayoutManager.findFirstVisibleItemPosition();
                int lastVisibleItemCount = linearLayoutManager.findLastVisibleItemPosition();

                //to avoid multiple calls to loadMore() method
                //maintain a boolean value (isLoading). if loadMore() task started set to true and completes set to false
                if (!isLoading) { 
                    if (total > 0) 
                        if ((total - 1) == lastVisibleItemCount){
                           loadMore();//your HTTP stuff goes in this method 
                           loadingProgress.setVisibility(View.VISIBLE);
                        }else
                           loadingProgress.setVisibility(View.GONE);
                }
            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

            }

    });

要在Kotlin中为RecyclerView实现OnScrollListener,可以使用

recyclerViewChat.addOnScrollListener(object : RecyclerView.OnScrollListener() {

            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    Log.d("scroll", "idle")
                } else if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
                    Log.d("scroll", "settling")
                } else if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    Log.d("scroll", "dragging")
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                Log.d("scroll", "scrolling")
            }
        })

现在被接受的答案是@SilentKnight建议的,因为Android SDK不推荐使用setOnscroll

你应该使用

recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
        int ydy = 0;
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            int offset = dy - ydy;
            ydy = dy;
            boolean shouldRefresh = (linearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0)
                    && (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) && offset > 30;
            if (shouldRefresh) {
                //swipeRefreshLayout.setRefreshing(true);
                //Refresh to load data here.
                return;
            }
            boolean shouldPullUpRefresh = linearLayoutManager.findLastCompletelyVisibleItemPosition() == linearLayoutManager.getChildCount() - 1
                    && recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING && offset < -30;
            if (shouldPullUpRefresh) {
                //swipeRefreshLayout.setRefreshing(true);
                //refresh to load data here.
                return;
            }
            swipeRefreshLayout.setRefreshing(false);
        }
    });
recyclerview.addOnScrollListener(新的recyclerview.OnScrollListener(){
int-ydy=0;
@凌驾
CrollStateChanged上的公共void(@NonNull RecyclerView RecyclerView,int newState){
super.onScrollStateChanged(recyclerView、newState);
}
@凌驾
已克隆的公共void(@NonNull RecyclerView RecyclerView,int-dx,int-dy){
super.onScrolled(recyclerView、dx、dy);
int offset=dy-ydy;
ydy=dy;
布尔值shouldRefresh=(linearLayoutManager.findFirstCompletelyVisibleItemPosition()==0)
&&(recyclerView.getScrollState()==recyclerView.SCROLL\u状态\u拖动)&偏移量>30;
如果(应刷新){
//swipeRefreshLayout.setRefreshing(true);
//刷新以在此处加载数据。
返回;
}
布尔值shouldPullUpRefresh=linearLayoutManager.findLastCompletelyVisibleItemPosition()==linearLayoutManager.getChildCount()-1
&&recyclerView.getScrollState()==recyclerView.SCROLL\u STATE\u拖动和偏移<-30;
如果(应使用pulluprefresh){
//swipeRefreshLayout.setRefreshing(true);
//刷新以在此处加载数据。
返回;
}
swipeRefreshLayout.setRefreshing(false);
}
});

和@AtulOHolic我已经实现了recyclerview的onScrollListener()但不知道如何基于Scroll获取数据这是一个双向过程。首先,您的web服务应提供页面数据。因此,假设您的应用程序加载时调用了第1页。现在,根据上面的github链接实现,您可以看到文本加载更多。这是您需要再次调用web服务的地方,但请询问下一页第2页在哪里这种情况如此类推。获取一个集合中的所有记录。获取另一个集合,该集合将填充部分记录,比如说10条记录。现在,当你到达底部时,填充集合中的下10条记录并通知列表。但是当我滚动RecycelView addonscrolllistener时,这只是为了在之后从web服务加载下一条记录r滚动时到达终点。不要在底部显示进度条。您需要稍微更改适配器类和asynctask以获得此功能。我正面临这样的问题。当在recycler视图中实现搜索并假设只有1项时,将发生额外的api调用。我尝试过面对小问题,p
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ProgressBar
        android:id="@+id/progressBar1"
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:layout_height="wrap_content" />

</LinearLayout>
public class BackGroundTask extends AsyncTask<Object, Void, String> {

    private ProgressDialog pDialog;
    public OnTaskCompleted listener = null;//Call back interface


    Context context;
    int pageNumber;

    public BackGroundTask(Context context1, OnTaskCompleted listener1, int pageNumber) {
        context = context1;
        listener = listener1;   //Assigning call back interface  through constructor
        this.pageNumber = pageNumber;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    @Override
    protected String doInBackground(Object... params) {

        //My Background tasks are written here

        synchronized (this) {

            String url = Const.URL_WALLPAPERS_HD + pageNumber;
            String jsonStr = ServiceHandler.makeServiceCall(url, ServiceHandler.GET);
            Log.i("Url: ", "> " + url);

            Log.i("Response: ", "> " + jsonStr);
            return jsonStr;
        }

    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        listener.onTaskCompleted(result);

    }

}
public class ServiceHandler {

    static String response = null;
    public final static int GET = 1;
    public final static int POST = 2;


    public ServiceHandler() {

    }

    /**
     * Making service call
     *
     * @url - url to make request
     * @method - http request method
     */
    public static String makeServiceCall(String url, int method) {
        return makeServiceCall(url, method, null);
    }

    /**
     * Making service call
     *
     * @url - url to make request
     * @method - http request method
     * @params - http request params
     */
    public static String makeServiceCall(String url, int method,
                                  List<NameValuePair> params) {
        try {
            // http client
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpEntity httpEntity = null;
            HttpResponse httpResponse = null;

            // Checking http request method type
            if (method == POST) {
                HttpPost httpPost = new HttpPost(url);
                // adding post params
                if (params != null) {
                    httpPost.setEntity(new UrlEncodedFormEntity(params));
                }
                Log.e("Selltis Request URL", url);
                httpResponse = httpClient.execute(httpPost);

            } else if (method == GET) {
                // appending params to url
                if (params != null) {
                    String paramString = URLEncodedUtils
                            .format(params, "utf-8");
                    url += paramString;

                    Log.i("Request URL", url);
                }
                HttpGet httpGet = new HttpGet(url);

                httpResponse = httpClient.execute(httpGet);

            }
            httpEntity = httpResponse.getEntity();
            response = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return "Fail";
        } catch (ClientProtocolException e) {
            e.printStackTrace();
            return "Fail";
        } catch (IOException e) {
            e.printStackTrace();
            return "Fail";
        }

        return response;

    }


}
public interface OnLoadMoreListener {
     void onLoadMore();
}
public interface OnTaskCompleted{

    void onTaskCompleted(String response);
}
  recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);

                int total = linearLayoutManager.getItemCount();
                int firstVisibleItemCount = linearLayoutManager.findFirstVisibleItemPosition();
                int lastVisibleItemCount = linearLayoutManager.findLastVisibleItemPosition();

                //to avoid multiple calls to loadMore() method
                //maintain a boolean value (isLoading). if loadMore() task started set to true and completes set to false
                if (!isLoading) { 
                    if (total > 0) 
                        if ((total - 1) == lastVisibleItemCount){
                           loadMore();//your HTTP stuff goes in this method 
                           loadingProgress.setVisibility(View.VISIBLE);
                        }else
                           loadingProgress.setVisibility(View.GONE);
                }
            }

            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);

            }

    });
recyclerViewChat.addOnScrollListener(object : RecyclerView.OnScrollListener() {

            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    Log.d("scroll", "idle")
                } else if (newState == RecyclerView.SCROLL_STATE_SETTLING) {
                    Log.d("scroll", "settling")
                } else if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
                    Log.d("scroll", "dragging")
                }
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                Log.d("scroll", "scrolling")
            }
        })
recyclerview.addOnScrollListener(new RecyclerView.OnScrollListener() {
        int ydy = 0;
        @Override
        public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
        }

        @Override
        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            int offset = dy - ydy;
            ydy = dy;
            boolean shouldRefresh = (linearLayoutManager.findFirstCompletelyVisibleItemPosition() == 0)
                    && (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) && offset > 30;
            if (shouldRefresh) {
                //swipeRefreshLayout.setRefreshing(true);
                //Refresh to load data here.
                return;
            }
            boolean shouldPullUpRefresh = linearLayoutManager.findLastCompletelyVisibleItemPosition() == linearLayoutManager.getChildCount() - 1
                    && recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING && offset < -30;
            if (shouldPullUpRefresh) {
                //swipeRefreshLayout.setRefreshing(true);
                //refresh to load data here.
                return;
            }
            swipeRefreshLayout.setRefreshing(false);
        }
    });