1

我試圖實現pull刷新和recyclerview無盡滾動。雖然無盡滾動效果很好,但如果我導航到recylerview的頂部並觸發拉動刷新,雖然列表會刷新,但會導致禁用無限滾動。我張貼的代碼,任何幫助讚賞RecyclerView:拉刷新和EndlessScroll實施也懶加載

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); 

回答

0

這是我的解決方案:

@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(); 
    }