使用分页库时,观察者将列表大小显示为零
When using Paging Library, observer showing list size as zero
我正在尝试使用较新版本的分页库。我正在使用截击从网络中获取我的数据。每当我从网络中获取数据时,都会获取数据,但是当调用转到观察者时,显示的列表大小为零。我不确定我做错了什么。
我是 android 的新手,所以对分页了解不多。自从我尝试以来已经有几天了,但仍然无法弄清楚。
我的gradle如下
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.athansys.mypagingapplication"
minSdkVersion 22
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.volley:volley:1.1.0'
implementation 'com.google.code.gson:gson:2.8.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "android.arch.paging:runtime:1.0.1"
implementation "android.arch.lifecycle:runtime:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
}
我的 MainActivity 看起来像:
package com.example.athansys.mypagingapplication;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private MyPatientAdapter mPatientAdapter;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FilterModel viewModel = ViewModelProviders.of(this).get(FilterModel.class);
viewModel.getData(this).observe(this, new Observer<PagedList<FilterPatientList>>() {
@Override
public void onChanged(@Nullable PagedList<FilterPatientList> results) {
mPatientAdapter.submitList(results);
//mPatientAdapter.setList(results);
mPatientAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mPatientAdapter);
}
});
}
private void setAdapter() {
mRecyclerView = findViewById(R.id.my_patient_recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
mPatientAdapter = new MyPatientAdapter();
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mPatientAdapter);
}
}
FilterModel class如下:
package com.example.athansys.mypagingapplication;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import android.arch.paging.LivePagedListBuilder;
import android.arch.paging.PagedList;
import android.content.Context;
import android.util.Log;
public class FilterModel extends ViewModel {
private LiveData<PagedList<FilterPatientList>> listLiveData;
LiveData<PagedList<FilterPatientList>> getData(Context context) {
if (listLiveData == null) {
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder()).setEnablePlaceholders(false)
.setPrefetchDistance(5)
.setPageSize(1).build();
listLiveData = new LivePagedListBuilder<>
(new MyPatientPagedListProvider(context)
.getAll()
, pagedListConfig).
build();
}
return listLiveData;
}
}
MyProvider class 是:
package com.example.athansys.mypagingapplication;
import android.arch.paging.DataSource;
import android.arch.paging.LivePagedListProvider;
import android.content.Context;
import android.util.Log;
import java.util.List;
public class MyPatientPagedListProvider {
Context mBaseContext;
public MyPatientPagedListProvider(Context context) {
mBaseContext = context;
dataClass.getContextInstance(context);
}
private static final String TAG = MyPatientPagedListProvider.class.getName();
MyPatientData dataClass = new MyPatientData() {
@Override
public List<FilterPatientList> convertToItems(List<FilterPatientList> result, int size) {
return result;
}
};
public LivePagedListProvider<Integer, FilterPatientList> getAll() {
return new LivePagedListProvider<Integer, FilterPatientList>() {
@Override
protected DataSource<Integer, FilterPatientList> createDataSource() {
return dataClass;
}
};
}
}
MyDataSource如下:
package com.example.athansys.mypagingapplication;
import android.arch.paging.TiledDataSource;
import android.content.Context;
import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class MyPatientData extends TiledDataSource<FilterPatientList> {
private Context mContext;
private List<FilterPatientList> patientList;
@Override
public int countItems() {
return 10;
}
@Override
public List<FilterPatientList> loadRange(int startPosition, int count) {
String url = "My URl";
return postStringRequestForMyPatient(url);
}
public List<FilterPatientList> postStringRequestForMyPatient(String url) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
String data = jsonObject.getString("patientsfordoctor");
mPatientsForDoctor = new Gson().fromJson(data, PatientsForDoctor.class);
mPatientList = new ArrayList<>();
mPatientList.addAll(mPatientsForDoctor.getPatientList());
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return super.getParams();
}
@Override
public String getBodyContentType() {
return super.getBodyContentType();
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return new HashMap<>();
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(mContext).add(stringRequest);
}
void getContextInstance(Context context) {
mContext = context;
}
public abstract List<FilterPatientList> convertToItems(List<FilterPatientList> result, int size);
}
我的适配器class
package com.example.athansys.mypagingapplication;
import android.arch.paging.PagedListAdapter;
import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MyPatientAdapter extends PagedListAdapter<FilterPatientList, MyPatientAdapter.PatientViewHolder> {
protected MyPatientAdapter() {
super(FilterPatientList.DIFF_CALLBACK);
}
@NonNull
@Override
public PatientViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull PatientViewHolder holder, int position) {
}
class PatientViewHolder extends RecyclerView.ViewHolder {
TextView patientName, patientPhoneNumber, genderAge;
PatientViewHolder(View itemView) {
super(itemView);
}
}
}
我的 POJO(型号 CLASSES 如下)
FilterPatientListclass:
package com.example.athansys.mypagingapplication;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.util.DiffUtil;
import com.google.gson.annotations.SerializedName;
public class FilterPatientList implements Parcelable {
private long patientId;
private Patient patientDetails;
protected FilterPatientList(Parcel in) {
patientId = in.readLong();
patientDetails = in.readParcelable(Patient.class.getClassLoader());
}
public static final Creator<FilterPatientList> CREATOR = new Creator<FilterPatientList>() {
@Override
public FilterPatientList createFromParcel(Parcel in) {
return new FilterPatientList(in);
}
@Override
public FilterPatientList[] newArray(int size) {
return new FilterPatientList[size];
}
};
public long getPatientId() {
return patientId;
}
public void setPatientId(long patientId) {
this.patientId = patientId;
}
public Patient getPatientDetails() {
return patientDetails;
}
public void setPatientDetails(Patient patientDetails) {
this.patientDetails = patientDetails;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(patientId);
dest.writeParcelable(patientDetails, flags);
}
public static final DiffUtil.ItemCallback<FilterPatientList> DIFF_CALLBACK = new DiffUtil.ItemCallback<FilterPatientList>() {
@Override
public boolean areItemsTheSame(FilterPatientList oldItem, FilterPatientList newItem) {
return false;
}
@Override
public boolean areContentsTheSame(FilterPatientList oldItem, FilterPatientList newItem) {
return false;
}
};
}
患者CLASS:
package com.example.athansys.mypagingapplication;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.gson.annotations.SerializedName;
public class Patient implements Parcelable{
private long localPatientId;
private long apptDoctorId;
private long patientId;
private boolean isLocalPatient;
private String firstName;
private String lastName;
private String phoneNumber;
private String email;
private String dob;
private int age;
private int height;
private int weight;
private String patientSex;
private String patientSystemRegistrationDate;
private int bloodGroup;
protected Patient(Parcel in) {
localPatientId = in.readLong();
apptDoctorId = in.readLong();
patientId = in.readLong();
isLocalPatient = in.readByte() != 0;
firstName = in.readString();
lastName = in.readString();
phoneNumber = in.readString();
email = in.readString();
dob = in.readString();
age = in.readInt();
height = in.readInt();
weight = in.readInt();
patientSex = in.readString();
patientSystemRegistrationDate = in.readString();
bloodGroup = in.readInt();
}
public static final Creator<Patient> CREATOR = new Creator<Patient>() {
@Override
public Patient createFromParcel(Parcel in) {
return new Patient(in);
}
@Override
public Patient[] newArray(int size) {
return new Patient[size];
}
};
public long getLocalPatientId() {
return localPatientId;
}
public void setLocalPatientId(long localPatientId) {
this.localPatientId = localPatientId;
}
public long getApptDoctorId() {
return apptDoctorId;
}
public void setApptDoctorId(long apptDoctorId) {
this.apptDoctorId = apptDoctorId;
}
public long getPatientId() {
return patientId;
}
public void setPatientId(long patientId) {
this.patientId = patientId;
}
public boolean isLocalPatient() {
return isLocalPatient;
}
public void setLocalPatient(boolean localPatient) {
isLocalPatient = localPatient;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getPatientSex() {
return patientSex;
}
public void setPatientSex(String patientSex) {
this.patientSex = patientSex;
}
public String getPatientSystemRegistrationDate() {
return patientSystemRegistrationDate;
}
public void setPatientSystemRegistrationDate(String patientSystemRegistrationDate) {
this.patientSystemRegistrationDate = patientSystemRegistrationDate;
}
public int getBloodGroup() {
return bloodGroup;
}
public void setBloodGroup(int bloodGroup) {
this.bloodGroup = bloodGroup;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(localPatientId);
dest.writeLong(apptDoctorId);
dest.writeLong(patientId);
dest.writeByte((byte) (isLocalPatient ? 1 : 0));
dest.writeString(firstName);
dest.writeString(lastName);
dest.writeString(phoneNumber);
dest.writeString(email);
dest.writeString(dob);
dest.writeInt(age);
dest.writeInt(height);
dest.writeInt(weight);
dest.writeString(patientSex);
dest.writeString(patientSystemRegistrationDate);
dest.writeInt(bloodGroup);
}
}
当我在数据源 class(MyPatientData) 中从网络接收数据时,调用会自动转到主 activity 中的观察者。此处显示的列表大小为零,而从网络获取的列表大小为 10 个项目。
你能帮帮我吗?我真的被困了好几天不知道下一步该怎么做。
非常感谢。 :)
这是分页的简单解决方案。
第一次 private void jsonRequestList(int pageCount) {
将用 pageCount=1
调用,下一次用 2,3,4...
递增
内部 private void jsonRequestList(int pageCount) {
方法 (JSON REQUEST) 第一次 if (!isScrollCalled) {
将被调用,下一次 else
块将被调用。
Activity/Fragment :
private boolean loading = false;
private boolean isScrollCalled;
int isLastPage = 10;
int pageCount = 1;
//Paigination
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
int lastvisibleitemposition = linearLayoutManager.findLastVisibleItemPosition();
if (lastvisibleitemposition == adapter.getItemCount() - 1) {
if (!loading && pageCount != isLastPage) {
loading = true;
jsonRequestList(++pageCount);
isScrollCalled = Boolean.TRUE;
}
}
}
});
private void jsonRequestList(int pageCount) {
//Json Request
if (!isScrollCalled) {
adapter = new FlowerListAdapter(FlowerListActivity.this, list);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
// Log.e("LIST_SIZE", "" + list.size());
} else {
adapter.updateList(list);
//Log.e("LIST_SIZE", "" + list.size());
}
loading = false;
}
回收器适配器:
ArrayList<YourModelClass> list;
Context context;
//Pagination
public void updateList(ArrayList<YourModelClass> list) {
this.list.addAll(list);
this.notifyDataSetChanged();
}
您可以在 LivePagedListBuilder 中实现 BoundaryCallback。它包含方法 onZeroItemsLoaded。
listLiveData = new LivePagedListBuilder<>
(new MyPatientPagedListProvider(context)
.getAll()
, pagedListConfig)
.setBoundaryCallback(new PagedList.BoundaryCallback() {
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
// do smth here. For example, post boolean value to MutableLiveData to notify activity //that result is empty
}
})
.build();
要获取插入项目的大小或 RecyclerView 的大小,我们需要向我们的 RecyclerView 注册一个 AdapterDataObserver
。
1) 创建一个 AdapterDataObserver 并覆盖你想要的函数。
public class SearchListAdapterDataObserver extends RecyclerView.AdapterDataObserver {
private RecyclerView mRecyclerView;
private ChangeListener mChangeListener;
public SearchListAdapterDataObserver(RecyclerView view, ChangeListener changeListener){
this.mRecyclerView = view;
this.mChangeListener = changeListener;
}
@Override
public void onChanged() {
super.onChanged();
sendItemCount();
}
private void sendItemCount() {
if(mRecyclerView.getAdapter() != null) {
mChangeListener.onChanged(getSize());
}
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
sendItemCount();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
super.onItemRangeChanged(positionStart, itemCount);
sendItemCount();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
super.onItemRangeRemoved(positionStart, itemCount);
sendItemCount();
}
public int getSize() {
if(mRecyclerView.getAdapter() != null) {
return mRecyclerView.getAdapter().getItemCount();
}
return 0;
}
public interface ChangeListener {
void onChanged(int size);
}
}
2) 将其注册到您的适配器并收听更改。
if(mViewModel.getSearchPaginatedAdapter() != null){
mViewModel.getSearchPaginatedAdapter().registerAdapterDataObserver
(new SearchListAdapterDataObserver(mRecyclerView, new SearchListAdapterDataObserver.ChangeListener() {
@Override
public void onChanged(int size) {
onListChanges(size);
}
}));
}
修改@Mike Makhovyk,这是我最终想出的办法
在您的 ViewModel 上
创建可变布尔值
private MutableLiveData<Boolean> emptyListMutableLiveData = new MutableLiveData<>();
listLiveData = new LivePagedListBuilder<>
(new MyPatientPagedListProvider(context)
.getAll()
, pagedListConfig)
.setBoundaryCallback(new PagedList.BoundaryCallback() {
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
emptyListMutableLiveData.setValue(true)
}
@Override
public void onItemAtFrontLoaded(@NonNull Complaint itemAtFront) {
super.onItemAtFrontLoaded(itemAtFront);
emptyListMutableLiveData.setValue(false);
}
})
.build();
创建一个方法,return te livedata
public LiveData<Boolean> isEmptyList() {
return emptyListMutableLiveData;
}
在您的 fragment/activity 上,您可以观察布尔结果,然后更新您的 UI
我正在尝试使用较新版本的分页库。我正在使用截击从网络中获取我的数据。每当我从网络中获取数据时,都会获取数据,但是当调用转到观察者时,显示的列表大小为零。我不确定我做错了什么。
我是 android 的新手,所以对分页了解不多。自从我尝试以来已经有几天了,但仍然无法弄清楚。
我的gradle如下
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.athansys.mypagingapplication"
minSdkVersion 22
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.android.volley:volley:1.1.0'
implementation 'com.google.code.gson:gson:2.8.1'
implementation 'com.android.support:design:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "android.arch.paging:runtime:1.0.1"
implementation "android.arch.lifecycle:runtime:1.1.1"
implementation "android.arch.lifecycle:extensions:1.1.1"
annotationProcessor "android.arch.lifecycle:compiler:1.1.1"
}
我的 MainActivity 看起来像:
package com.example.athansys.mypagingapplication;
import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.arch.paging.PagedList;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public class MainActivity extends AppCompatActivity {
private MyPatientAdapter mPatientAdapter;
private RecyclerView mRecyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FilterModel viewModel = ViewModelProviders.of(this).get(FilterModel.class);
viewModel.getData(this).observe(this, new Observer<PagedList<FilterPatientList>>() {
@Override
public void onChanged(@Nullable PagedList<FilterPatientList> results) {
mPatientAdapter.submitList(results);
//mPatientAdapter.setList(results);
mPatientAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mPatientAdapter);
}
});
}
private void setAdapter() {
mRecyclerView = findViewById(R.id.my_patient_recycler_view);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
mPatientAdapter = new MyPatientAdapter();
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mPatientAdapter);
}
}
FilterModel class如下:
package com.example.athansys.mypagingapplication;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.ViewModel;
import android.arch.paging.LivePagedListBuilder;
import android.arch.paging.PagedList;
import android.content.Context;
import android.util.Log;
public class FilterModel extends ViewModel {
private LiveData<PagedList<FilterPatientList>> listLiveData;
LiveData<PagedList<FilterPatientList>> getData(Context context) {
if (listLiveData == null) {
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder()).setEnablePlaceholders(false)
.setPrefetchDistance(5)
.setPageSize(1).build();
listLiveData = new LivePagedListBuilder<>
(new MyPatientPagedListProvider(context)
.getAll()
, pagedListConfig).
build();
}
return listLiveData;
}
}
MyProvider class 是:
package com.example.athansys.mypagingapplication;
import android.arch.paging.DataSource;
import android.arch.paging.LivePagedListProvider;
import android.content.Context;
import android.util.Log;
import java.util.List;
public class MyPatientPagedListProvider {
Context mBaseContext;
public MyPatientPagedListProvider(Context context) {
mBaseContext = context;
dataClass.getContextInstance(context);
}
private static final String TAG = MyPatientPagedListProvider.class.getName();
MyPatientData dataClass = new MyPatientData() {
@Override
public List<FilterPatientList> convertToItems(List<FilterPatientList> result, int size) {
return result;
}
};
public LivePagedListProvider<Integer, FilterPatientList> getAll() {
return new LivePagedListProvider<Integer, FilterPatientList>() {
@Override
protected DataSource<Integer, FilterPatientList> createDataSource() {
return dataClass;
}
};
}
}
MyDataSource如下:
package com.example.athansys.mypagingapplication;
import android.arch.paging.TiledDataSource;
import android.content.Context;
import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class MyPatientData extends TiledDataSource<FilterPatientList> {
private Context mContext;
private List<FilterPatientList> patientList;
@Override
public int countItems() {
return 10;
}
@Override
public List<FilterPatientList> loadRange(int startPosition, int count) {
String url = "My URl";
return postStringRequestForMyPatient(url);
}
public List<FilterPatientList> postStringRequestForMyPatient(String url) {
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(response);
String data = jsonObject.getString("patientsfordoctor");
mPatientsForDoctor = new Gson().fromJson(data, PatientsForDoctor.class);
mPatientList = new ArrayList<>();
mPatientList.addAll(mPatientsForDoctor.getPatientList());
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map<String, String> getParams() throws AuthFailureError {
return super.getParams();
}
@Override
public String getBodyContentType() {
return super.getBodyContentType();
}
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
return new HashMap<>();
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(mContext).add(stringRequest);
}
void getContextInstance(Context context) {
mContext = context;
}
public abstract List<FilterPatientList> convertToItems(List<FilterPatientList> result, int size);
}
我的适配器class
package com.example.athansys.mypagingapplication;
import android.arch.paging.PagedListAdapter;
import android.support.annotation.NonNull;
import android.support.v7.util.DiffUtil;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class MyPatientAdapter extends PagedListAdapter<FilterPatientList, MyPatientAdapter.PatientViewHolder> {
protected MyPatientAdapter() {
super(FilterPatientList.DIFF_CALLBACK);
}
@NonNull
@Override
public PatientViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(@NonNull PatientViewHolder holder, int position) {
}
class PatientViewHolder extends RecyclerView.ViewHolder {
TextView patientName, patientPhoneNumber, genderAge;
PatientViewHolder(View itemView) {
super(itemView);
}
}
}
我的 POJO(型号 CLASSES 如下)
FilterPatientListclass:
package com.example.athansys.mypagingapplication;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v7.util.DiffUtil;
import com.google.gson.annotations.SerializedName;
public class FilterPatientList implements Parcelable {
private long patientId;
private Patient patientDetails;
protected FilterPatientList(Parcel in) {
patientId = in.readLong();
patientDetails = in.readParcelable(Patient.class.getClassLoader());
}
public static final Creator<FilterPatientList> CREATOR = new Creator<FilterPatientList>() {
@Override
public FilterPatientList createFromParcel(Parcel in) {
return new FilterPatientList(in);
}
@Override
public FilterPatientList[] newArray(int size) {
return new FilterPatientList[size];
}
};
public long getPatientId() {
return patientId;
}
public void setPatientId(long patientId) {
this.patientId = patientId;
}
public Patient getPatientDetails() {
return patientDetails;
}
public void setPatientDetails(Patient patientDetails) {
this.patientDetails = patientDetails;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(patientId);
dest.writeParcelable(patientDetails, flags);
}
public static final DiffUtil.ItemCallback<FilterPatientList> DIFF_CALLBACK = new DiffUtil.ItemCallback<FilterPatientList>() {
@Override
public boolean areItemsTheSame(FilterPatientList oldItem, FilterPatientList newItem) {
return false;
}
@Override
public boolean areContentsTheSame(FilterPatientList oldItem, FilterPatientList newItem) {
return false;
}
};
}
患者CLASS:
package com.example.athansys.mypagingapplication;
import android.os.Parcel;
import android.os.Parcelable;
import com.google.gson.annotations.SerializedName;
public class Patient implements Parcelable{
private long localPatientId;
private long apptDoctorId;
private long patientId;
private boolean isLocalPatient;
private String firstName;
private String lastName;
private String phoneNumber;
private String email;
private String dob;
private int age;
private int height;
private int weight;
private String patientSex;
private String patientSystemRegistrationDate;
private int bloodGroup;
protected Patient(Parcel in) {
localPatientId = in.readLong();
apptDoctorId = in.readLong();
patientId = in.readLong();
isLocalPatient = in.readByte() != 0;
firstName = in.readString();
lastName = in.readString();
phoneNumber = in.readString();
email = in.readString();
dob = in.readString();
age = in.readInt();
height = in.readInt();
weight = in.readInt();
patientSex = in.readString();
patientSystemRegistrationDate = in.readString();
bloodGroup = in.readInt();
}
public static final Creator<Patient> CREATOR = new Creator<Patient>() {
@Override
public Patient createFromParcel(Parcel in) {
return new Patient(in);
}
@Override
public Patient[] newArray(int size) {
return new Patient[size];
}
};
public long getLocalPatientId() {
return localPatientId;
}
public void setLocalPatientId(long localPatientId) {
this.localPatientId = localPatientId;
}
public long getApptDoctorId() {
return apptDoctorId;
}
public void setApptDoctorId(long apptDoctorId) {
this.apptDoctorId = apptDoctorId;
}
public long getPatientId() {
return patientId;
}
public void setPatientId(long patientId) {
this.patientId = patientId;
}
public boolean isLocalPatient() {
return isLocalPatient;
}
public void setLocalPatient(boolean localPatient) {
isLocalPatient = localPatient;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public String getPatientSex() {
return patientSex;
}
public void setPatientSex(String patientSex) {
this.patientSex = patientSex;
}
public String getPatientSystemRegistrationDate() {
return patientSystemRegistrationDate;
}
public void setPatientSystemRegistrationDate(String patientSystemRegistrationDate) {
this.patientSystemRegistrationDate = patientSystemRegistrationDate;
}
public int getBloodGroup() {
return bloodGroup;
}
public void setBloodGroup(int bloodGroup) {
this.bloodGroup = bloodGroup;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(localPatientId);
dest.writeLong(apptDoctorId);
dest.writeLong(patientId);
dest.writeByte((byte) (isLocalPatient ? 1 : 0));
dest.writeString(firstName);
dest.writeString(lastName);
dest.writeString(phoneNumber);
dest.writeString(email);
dest.writeString(dob);
dest.writeInt(age);
dest.writeInt(height);
dest.writeInt(weight);
dest.writeString(patientSex);
dest.writeString(patientSystemRegistrationDate);
dest.writeInt(bloodGroup);
}
}
当我在数据源 class(MyPatientData) 中从网络接收数据时,调用会自动转到主 activity 中的观察者。此处显示的列表大小为零,而从网络获取的列表大小为 10 个项目。
你能帮帮我吗?我真的被困了好几天不知道下一步该怎么做。 非常感谢。 :)
这是分页的简单解决方案。
第一次 private void jsonRequestList(int pageCount) {
将用 pageCount=1
调用,下一次用 2,3,4...
内部 private void jsonRequestList(int pageCount) {
方法 (JSON REQUEST) 第一次 if (!isScrollCalled) {
将被调用,下一次 else
块将被调用。
Activity/Fragment :
private boolean loading = false;
private boolean isScrollCalled;
int isLastPage = 10;
int pageCount = 1;
//Paigination
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
int lastvisibleitemposition = linearLayoutManager.findLastVisibleItemPosition();
if (lastvisibleitemposition == adapter.getItemCount() - 1) {
if (!loading && pageCount != isLastPage) {
loading = true;
jsonRequestList(++pageCount);
isScrollCalled = Boolean.TRUE;
}
}
}
});
private void jsonRequestList(int pageCount) {
//Json Request
if (!isScrollCalled) {
adapter = new FlowerListAdapter(FlowerListActivity.this, list);
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
// Log.e("LIST_SIZE", "" + list.size());
} else {
adapter.updateList(list);
//Log.e("LIST_SIZE", "" + list.size());
}
loading = false;
}
回收器适配器:
ArrayList<YourModelClass> list;
Context context;
//Pagination
public void updateList(ArrayList<YourModelClass> list) {
this.list.addAll(list);
this.notifyDataSetChanged();
}
您可以在 LivePagedListBuilder 中实现 BoundaryCallback。它包含方法 onZeroItemsLoaded。
listLiveData = new LivePagedListBuilder<>
(new MyPatientPagedListProvider(context)
.getAll()
, pagedListConfig)
.setBoundaryCallback(new PagedList.BoundaryCallback() {
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
// do smth here. For example, post boolean value to MutableLiveData to notify activity //that result is empty
}
})
.build();
要获取插入项目的大小或 RecyclerView 的大小,我们需要向我们的 RecyclerView 注册一个 AdapterDataObserver
。
1) 创建一个 AdapterDataObserver 并覆盖你想要的函数。
public class SearchListAdapterDataObserver extends RecyclerView.AdapterDataObserver {
private RecyclerView mRecyclerView;
private ChangeListener mChangeListener;
public SearchListAdapterDataObserver(RecyclerView view, ChangeListener changeListener){
this.mRecyclerView = view;
this.mChangeListener = changeListener;
}
@Override
public void onChanged() {
super.onChanged();
sendItemCount();
}
private void sendItemCount() {
if(mRecyclerView.getAdapter() != null) {
mChangeListener.onChanged(getSize());
}
}
@Override
public void onItemRangeInserted(int positionStart, int itemCount) {
super.onItemRangeInserted(positionStart, itemCount);
sendItemCount();
}
@Override
public void onItemRangeChanged(int positionStart, int itemCount) {
super.onItemRangeChanged(positionStart, itemCount);
sendItemCount();
}
@Override
public void onItemRangeRemoved(int positionStart, int itemCount) {
super.onItemRangeRemoved(positionStart, itemCount);
sendItemCount();
}
public int getSize() {
if(mRecyclerView.getAdapter() != null) {
return mRecyclerView.getAdapter().getItemCount();
}
return 0;
}
public interface ChangeListener {
void onChanged(int size);
}
}
2) 将其注册到您的适配器并收听更改。
if(mViewModel.getSearchPaginatedAdapter() != null){
mViewModel.getSearchPaginatedAdapter().registerAdapterDataObserver
(new SearchListAdapterDataObserver(mRecyclerView, new SearchListAdapterDataObserver.ChangeListener() {
@Override
public void onChanged(int size) {
onListChanges(size);
}
}));
}
修改@Mike Makhovyk,这是我最终想出的办法
在您的 ViewModel 上
创建可变布尔值
private MutableLiveData<Boolean> emptyListMutableLiveData = new MutableLiveData<>();
listLiveData = new LivePagedListBuilder<>
(new MyPatientPagedListProvider(context)
.getAll()
, pagedListConfig)
.setBoundaryCallback(new PagedList.BoundaryCallback() {
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
emptyListMutableLiveData.setValue(true)
}
@Override
public void onItemAtFrontLoaded(@NonNull Complaint itemAtFront) {
super.onItemAtFrontLoaded(itemAtFront);
emptyListMutableLiveData.setValue(false);
}
})
.build();
创建一个方法,return te livedata
public LiveData<Boolean> isEmptyList() {
return emptyListMutableLiveData;
}
在您的 fragment/activity 上,您可以观察布尔结果,然后更新您的 UI