0

晕,我的应用中有 LoadMore RecyclerView。这是工作,但是当我加载更多项目时,recyclerview 总是保持显示列表的顶部。我的意思是,它应该显示最后加载的项目。

任何人,你愿意帮助我吗?谢谢。

我的截图:

  1. 1 - 5 是第一个加载的列表

在此处输入图像描述

  1. 滚动 recyclerView 后显示 6 - 10,但在加载 6 - 10 后,recyclerView 始终保持显示列表顶部(1-5)

在此处输入图像描述

这是我的代码:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_job_company);

    //intent untuk nerima value namaAdver dan handling jika tdk ada list
    TextView namaCompany = (TextView) findViewById(R.id.tv_companyname);
    TextView emptyList = (TextView) findViewById(R.id.emptylist);

    loading = (ProgressBar) findViewById(R.id.loading);
    loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);

    Intent intentGet = getIntent();
    companyName = intentGet.getStringExtra("namaCompany");
    idComp = intentGet.getStringExtra("idCompany");

    try {
        compID = Integer.parseInt(idComp);
    } catch (NumberFormatException nfe) {

    }

    namaCompany.setText(companyName);
    setTitle(intentGet.getStringExtra("namaCompany"));

    PaginationJobCompany(compID, pageNum);

    recyclerView = (RecyclerView) findViewById(R.id.rv_job_company2);
    recyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.addItemDecoration(new DividerItemDecoration(getApplicationContext(), null)); //untuk divider

}

private void PaginationJobCompany(final int compID, final int pageNumber) {
    try {
        loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
        loading.setVisibility(View.GONE);


        //authorization JWT pref_token berdasarkan string yg disimpan di preferenceManager pada class login.
        Authorization = (PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString(
                getResources().getString(R.string.pref_token), ""));

        //production
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(getResources().getString(R.string.base_url))
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        //assign variabel request ke class interface TabAdverRequest
        final APIInterfaces request = retrofit.create(APIInterfaces.class);

        Call<ReportJobModel> call = request.getReportPagination(compID, pageNum, length, Authorization); //ngirim ke API
        call.enqueue(new Callback<ReportJobModel>() {
            @Override
            public void onResponse(Call<ReportJobModel> call, Response<ReportJobModel> response) {
                loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
                loading.setVisibility(View.GONE);
                if (response.isSuccessful()) {
                    companyResult = response.body().getResult();
                    if (!companyResult.isEmpty()) {
                        company.addAll(companyResult);

                        for (int i = 0; i < companyResult.size(); i++) {
                            if (company.get(i).getCompanyID() == compID) {
                                jobItemResult = response.body().getResult().get(i).getJobs();
                                jobItem.addAll(jobItemResult);
                            }
                        }
                    }
                    else {
                        for (int j = 0; j < companyResult.size(); j++) {
                            if (company.get(j).getCompanyID() == compID) {
                                lastId = jobItem.size()-1;
                            }
                        }

                    }

                    adapter = new JobCompanyAdapter(jobItem, recyclerView);
                    recyclerView.setAdapter(adapter);

                    adapter.setOnLoadMoreListener(new OnLoadMoreListener() {
                        @Override
                        public void onLoadMore() {
                            //add null , so the adapter will check view_type and show progress bar at bottom
                            jobItem.add(null);
                            adapter.notifyItemInserted(jobItem.size() - 1);
                            loading.getIndeterminateDrawable().setColorFilter(getResources().getColor(R.color.colorPrimary), PorterDuff.Mode.MULTIPLY);
                            loading.setVisibility(View.GONE);

                            handler.postDelayed(new Runnable() {
                                @Override
                                public void run() {

                                    jobItem.remove(jobItem.size() - 1);
                                    adapter.notifyItemRemoved(jobItem.size());
                                    loading.setVisibility(View.GONE);

                                        pageNum++;
                                        loading.setVisibility(View.GONE);
                                        PaginationJobCompany(compID, pageNum);
                                        adapter.notifyDataSetChanged();
                                }
                            }, 2000);
                        }
                    });

                } else if (response.errorBody() != null) {
                    loading.setVisibility(View.GONE);
                    Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda!", Toast.LENGTH_LONG).show();
                } else if (response.code() == 400) {
                    loading.setVisibility(View.GONE);
                    Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda!", Toast.LENGTH_LONG).show();
                } else {
                    loading.setVisibility(View.GONE);
                    Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda! 1", Toast.LENGTH_LONG).show();
                }
            }

            @Override
            public void onFailure(Call<ReportJobModel> call, Throwable t) {
                Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda! 1", Toast.LENGTH_LONG).show();
            }
        });
    } catch (Exception e) {
        Toast.makeText(getApplicationContext(), "Gagal Memuat. Periksa Koneksi Anda! 1", Toast.LENGTH_LONG).show();
    }
}
4

1 回答 1

0

好的,我假设您已经实现EndlessScrollListenerRecyclerView如果没有,我敦促您检查一下:https ://gist.github.com/nesquena/d09dc68ff07e845cc622 。为了进一步使您的代码更具可读性和适应性,我建议您使用更多的封装。

例如:有一个NetworkHandler为您执行 UI 的回调。相应地切换 UI 行为的位置。为此,您需要一个OnDataCallback接口。

// OnDataCallback.java
interface OnDataCallback<T> {
    void onData(T data);
    void onError(Throwable error);
}

// NetworkHandler.java
public class NetworkHandler<T> {
    @Nullable
    protected OnDataCallback<T> dataCallback;

