PageKeyedDataSource loadAfter 没有起火

2024-01-02

在我的片段中,我集成了 android jetpack 分页库和我使用的数据源页面键控数据源带有改造 API 回调。

代码以异常方式运行并将数据加载到回收者视图但当我滚动到底部后,它应该通过触发加载更多数据加载后数据源类中的函数,但没有

我也切换到项目键控数据源仍然无法执行

是我的代码错误还是插件有问题!但在我发现 GitHub 上的一些演示应用程序运行良好时,我遵循了那里的代码。如果有人遇到此问题并已修复,请告诉我 编辑:使用AndroidX

public class ReportsDataSource extends PageKeyedDataSource<Integer, ReportItemModel> {

    MutableLiveData<NetworkState> networkState = new MutableLiveData<>();
    MutableLiveData<NetworkState> initialLoad = new MutableLiveData<>();

    private UserService getUserService;
    private List<Call<?>> compositeDisposable;
    private CompositeDisposable compositeDisposableData;
    private SchedulerProvider schedulerProvider;
    private Completable retryCompletable = null;

    public ReportsDataSource(UserService getUserService, List<Call<?>> compositeDisposable, CompositeDisposable compositeDisposableData, SchedulerProvider schedulerProvider) {
        this.getUserService = getUserService;
        this.compositeDisposable = compositeDisposable;
        this.compositeDisposableData = compositeDisposableData;
        this.schedulerProvider = schedulerProvider;
    }


    @Override
    public void loadInitial(@NonNull LoadInitialParams<Integer> params, @NonNull LoadInitialCallback<Integer, ReportItemModel> callback) {

        networkState.postValue(NetworkState.LOADING);
        initialLoad.postValue(NetworkState.LOADING);

        loadPage(1, new callback() {
            @Override
            public void get(ReportListModel list) {
                setRetry(null);
                networkState.postValue(NetworkState.LOADED);
                initialLoad.postValue(NetworkState.LOADED);
                callback.onResult(list.data.items, 1, list.data.next);
            }

            @Override
            public void failure(Throwable t) {
                setRetry(() -> loadInitial(params, callback));
                NetworkState error = NetworkState.error(t.getMessage());
                networkState.postValue(error);
                initialLoad.postValue(error);
            }
        });
    }

    @Override
    public void loadBefore(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, ReportItemModel> callback) {

    }

    @Override
    public void loadAfter(@NonNull LoadParams<Integer> params, @NonNull LoadCallback<Integer, ReportItemModel> callback) {

        networkState.postValue(NetworkState.LOADING);

        loadPage(params.key, new callback() {
            @Override
            public void get(ReportListModel list) {
                setRetry(null);
                networkState.postValue(NetworkState.LOADED);
                callback.onResult(list.data.items, list.data.next != params.key ? null : list.data.next);
            }

            @Override
            public void failure(Throwable t) {
                setRetry(() -> loadAfter(params, callback));
                networkState.postValue(NetworkState.error(t.getMessage()));
            }
        });
    }


    public static void log(String msg) {
        boolean threadMain = Looper.getMainLooper().getThread() == Thread.currentThread();
        Timber.tag("Thread_finder_" + (threadMain ? "ui" : "none")).d(Thread.currentThread().getId() + " " + msg);
    }

    private void loadPage(int i, callback callback) {
        log("loadPage");
        Call<ReportListModel> call = getUserService.getReportsList(i);
        compositeDisposable.add(call);
        try {
            Response<ReportListModel> response = call.execute();
            log("onResponse");
            if (RetrofitHelper.isSuccessful(response)) {
                callback.get(response.body());
            } else {
                callback.failure(new Throwable("Model verification is failed"));
            }
        } catch (IOException e) {
            callback.failure(e);
            //e.printStackTrace();
        }
    }

    public void retry() {
        if (retryCompletable != null) {
            compositeDisposableData.add(retryCompletable.subscribeOn(schedulerProvider.io()).observeOn(schedulerProvider.ui()).subscribe(() -> {
            }, Timber::d));
        }
    }

