晕,我的应用程序中有LoadMore RecyclerView。它的工作,但当我加载更多的项目时,recyclerview始终保持显示列表的顶部。我的意思是,应该显示最后加载的项目。
任何人,您想帮助我吗?谢谢。
我的屏幕截图:
这是我的代码:
@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();
}
}
答案 0 :(得分:0)
好的,我假设您已经为EndlessScrollListener
实现了RecyclerView
,如果没有,我敦促您检查一下: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
类作为可用于创建服务的Singleton。
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会自动触发网络呼叫,从而避免编写多余的呼叫。
最后,在您的Fragment
或Activity
中,您会看到以下内容:
// 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()
将通过CustomRecyclerScrollListener
触发,然后触发updatePageNumber()
,然后调用fetchJobModel()
,最终您会得到一个回调您的片段。