    protected int pageIndex = 0;

    public void setDataCallback(OnDataCallback<T> dataCallback) {
        this.dataCallback = dataCallback;
    }

    public void removeDataCallback() {
        dataCallback = null;
    }

    public void setPageIndex(int pageIndex) {
        this.pageIndex = pageIndex;
    }

    public void updatePageNumber() {
        pageIndex++;
    }
}

创建一个RetrofitUtils可以用于创建服务的单例类。

public static class RetrofitUtils {

    private static RetrofitUtils utils;
    public static RetrofitUtils getInstance() {
        if (utils == null) {
            utils = new RetrofitUtils();
        }
        return utils;
    }

    private Retrofit retrofit;

    public Retrofit getRetrofitInstance(){
        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl("http://mybaseurl.api/v1/")
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }

    public JobService constructJobService(Class<JobService> uClass)  {
        return getRetrofitInstance().create(uClass);
    }

    public LoginService construcstLoginService(Class<LoginService> uClass) {
        return getRetrofitInstance().create(uClass);
    }
}

NetworkHandler然后根据您的规范继承并覆盖方法,例如有一个JobNetworkHandler为您执行请求和分页的方法。创建自定义Throwable类以更有效地处理错误,就像在示例中一样ErrorBodyThrowable。剩下的就是你必须实现回调并在片段或活动中设置 UI。

public class JobReportHandler extends NetworkHandler<ReportJobModel> {
    int compID;
    int length;

    Authorization auth = AuthUtils.getAuth();

    @Override
    public void updatePageNumber() {
        super.updatePageNumber();
        fetchJobsModel(compID, length);
    }

    public void fetchJobsModel(int compID, int length) {
        this.compID = compID;
        this.length = length;
        JobService request = RetrofitUtils.getInstance().constructJobService(JobService.class);
        Call<ReportJobModel> call = request.getReportPagination(compID, pageIndex, length, auth); //ngirim ke API
        call.enqueue(new Callback<JobModel>() {
            @Override
            public void onResponse(Call<JobModel> call, Response<JobModel> response) {
                // manipulate data and pass the UI model
                // that needs to be handled by the view
                ReportJobModel reportJobModel = response.convertToReport();
                if (dataCallback == null) return;

                if (response.isSuccessful()) {
                    dataCallback.onData(reportJobModel);
                } else if (response.errorBody() != null) {
                    dataCallback.onError(new ErrorBodyThrowable());
                } else if (response.code() == 400) {
                    dataCallback.onError(new ApiError());
                } else {
                    // do something else
                }
            }

            @Override
            public void onFailure(Call<ReportJobModel> call, Throwable t) {
                if (dataCallback != null) {
                    dataCallback.onError(t);
                }
            }
        });
    }
    public class ErrorBodyThrowable extends Throwable {
        ErrorBodyThrowable() {
            super("Gagal Memuat. Periksa Koneksi Anda!");
        }
    }
}

请注意,更新 pageIndex 会自动触发网络调用,因此您可以避免编写冗余调用。

最后在你的FragmentActivity有这样的东西:

// TestFragment.java
public final class TestFragment extends Fragment implements OnDataCallback<ReportJobModel>, CustomRecyclerOnScrollListener {
    @Bind(R.id.myRecyclerView)
    RecyclerView myRecyclerView;

    private JobsAdapter adapter;
    private final JobReportHandler jobHandler = new JobReportHandler();
    private final Handler mainThreadHandler = new Handler(Looper.getMainLooper());
    private MyCustomEndlessScrollListener endlessScroll;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.my_list_fragment, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        endlessScroll = = new MyCustomEndlessScrollListener(this);
        setUi();
        initializeNetwork();
    }

    private void initializeNetwork() {
        // after setting the UI Parameters
        jobHandler.setDataCallback(this);
        jobHandler.fetchJobsModel(compID, length);
    }

    @Override
    public void onData(ReportJobModel dataModel) {
        // just a safety mechanism to handle threading
        // use the main thread dispatcher
        mainThreadHandler.post(new Runnable() {
            @Override
            public void run() {
                final ArrayList<JobItem> data = dataModel.getJobItems();
                UiUtils.makeGone(loadingProgress);
                if (myRecyclerView.getAdapter() == null || jobAdapter == null) {
                    jobAdapter = JobsAdapter(data);
                    myRecyclerView.setAdapter(jobAdapter);
                    myRecyclerView.setOnScrollChangeListener(endlessScroll);
                } else {
                    jobAdapter.getItems().addAll(data);
                    jobAdapter.notifyItemRangeInserted(jobAdapter.getItems().size() -1, data.size());
                }
            }
        });
    }


    @Override
    public void onScrolledToBottom() {
        jobHandler.updatePageNumber();
    }

    @Override
    public void onError(final Throwable error) {
        // just a safety mechanism to handle threading
        // use the main thread dispatcher
        mainThreadHandler.post(new Runnable() {
            @Override
            public void run() {
                if (error.getMessage() != null && !error.getMessage().isEmpty()) {
                    Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    @Override
    public void onDestroy() {
        jobHandler.removeDataCallback();
        super.onDestroy();
    }
}

如您所见,onScrolledToBottom()将通过 theCustomRecyclerScrollListener触发,然后触发 the updatePageNumber(),然后调用 the fetchJobModel(),最终您将在片段上获得回调。

于 2018-06-29T11:39:56.697 回答