#java #android #android-paging #pagedlist
#java #Android #android-подкачка #список страниц
Вопрос:
Я делал разные способы, но безрезультатно
Источник данных
public class NetReqDataSourceFactory extends DataSource.Factory {
private static final String TAG = NetReqDataSourceFactory.class.getSimpleName();
private MutableLiveData<NetReqPageKeyedDataSource> networkStatus;
private NetReqPageKeyedDataSource moviesPageKeyedDataSource;
public NetReqDataSourceFactory(Context context, String status) {
this.networkStatus = new MutableLiveData<>();
moviesPageKeyedDataSource = new NetReqPageKeyedDataSource(context, status);
}
@Override
public DataSource create() {
networkStatus.postValue(moviesPageKeyedDataSource);
return moviesPageKeyedDataSource;
}
public MutableLiveData<NetReqPageKeyedDataSource> getNetworkStatus() {
return networkStatus;
}
public ReplaySubject<ReqDataList> getData() {
return moviesPageKeyedDataSource.getData();
}
}
PageKeyedDataSource
public class NetReqPageKeyedDataSource extends PageKeyedDataSource<String, ReqDataList> {
private static final String TAG = NetReqPageKeyedDataSource.class.getSimpleName();
private final MutableLiveData networkState;
private final ReplaySubject<ReqDataList> moviesObservable;
private final ConnectionServer connectionServer;
private final String status;
private final MasterRepository repository;
NetReqPageKeyedDataSource(Context context, String status) {
networkState = new MutableLiveData();
connectionServer = new ConnectionServer(Util.getApiWithAuth(context, (new ArrayList<ReqDataList>()).getClass(), new ReqJsonDeserializer()));
moviesObservable = ReplaySubject.create();
this.status = status;
this.repository = MasterRepository.getInstance(context);
}
public MutableLiveData getNetworkState() {
return networkState;
}
public ReplaySubject<ReqDataList> getData() {
return moviesObservable;
}
@Override
public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, ReqDataList> callback) {
Log.i(TAG, "Loading Initial Rang, Count " params.requestedLoadSize);
Log.i(TAG, "Loading Initial, Status " status);
networkState.postValue(NetworkState.FIRST_LOADING);
connectionServer.getReqByPage(1, status).enqueue(new Callback<ArrayList<ReqDataList>>() {
@Override
public void onResponse(Call<ArrayList<ReqDataList>> call, Response<ArrayList<ReqDataList>> response) {
if (response.isSuccessful()) {
callback.onResult(response.body(), Integer.toString(1), Integer.toString(2));
networkState.postValue(NetworkState.LOADED);
if (response.body().size() > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
response.body().forEach(moviesObservable::onNext);
} else {
for (ReqDataList data : response.body()) {
moviesObservable.onNext(data);
}
}
} else {
networkState.postValue(new NetworkState(NetworkState.Status.FIRST_FAILED, "Nothing here yet, pull to refresh amp; try again"));
}
} else {
Log.e("API CALL", response.message());
networkState.postValue(new NetworkState(NetworkState.Status.FIRST_FAILED, response.message()));
}
}
@Override
public void onFailure(Call<ArrayList<ReqDataList>> call, Throwable t) {
String errorMessage;
if (t.getMessage() == null) {
errorMessage = "unknown error";
} else {
errorMessage = t.getMessage();
}
networkState.postValue(new NetworkState(NetworkState.Status.FIRST_FAILED, errorMessage));
callback.onResult(new ArrayList<>(), Integer.toString(1), Integer.toString(2));
}
});
}
@Override
public void loadAfter(@NonNull LoadParams<String> params, final @NonNull LoadCallback<String, ReqDataList> callback) {
Log.i(TAG, "Loading page " params.key );
networkState.postValue(NetworkState.LOADING);
final AtomicInteger page = new AtomicInteger(0);
try {
page.set(Integer.parseInt(params.key));
}catch (NumberFormatException e){
e.printStackTrace();
}
Call<ArrayList<ReqDataList>> callBack = connectionServer.getReqByPage(page.get(), status);
callBack.enqueue(new Callback<ArrayList<ReqDataList>>() {
@Override
public void onResponse(Call<ArrayList<ReqDataList>> call, Response<ArrayList<ReqDataList>> response) {
if (response.isSuccessful()) {
callback.onResult(response.body(), Integer.toString(page.get() 1));
networkState.postValue(NetworkState.LOADED);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
response.body().forEach(moviesObservable::onNext);
} else {
for (ReqDataList data : response.body()) {
moviesObservable.onNext(data);
}
}
} else {
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, response.message()));
Log.e("API CALL", response.message());
}
}
@Override
public void onFailure(Call<ArrayList<ReqDataList>> call, Throwable t) {
String errorMessage;
if (t.getMessage() == null) {
errorMessage = "unknown error";
} else {
errorMessage = t.getMessage();
}
networkState.postValue(new NetworkState(NetworkState.Status.FAILED, errorMessage));
callback.onResult(new ArrayList<>(), Integer.toString(page.get()));
}
});
}
@Override
public void loadBefore(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, ReqDataList> callback) {
}
}
PagedList.Config
public class ReqNetwork {
final private static String TAG = ReqNetwork.class.getSimpleName();
final private LiveData<PagedList<ReqDataList>> moviesPaged;
final private LiveData<NetworkState> networkState;
public ReqNetwork(NetReqDataSourceFactory dataSourceFactory, PagedList.BoundaryCallback<ReqDataList> boundaryCallback) {
PagedList.Config pagedListConfig = (new PagedList.Config.Builder())
.setEnablePlaceholders(false)
.setInitialLoadSizeHint(20)
.setPageSize(10)
.build();
networkState = Transformations.switchMap(
dataSourceFactory.getNetworkStatus(),
(Function<NetReqPageKeyedDataSource, LiveData<NetworkState>>) NetReqPageKeyedDataSource::getNetworkState
);
Executor executor = Executors.newFixedThreadPool(3);
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(dataSourceFactory, pagedListConfig);
moviesPaged = livePagedListBuilder.
setFetchExecutor(executor).
setBoundaryCallback(boundaryCallback).
build();
}
public LiveData<PagedList<ReqDataList>> getPagedMovies() {
return moviesPaged;
}
public LiveData<NetworkState> getNetworkState() {
return networkState;
}
}
LocalDataSource
public class DbReqDataSourceFactory extends DataSource.Factory {
private static final String TAG = DbReqDataSourceFactory.class.getSimpleName();
private DbReqPageKeyedDataSource moviesPageKeyedDataSource;
public DbReqDataSourceFactory(ReqDataDao dao, String filterStatus) {
moviesPageKeyedDataSource = new DbReqPageKeyedDataSource(dao, filterStatus);
}
@Override
public DataSource create() {
return moviesPageKeyedDataSource;
}
}
LocalPageKeyedDataSource
public class DbReqPageKeyedDataSource extends PageKeyedDataSource<String, ReqDataList> {
public static final String TAG = DbReqPageKeyedDataSource.class.getSimpleName();
private final ReqDataDao dataDao;
private String filterStatus;
public DbReqPageKeyedDataSource(ReqDataDao dao, String status) {
dataDao = dao;
filterStatus = status;
}
@Override
public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, ReqDataList> callback) {
Log.i(TAG, "Loading Initial Rang, Count " params.requestedLoadSize);
Log.w(TAG, "loadInitial: " filterStatus);
List<ReqDataList> data = null;
if (filterStatus == null) {
data = dataDao.getListAll();
} else {
data = dataDao.getListAllByStatus(filterStatus);
}
if(data.size() != 0) {
callback.onResult(data, "0", "1");
}
}
@Override
public void loadAfter(@NonNull LoadParams<String> params, final @NonNull LoadCallback<String, ReqDataList> callback) {
}
@Override
public void loadBefore(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, ReqDataList> callback) {
}
}
Repository
public LiveData<PagedList<ReqDataList>> getDataReqPage(Context context, String status){
initReqPageDao(status);
NetReqDataSourceFactory dataSourceFactory = new NetReqDataSourceFactory(context, status);
network = new ReqNetwork(dataSourceFactory, reqBoundaryCallback);
reqLiveDataMerger = new MediatorLiveData<>();
reqLiveDataMerger.addSource(network.getPagedMovies(), value -> {
reqLiveDataMerger.setValue(value);
Log.d(TAG, value.toString());
});
dataSourceFactory.getData().
observeOn(Schedulers.io()).
subscribe(item -> {
ReqData reqData = new ReqData();
reqData.req_sid = item.req_sid;
reqData.req_uid = item.req_uid;
reqData.req_total = item.req_total;
reqData.req_pemda = item.req_pemda;
reqData.req_lon = item.req_lon;
reqData.req_lat = item.req_lat;
reqData.req_address = item.req_address;
reqData.req_remark = item.req_remark;
reqData.address_id = item.address_id;
reqData.post_by = item.post_by;
reqData.post_date = item.post_date;
reqData.update_by = item.update_by;
reqData.update_date = item.update_date;
reqData.post_status = 1;
database.dataReqDao().insert(reqData);
});
return reqLiveDataMerger;
}
public void initReqPageDao(String status) {
PagedList.Config pagedListConfig = (new PagedList.Config.Builder()).setEnablePlaceholders(false)
.setInitialLoadSizeHint(Integer.MAX_VALUE).setPageSize(Integer.MAX_VALUE).build();
Executor executor = Executors.newFixedThreadPool(3);
DbReqDataSourceFactory dataSourceFactory = new DbReqDataSourceFactory(database.dataReqDao(), status);
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(dataSourceFactory, pagedListConfig);
reqPaged = livePagedListBuilder.setFetchExecutor(executor).build();
}
private PagedList.BoundaryCallback<ReqDataList> reqBoundaryCallback = new PagedList.BoundaryCallback<ReqDataList>() {
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
reqLiveDataMerger.addSource(getReqData(), value -> {
reqLiveDataMerger.setValue(value);
reqLiveDataMerger.removeSource(getReqData());
});
}
};
public LiveData<PagedList<ReqDataList>> getReqData() {
return reqPaged;
}
ViewModel
public LiveData<PagedList<ReqDataList>> getReqDataPaged(String status) {
return getRepository().getDataReqPage(getContext(), status);
}
public LiveData<NetworkState> getNetworkState() {
return getRepository().getNetworkState();
}
Вы, ребята, нашли мою ошибку?
Я загружаю данные, используя фрагмент внутри ViewPager
public class ReqListFragment extends BaseFragment<FragmentReqListBinding, ReqListViewModel> implements ReqListViewModel.Navigator {
@Inject
ConnectionServer server;
@Inject
MasterRepository repository;
private FragmentReqListBinding binding;
private ReqListViewModel viewModel;
private String status;
private boolean hasLoaded = false;
@Override
public int getBindingVariable() {
return 0;
}
@Override
public int getLayoutId() {
return R.layout.fragment_req_list;
}
@Override
public ReqListViewModel getViewModel() {
return viewModel;
}
public ReqListFragment newInstance(String status) {
ReqListFragment fragment = new ReqListFragment();
Bundle bundle = new Bundle();
bundle.putString(Constants.STATUS, status);
fragment.setArguments(bundle);
return fragment;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
AndroidSupportInjection.inject(this);
binding = getViewDataBinding();
viewModel = ViewModelProviders.of(this, new ReqListViewModel.ModelFactory(getBaseActivity(), server, repository)).get(ReqListViewModel.class);
viewModel.setNavigator(this);
status = getArguments().getString(Constants.STATUS);
viewModel.filterStatus.postValue(status);
if (status.equals(Constants.ALL)) {
loadData(status);
}
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
binding.swipe.setColorSchemeColors(getResources().getColor(R.color.colorPrimary), getResources().getColor(R.color.colorApprovedBg));
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getBaseActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
binding.recyclerView.setLayoutManager(linearLayoutManager);
binding.swipe.setOnRefreshListener(()->loadData(status));
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(getView() != null amp;amp; isVisibleToUser amp;amp; !hasLoaded amp;amp; !status.equals(Constants.ALL)) {
loadData(status);
}
}
private void loadData(String status) {
binding.shimmerViewContainer.startShimmer();
binding.shimmerViewContainer.setVisibility(View.VISIBLE);
final ReqListAdapter pageListAdapter = new ReqListAdapter(viewModel);
viewModel.getReqDataPaged(status).observe(this, pageListAdapter::submitList);
viewModel.getNetworkState().observe(this, networkState -> {
pageListAdapter.setNetworkState(networkState);
binding.setState(networkState);
});
binding.recyclerView.setAdapter(pageListAdapter);
hasLoaded = true;
}
@Override
public void onItemClick(String item) {
Intent intent = new Intent(getBaseActivity(), ReqViewActivity.class);
intent.putExtra(Constants.SID, item);
startActivity(intent);
}
}
В других условиях я добьюсь успеха, если переместу код initReqPageDao
в класс RoomDatabase,
но я не понимаю, как отправлять статус для фильтра Спасибо всем за вашу помощь, надеюсь, я найду ошибку и решение