我正在尝试在recyclerview上实现pull to refresh和无限滚动。虽然无限滚动效果非常好,但如果我导航到recylerview的顶部并触发pull to refresh,则会刷新列表,但会导致无限滚动禁用。我发布的代码,任何帮助赞赏
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 :(得分: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();
}