    private void setRetry(Action action) {
        if (action == null) {
            this.retryCompletable = null;
        } else {
            this.retryCompletable = Completable.fromAction(action);
        }
    }

    @NonNull
    public MutableLiveData<NetworkState> getNetworkState() {
        return networkState;
    }

    @NonNull
    public MutableLiveData<NetworkState> getInitialLoad() {
        return initialLoad;
    }


    public interface callback {
        void get(ReportListModel list);

        void failure(Throwable t);
    }
}

视图模型

public class ReportsListViewModel extends ViewModel {

    private static final int PAGE_SIZE = 10;
    private Executor executor = Executors.newFixedThreadPool(5);
    public LiveData<PagedList<ReportItemModel>> list;
    private List<Call<?>> compositeDisposable = new ArrayList<>();
    private CompositeDisposable compositeDisposableData = new CompositeDisposable();
    private ReportsDataSourceFactory sourceFactory;


    public final ObservableBoolean isErrorMessageVisible;
    public final ObservableBoolean isRetryButtonVisible;
    public final ObservableBoolean isLoadingProgressBarVisible;
    public final ObservableBoolean isSwipeRefreshLayoutEnable;
    public final ObservableField<String> errorMessage;


    public ReportsListViewModel(UserService userService, SchedulerProvider schedulerProvider) {
        sourceFactory = new ReportsDataSourceFactory(userService, compositeDisposable, compositeDisposableData, schedulerProvider);
        PagedList.Config config = new PagedList.Config.Builder()
                .setPageSize(PAGE_SIZE)
                .setEnablePlaceholders(false)
                .build();

        list = new LivePagedListBuilder<>(sourceFactory, config).build();

        isErrorMessageVisible = new ObservableBoolean(false);
        errorMessage = new ObservableField<>("");
        isRetryButtonVisible = new ObservableBoolean(false);
        isLoadingProgressBarVisible = new ObservableBoolean(true);
        isSwipeRefreshLayoutEnable = new ObservableBoolean(true);
    }


    @Override
    protected void onCleared() {
        super.onCleared();
        RetrofitStatic.clearRetrofitList(compositeDisposable);
        compositeDisposableData.clear();
    }

    public void retry() {
        sourceFactory.getDataSourceLiveData().getValue().retry();
    }

    public void refresh() {
        sourceFactory.getDataSourceLiveData().getValue().invalidate();
    }

    public LiveData<NetworkState> getNetworkState() {
        return Transformations.switchMap(sourceFactory.getDataSourceLiveData(), ReportsDataSource::getNetworkState);
    }

    public LiveData<NetworkState> getRefreshState() {
        return Transformations.switchMap(sourceFactory.getDataSourceLiveData(), ReportsDataSource::getInitialLoad);
    }

    public void setInitialLoadingState(NetworkState networkState) {
        isErrorMessageVisible.set((networkState.getMessage() != null));
        errorMessage.set(networkState.getMessage());

        isRetryButtonVisible.set(networkState.getStatus() == NetworkStateStatus.FAILED);
        isLoadingProgressBarVisible.set(networkState.getStatus() == NetworkStateStatus.RUNNING);
        isSwipeRefreshLayoutEnable.set(networkState.getStatus() == NetworkStateStatus.SUCCESS);
    }
}

页列表适配器

public class ReportListAdapter extends PagedListAdapter<ReportItemModel, RecyclerView.ViewHolder> {

    public static final DiffUtil.ItemCallback<ReportItemModel> DIFF_CALLBACK = new DiffUtil.ItemCallback<ReportItemModel>() {

        @Override
        public boolean areItemsTheSame(@NonNull ReportItemModel oldItem, @NonNull ReportItemModel newItem) {
            return oldItem.reportId == newItem.reportId;
        }

        @Override
        public boolean areContentsTheSame(@NonNull ReportItemModel oldItem, @NonNull ReportItemModel newItem) {
            return oldItem.equals(newItem);
        }
    };
    private NetworkState networkState = null;
    private RetryCallback retryCallback;

