抽屉中的某些菜单会打开Tab + ViewPager内容。每个页面(片段)都是从服务器请求其数据的列表。
每次单击该菜单时,我都希望内容会立即显示标签,即使仍然请求数据而不是空屏幕。我尝试在TabFragment中添加进度条,以便在准备ViewPager和寻呼机数据时内容将显示加载。但是,内容仍然显示没有加载指示器的空屏幕。我发现问题是因为从每个寻呼机调用从服务器请求数据的方法。
我应该将请求数据的方法移到TabFragment吗?
我的TabFragment类看起来像:
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
.....
content = view.findViewById(R.id.content);
content.setVisibility(View.GONE);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
viewPager = (ViewPager) view.findViewById(R.id.pager);
progressBar = (ProgressBar) view.findViewById(R.id.progressBar1);
farmerViewPagerAdapter = new FarmerViewPagerAdapter(getChildFragmentManager(), titles);
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(farmerViewPagerAdapter);
tabLayout.post(()->{
tabLayout.setupWithViewPager(viewPager);
for (int i = 0; i < titles.length; ++i){
tabLayout.getTabAt(i).setIcon(icons[i]);
}
});
}
这里是每个页面的片段(每个页面请求不同的数据):
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
this.view = view;
emptyView = view.findViewById(R.id.emptyView);
emptyText = (TextView) view.findViewById(R.id.emptyTextView);
recyclerView = (RecyclerView) view.findViewById(R.id.list);
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new FarmerAdapter(data, getContext());
recyclerView.setAdapter(adapter);
recyclerView.addItemDecoration(
new HorizontalDividerItemDecoration.Builder(getContext())
.showLastDivider()
.marginResId(R.dimen.divider_margin_left, R.dimen.divider_margin_right)
.build());
swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.swipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(() -> {
if (!Util.isNetworkAvailable(getContext())) {
if (swipeRefreshLayout.isRefreshing()) swipeRefreshLayout.setRefreshing(false);
} else {
currentPage = 1;
loadData(); //method to request data from server
}
}
);
if (user != null) {
getDataFromLocal();
addToAdapter();
loadData();
}
}
(Ed)loadData方法:
Observable<Response<List<Data>>> dataApi = request.getServerData(currentPage,
NUMBER_DATA_PER_PAGE,
token);
dataApi.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(responseData -> {
if (swipeRefreshLayout.isRefreshing()) swipeRefreshLayout.setRefreshing(false);
if (responseData.isSuccessful() && responseData.code() == 200) {
currentPage++;
adapter.add(responseData.body());
if (adapter.getItemCount() < 1) {
emptyText.setText("Empty");
emptyView.setVisibility(View.VISIBLE);
}
} else {
try {
JSONObject json = new JSONObject(responseFarmer.errorBody().string());
Toast.makeText(getContext(), json.getString("message"), Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}, error -> {
if (swipeRefreshLayout != null && swipeRefreshLayout.isRefreshing())
swipeRefreshLayout.setRefreshing(false);
if (error != null && error.getLocalizedMessage() != null)
Toast.makeText(getContext(), error.getLocalizedMessage(), Toast.LENGTH_LONG).show();
});
此方法从寻呼机片段调用。
答案 0 :(得分:0)
你的AsyncTask有一个空的doInBackground()体。这基本上使它同步。假设你有这个AsyncTask:
private class SetAdapterTask extends AsyncTask<Void,Void,Void> {
protected Void doInBackground(Void... params) {
return null;
}
@Override
protected void onPostExecute(Void result) {
doPostExecute();
}
@Override
protected void onPreExecute() {
doPreExecute();
}
}
你可以在你的代码中这样称呼它:
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
.....
new SetAdapterTask().execute();
}
但由于你的AsyncTask在后台没有做任何事情,postExecute会在preExecute之后立即触发,使整个事情等同于:
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
.....
doPreExecute();
doPostExecute();
}
换句话说,您可以在preExecute中使ProgressBar可见,并在postExecute中使其消失后立即显示。
正确的方法是将ProgressBar可见性设置移动到用于加载数据的AsyncTask,该数据位于我假设的loadData()中的某个位置。至于数据加载本身,如果没有看到加载数据的实际方法,很难说出了什么问题。