【问题标题】:RecyclerView : Pull to refresh and EndlessScroll implementation AKA Lazy loadingRecyclerView : 拉动刷新和 EndlessScroll 实现 AKA 延迟加载
【发布时间】:2016-02-26 12:38:18
【问题描述】:

我正在尝试在 recyclerview 上实现拉动刷新和无限滚动。虽然无限滚动效果很好,但如果我导航到 recylerview 的顶部并触发拉动刷新,列表会刷新,但它会导致无限滚动被禁用。我正在发布代码,任何帮助表示赞赏

Layout XML :

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                    xmlns:tools="http://schemas.android.com/tools"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    xmlns:app="http://schemas.android.com/apk/res-auto"
                    android:orientation="vertical">

        <android.support.v4.widget.SwipeRefreshLayout
            android:id="@+id/swipeRefresh"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/recyclerView_confirmedListRowtoday"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:listitem="@layout/adapter_item_confirmed"
                />
        </android.support.v4.widget.SwipeRefreshLayout>

        <com.victor.loading.rotate.RotateLoading
            android:id="@+id/rotateloading"
            app:loading_color="@color/primary_light"
            app:loading_width="5dp"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_centerInParent="true"
            />

        <TextView
            android:id="@+id/emptyTextView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:text="No Appointments"
            android:textColor="@color/black_semi_transparent"
            android:textSize="20sp"
            android:visibility="gone"
            tools:visibility="visible"/>


    </RelativeLayout>

ScrollListener implementation :

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

RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener() {

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

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

            if (loading) {
                if (totalItemCount > previousTotal) {
                    loading = false;
                    previousTotal = totalItemCount;
                }
            }
            if (!loading && (totalItemCount - visibleItemCount)
                    <= (firstVisibleItem + visibleThreshold)) {
                pageNumber++;
                callAppointmentApi();
                loading = true;
            }
        }
    };

RecyclerView code :



mRecyclerView.setHasFixedSize(true);
    llm = new LinearLayoutManager(getActivity());
    mRecyclerView.setLayoutManager(llm);
    adapter = new ConfirmedRecyclerAdapter(getActivity(), appointmentModelList);
    mRecyclerView.setAdapter(adapter);

     // Setup refresh listener which triggers new data loading
    swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    // Your code to refresh the list here.
                    // Make sure you call swipeContainer.setRefreshing(false)
                    // once the network request has completed successfully.
                    appointmentModelList.clear();
                    pageNumber = 0;
                    callAppointmentApi();
                    mRecyclerView.addOnScrollListener( onScrollListener );
                }
            });
    mRecyclerView.addOnScrollListener( onScrollListener );