    public ReportListAdapter(RetryCallback retryCallback) {
        super(DIFF_CALLBACK);
        this.retryCallback = retryCallback;
    }

    @Override
    public int getItemViewType(int position) {
        if (hasExtraRow() && position == getItemCount() - 1) {
            return R.layout.item_network_state;
        } else {
            return R.layout.recycler_report_item;
        }
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        switch (viewType) {
            case R.layout.recycler_report_item:
            default:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_report_item, parent, false);
                return new ViewHolder(view);
            case R.layout.item_network_state:
                view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_network_state, parent, false);
                return new NetWorkStateHolder(view);
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof ViewHolder) {
            bindView((ViewHolder) holder, position, holder.itemView.getContext());
        } else if (holder instanceof NetWorkStateHolder) {
            bindNetworkView((NetWorkStateHolder) holder, position, holder.itemView.getContext());
        }
    }

    private void bindNetworkView(NetWorkStateHolder holder, int position, Context context) {
        NetworkStateItemViewModel mNetworkStateItemViewModel = new NetworkStateItemViewModel(networkState, retryCallback);
        if (holder.binding != null) {
            holder.binding.setViewModel(mNetworkStateItemViewModel);
            holder.binding.executePendingBindings();
        }
    }

    @Override
    public int getItemCount() {
        return super.getItemCount() + (hasExtraRow() ? 1 : 0);
    }

    private void bindView(ViewHolder holder, int position, Context context) {
        holder.binding.reportId.setText( "Report ID: "+position);
    }

    private boolean hasExtraRow() {
        return networkState != null && networkState != NetworkState.LOADED;
    }

    public void setNetworkState(NetworkState newNetworkState) {
        if (getCurrentList() != null) {
            if (getCurrentList().size() != 0) {
                NetworkState previousState = this.networkState;
                boolean hadExtraRow = hasExtraRow();
                this.networkState = newNetworkState;
                boolean hasExtraRow = hasExtraRow();
                if (hadExtraRow != hasExtraRow) {
                    if (hadExtraRow) {
                        notifyItemRemoved(super.getItemCount());
                    } else {
                        notifyItemInserted(super.getItemCount());
                    }
                } else if (hasExtraRow && previousState != newNetworkState) {
                    notifyItemChanged(getItemCount() - 1);
                }
            }
        }
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private final RecyclerReportItemBinding binding;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            binding = DataBindingUtil.bind(itemView);
        }
    }

    public class NetWorkStateHolder extends RecyclerView.ViewHolder {
        private final ItemNetworkStateBinding binding;
        private final NetworkStateItemViewModel mNetworkStateItemViewModel;

        public NetWorkStateHolder(@NonNull View itemView) {
            super(itemView);
            mNetworkStateItemViewModel = new NetworkStateItemViewModel(networkState, retryCallback);
            binding = DataBindingUtil.bind(itemView);
            binding.setViewModel(mNetworkStateItemViewModel);
            binding.executePendingBindings();
        }
    }
}

分段:

public class ReportsFragment extends ParentFragment implements RetryCallback {

    private ReportsFragment.callback callback;
    private FragmentReportsListBinding binding;
    private ReportsListViewModel reportViewModel;
    private ReportListAdapter adapter;


    public void setup(callback callback) {
        this.callback = callback;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        binding = DataBindingUtil.inflate(inflater, R.layout.fragment_reports_list, container, false);
        reportViewModel = ViewModelProviders.of(this, mViewModelFactory).get(ReportsListViewModel.class);
        binding.setViewModel(reportViewModel);
        binding.executePendingBindings();
        initAdapter();
        initSwipeToRefresh();
        return binding.getRoot();
    }