【问题讨论】:

    标签: android-recyclerview lazy-loading swiperefreshlayout endlessscroll


    【解决方案1】:

    这是我的解决方案:

     @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            View rootView = inflater.inflate(R.layout.fragment_confirmed, container, false);
            ButterKnife.bind(this, rootView);
            appointmentModelList = new ArrayList<>();
            preferenceManager = new PreferenceManager(getActivity());
            setRecyclerView();
            appointmentsInterface = ParseApiGenerator.createService(AppointmentsApi.class);
            callAppointmentApi(appointmentModelList.size());
            return rootView;
        }
    
        private int mFirstVisibleItem, mVisibleItemCount, mTotalItemCount;
        private boolean mLoading;
        private int mPreviousTotal = 0;
        RecyclerView.OnScrollListener mRecylerViewScrollListener = new RecyclerView.OnScrollListener() {
    
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
    
                mVisibleItemCount = mRecyclerView.getChildCount();
                mTotalItemCount = llm.getItemCount();
                mFirstVisibleItem = llm.findFirstVisibleItemPosition();
    
                if (mLoading) {
                    if (mTotalItemCount > mPreviousTotal) {
                        mLoading = false;
                        mPreviousTotal = mTotalItemCount;
                    }
                }
                if (!mLoading && (mTotalItemCount - mVisibleItemCount) <= (mFirstVisibleItem)) {
                    callAppointmentApi(appointmentModelList.size());
                    mLoading = true;
                }
            }
        };
    
        private void setRecyclerView() {
    
            mRecyclerView.setHasFixedSize(true);
            llm = new LinearLayoutManager(getActivity());
            mRecyclerView.setLayoutManager(llm);
            adapter = new ConfirmedRecyclerAdapter(getActivity(), appointmentModelList);
            mRecyclerView.setAdapter(adapter);
    
            // Setup refresh listener which triggers new data loading
            swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                @Override
                public void onRefresh() {
                    // Your code to refresh the list here.
                    // Make sure you call swipeContainer.setRefreshing(false)
                    // once the network request has completed successfully.
                    appointmentModelList.clear();
                    mPreviousTotal = 0;
                    mLoading = false;
                    callAppointmentApi(appointmentModelList.size());
                }
            });
            mRecyclerView.addOnScrollListener( mRecylerViewScrollListener );
            checkAdapterIsEmpty();
            // Configure the refreshing colors
            swipeRefresh.setColorSchemeResources(android.R.color.holo_blue_bright,
                    android.R.color.holo_green_light,
                    android.R.color.holo_orange_light,
                    android.R.color.holo_red_light);
            rotateloading.start();
            emptyTextView.setVisibility(View.GONE);
            mRecyclerView.addOnItemTouchListener(new RecyclerViewItemClickListener(getActivity(), new RecyclerViewItemClickListener.OnItemClickListener() {
                @Override
                public void onItemClick(View view, int position) {
    
                    Intent i = new Intent(getActivity(), AppointmentOverviewActivity.class);
                    AppointmentModel appointmentModel = appointmentModelList.get(position);
                    formatter = new DecimalFormat("#.##");
                    if (appointmentModel.getDistance() != null) {
    
    
                        if (formatter.format(Double.parseDouble(appointmentModel.getDistance())).equals("00.00")) {
                            distanceStr = "";
                        } else if (Double.parseDouble(appointmentModel.getDistance()) > 1) {
                            //  spDistance.setText(formatter.format(appointmentModel.getDistance())+"miles");
                            distanceStr = "" + formatter.format(Double.parseDouble(appointmentModel.getDistance())) + " miles";
                        } else {
                            distanceStr = "" + formatter.format(Double.parseDouble(appointmentModel.getDistance())) + " mile";
                        }
                    }
                    else
                    {
                        distanceStr="";
                    }
                    // Parcelable input
                    i.putExtra("distance", distanceStr);
                    i.putExtra("data_appointment", appointmentModel);
                    getActivity().startActivityForResult(i, Constants.APPOINTMENT_REQUEST);
                }
            }));
        }
    
        private void checkAdapterIsEmpty() {
            if (adapter != null & emptyTextView != null)
                if (adapter.getItemCount() == 0) {
                    emptyTextView.setVisibility(View.VISIBLE);
                } else {
                    emptyTextView.setVisibility(View.GONE);
                }
        }
    
        public void callAppointmentApi( int pageNumber ) {
    
            if( pageNumber == 0 ) {
                appointmentModelList.clear();
            }
    
            JSONObject jsonObject = new JSONObject();
            try {
                JSONObject customerId = new JSONObject();
                customerId.put("__type", "Pointer");
                customerId.put("className", "Customer");
                customerId.put("objectId", preferenceManager.getCustomerObjectId()); // "YXH1dBgj1i"
                jsonObject.put("customerId", customerId);
                jsonObject.put("state", "cancelled");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            Logger.d("Page is " + pageNumber );
    
            appointmentsInterface.getAppointments(
                    jsonObject.toString(),
                    "serviceProviderId,customerId,rating",
                    pageNumber, 10,
                    preferenceManager.getUserSessionToken(),
                    new Callback<Response>() {
                @Override
                public void success(Response response, Response response2) {
    
                    try {
                        JSONObject object = new JSONObject(new String(((TypedByteArray) response.getBody()).getBytes()));
                        Gson gson = new Gson();
                        AppointmentResultModel results = gson.fromJson(object.toString(), AppointmentResultModel.class);
                        if( results != null && results.getResult() != null ) {
    
                            appointmentModelList.addAll(results.getResult());
                            checkAdapterIsEmpty();
                            dismissProgressDisplay();
                        }
                        else {
                            dismissProgressDisplay();
                        }
                        adapter.notifyDataSetChanged();
                    } catch (JSONException e) {
                        e.printStackTrace();
                        dismissProgressDisplay();
                    }
    
                }
                @Override
                public void failure(RetrofitError error) {
                    Logger.d("CancelledData RespFail", error.toString());
                    dismissProgressDisplay();
                }
            });
        }
    
        private void dismissProgressDisplay() {
            if (swipeRefresh != null)
                swipeRefresh.setRefreshing(false);
            if (rotateloading != null)
                rotateloading.stop();
            CommonUtils.dismissProgressDialog();
        }
    

    【讨论】:

      猜你喜欢
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-11
      相关资源
      最近更新 更多