    private void initSwipeToRefresh() {
        reportViewModel.getRefreshState().observe(this, networkState -> {
            if (adapter.getCurrentList() != null) {
                if (adapter.getCurrentList().size() > 0) {
                    binding.usersSwipeRefreshLayout.setRefreshing(networkState != null && networkState.getStatus() == NetworkState.LOADING.getStatus());
                } else {
                    setInitialLoadingState(networkState);
                }
            } else {
                setInitialLoadingState(networkState);
            }
        });
    }

    private void setInitialLoadingState(NetworkState networkState) {
        reportViewModel.setInitialLoadingState(networkState);
    }

    private void initAdapter() {
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext());
        adapter = new ReportListAdapter(this);
        binding.recycler.setLayoutManager(linearLayoutManager);
        binding.recycler.setAdapter(adapter);
        reportViewModel.list.observe(this,  adapter::submitList);
        reportViewModel.getNetworkState().observe(this, adapter::setNetworkState);
    }

    @Override
    public void retry() {
        reportViewModel.retry();
    }

    public interface callback {

    }
}

XML

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <data>

        <import type="android.view.View" />

        <variable
            name="viewModel"
            type="dasarahalli.portal.adapters.paging.reports.ReportsListViewModel" />
    </data>


    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/usersSwipeRefreshLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:enabled="@{viewModel.isSwipeRefreshLayoutEnable}"
            app:onRefreshListener="@{viewModel::refresh}">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recycler"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:orientation="vertical"
            android:padding="8dp">

            <TextView
                android:id="@+id/errorMessageTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:text="@{viewModel.errorMessage}"
                android:visibility="@{viewModel.isErrorMessageVisible ? View.VISIBLE : View.GONE}" />

            <ProgressBar
                android:id="@+id/loadingProgressBar"
                style="?android:attr/progressBarStyle"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:visibility="@{viewModel.isLoadingProgressBarVisible ? View.VISIBLE : View.GONE}" />

            <Button
                android:id="@+id/retryLoadingButton"
                style="@style/Widget.AppCompat.Button.Colored"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:onClick="@{() -> viewModel.retry()}"
                android:text="RETRY"
                android:visibility="@{viewModel.isRetryButtonVisible ? View.VISIBLE : View.GONE}" />

        </LinearLayout>

    </androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>

在上面的代码中你可以看到我没有调用getitem under 绑定视图持有者但一旦我请求 getItem(itemPostion) 后,一切都开始工作了,它应该是

演示项目:

androidx-paging-library-demo-java https://bitbucket.org/falconro/androidx-paging-library-demo-java

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PageKeyedDataSource loadAfter 没有起火 的相关文章

  • 如何在android中实现触摸平滑图像橡皮擦?

    我已经从 API 演示中看到了finturePaint java 我想实现触摸平滑橡皮擦 通过在android中触摸移动来擦除部分图像 FingerPaint 告诉我要实现这个 mPaint setXfermode new PorterDu
  • 如何从 SDK 实现每个会话的 Google Places 自动完成功能?

    是否可以从 Android 和 iOS 应用程序的 place sdk 实现基于会话的自动完成 根据 6 月 11 日生效的新 Google 地图框架定价 对自动完成的请求可以分为基于击键 会话的请求 我找不到描述实施步骤的文档 除了这个参
  • 如何自定义菜单项的背景颜色?

    我正在尝试定制Toolbar的弹出菜单 现在我无法设置菜单项的背景颜色 我的 styles xml 如下所示
  • Xamarin Android Webview Javascript

    我正在尝试通过 Xamarin for Android 创建一个移动应用程序 它有一个显示网站的 WebView 问题是正常按钮会触发 但 javascript 事件不会触发 我已经启用了 Javascript 但没有运气 如何在 Andr
  • 如何正确释放Android MediaPlayer

    我正在尝试向我的 Android 应用程序添加一个按钮 当点击该按钮时它会播放 MP3 我已经让它工作了 但没有办法释放 mediaPlayer 对象 因此即使在我离开活动后它仍然会继续播放 如果我在react 方法之外初始化MediaPl
  • 按下按钮时应用不同的样式

    有没有办法在按下按钮时将样式应用于按钮 如果我有一种风格样式 xml
  • Gradle 构建错误:无法从 https://repo1.maven.org/maven2/io/fabric/tools/gradle/maven-metadata.xml 加载 Maven 元数据

    我在 Android studio 中遇到 gradle 构建错误 如下所示 Error A problem occurred configuring project MyApp Could not resolve all dependen
  • Android WebView里面的ScrollView只滚动scrollview

    在我的应用程序中 我有一个 ScrollView 其中包含一些线性视图 一些文本视图和一个 Webview 然后是其他线性布局等 问题是 WebView 不滚动 Scroll 仅侦听 ScrollView 有什么建议么
  • Android应用程序组件销毁和重新创建的详细信息

    有人可以向我提供一些具体的 值得信赖的 最好是简洁的 信息 内容如下 系统销毁和 如果适用 重新创建组件的顺序 片段 活动 活动的线程 异步任务 计时器 静态数据 类何时卸载 其他类中的线程 异步任务 定时器 主机 TabActivity
  • 通过 WhatsApp 发送消息

    由于我发现了一些较旧的帖子 表明 Whatsapp 不支持此功能 我想知道是否发生了变化 以及是否有办法打开与我通过意图发送的号码进行 Whatsapp 聊天 UPDATE请参阅https faq whatsapp com en andro
  • 在 Cordova 应用程序中获取额外功能

    我们有两个 Android 应用程序 一个使用本机 Java 实现 另一个使用 Ionic 编写 Ionic 应用程序启动我的应用程序 这是使用灯插件 https github com lampaa com lampa startapp 我
  • 对于一个单元格,RecyclerView onBindViewHolder 调用次数过多

    我正在将 RecyclerView 与 GridLayoutManager 一起使用 对于网格中的每个项目 我需要调用 REST api 来检索数据 然后 从远程异步获取数据后 我使用 UIL 加载 显示图像 一切似乎都很好 但我发现 on
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • 我应该释放或重置 MediaPlayer 吗?

    我有自己的自定义适配器类 称为 WordAdapter 并且我正在使用媒体播放器 名为pronounce WordAdapter 类中的全局变量 我有不同的活动 其中每个列表项都有线性布局 名为linearLayout 我正在设置onCli
  • Android 中的处理程序与异步调用

    目前我正在使用处理程序来调用 Web 服务方法以使其在后台运行 问题是它需要更多的时间来给出响应 在性能方面似乎更昂贵 现在我计划使用异步调用 哪一个是最好的 Android 中的处理程序和异步调用有什么区别 请帮我想出一个最好的解决方案
  • 如何检查 Android 中的同步设置

    我正在构建一个 Android 应用程序 我需要检查设备中注册的每个单独帐户的同步设置 我知道我可以通过 ContentResolver 类来做到这一点 但我遇到了一些问题 我已设法获取设备上所有帐户的列表 但我不知道在运行时从哪里获取特定
  • 没有用于警告的设置器/字段 Firebase 数据库检索数据填充列表视图

    我只是想将 Firebase 数据库中的数据填充到我的列表视图中 日志显示正在检索数据 但适配器不会将值设置为列表中单个列表项中的文本 它只说 没有二传手 场地插入值 这让我觉得我的设置器没有正确制作 但 Android Studio 自动
  • 插件“Android Bundle Support”不兼容

    大家好 自从上次更新以来 当我启动 android studio 时 我遇到了一个非常奇怪的错误 我有这个错误 插件错误 插件 Android Bundle Support 不兼容 直到构建 AI 195 SNAPSHOT 我在网上找不到任
  • 问题:为什么React Native Video不能全屏播放视频?

    我正在react native 0 57 7 中为android和ios创建一个应用程序并使用反应本机视频 https github com react native community react native video播放上传到的视频
  • Android 屏幕方向错误

    我使用的是 Android HTC HERO 2 1 版本 我写的活动

随机推荐