由于休息 api 延迟,视图寻呼机中的第一个片段未显示
First fragment in view pager not showing because of rest api delay
我有一个导航抽屉 activity,其中一个片段具有视图分页器和选项卡。所有 4 个片段都从服务器获取数据。我的问题是视图寻呼机正在加载前 2 个片段,因此我的第一个片段一开始没有显示内容,因为其余片段 api 的延迟。因此,在解析和显示第一个片段中的数据之前,将创建并显示第二个片段。我该如何解决?
这是我的片段容器
public class FragmentMoviesContainer extends KFragment {
private MainActivity activity;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies_container, container, false);
activity = (MainActivity) getActivity();
assert activity != null;
activity.setVisibleFragment(this);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
// Set up the ViewPager with the sections adapter.
ViewPager mViewPager = rootView.findViewById(R.id.container);
TabLayout tabLayout = rootView.findViewById(R.id.tabs);
mViewPager.setAdapter(mSectionsPagerAdapter);
tabLayout.setupWithViewPager(mViewPager);
return rootView;
}
@Override
public void onResume() {
super.onResume();
ActionBar actionBar = activity.getSupportActionBar();
if (actionBar != null)
actionBar.setTitle(R.string.movies);
activity.getNavigationView().setCheckedItem(R.id.nav_movies);
activity.setElevation(true);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return replaceFragmentMovies(Constants.STRINGS.UPCOMING);
case 1:
return replaceFragmentMovies(Constants.STRINGS.NOW_PLAYING);
case 2:
return replaceFragmentMovies(Constants.STRINGS.POPULAR);
case 3:
return replaceFragmentMovies(Constants.STRINGS.TOP_RATED);
default:
return null;
}
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.coming_soon);
case 1:
return getString(R.string.now_playing);
case 2:
return getString(R.string.popular);
case 3:
return getString(R.string.top_rated);
default:
return "";
}
}
@Override
public int getCount() {
return 4;
}
private FragmentMovies replaceFragmentMovies(String type) {
FragmentMovies fragmentMovies = new FragmentMovies();
fragmentMovies.setType(type);
return fragmentMovies;
}
}
@Override
public void serviceResponse(int responseID, List<KObject> objects) {
}
@Override
public void update(ModelService service, boolean reload) {
}
}
这是我在选项卡中显示的片段
public class FragmentMovies extends KFragment implements MoviesAdapter.OnLoadMoreListener {
private MainActivity activity;
private ModelService service;
private RecyclerView moviesRv;
private String type;
public void setType(String type) {
this.type = type;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
activity = (MainActivity) getActivity();
if (activity != null) {
service = activity.getService();
activity.setVisibleFragment(this);
}
moviesRv = rootView.findViewById(R.id.movies_list);
moviesRv.setLayoutManager(new LinearLayoutManager(getContext()));
this.update(service, false);
return rootView;
}
@Override
public void serviceResponse(int responseID, List<KObject> objects) {
if ((objects != null && !objects.isEmpty()) && (responseID == Constants.UPCOMING || responseID == Constants.NOW_PLAYING || responseID == Constants.POPULAR
|| responseID == Constants.TOP_RATED)) {
Section section = (Section) objects.get(0);
MovieListAdapter adapter = new MovieListAdapter(getContext(), section.getMovieList());
moviesRv.setAdapter(adapter);
}
}
@Override
public void update(final ModelService service, final boolean reload) {
boolean hasConnection = Connection.isNetworkAvailable(getContext());
if (hasConnection && service != null) {
final int responseId = getResponseID();
service.getMovies(type, "", false, responseId, reload);
} else {
// progressBar.setVisibility(View.GONE);
DialogHelper.noConnectionDialog(getContext());
}
}
private int getResponseID() {
switch (type) {
case Constants.STRINGS.UPCOMING:
return Constants.UPCOMING;
case Constants.STRINGS.NOW_PLAYING:
return Constants.NOW_PLAYING;
case Constants.STRINGS.POPULAR:
return Constants.POPULAR;
case Constants.STRINGS.TOP_RATED:
return Constants.TOP_RATED;
default:
return 0;
}
}
@Override
public void onLoadMore(MoviesAdapter adapter) {
}
@Override
public void onResume() {
super.onResume();
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().setTitle("Movies");
activity.getNavigationView().setCheckedItem(R.id.nav_movies);
activity.setElevation(true);
activity.getAddFab().hide();
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
方法 update 调用其余 api url 并获取数据。这是我基于 AsyncTask 创建的框架。然后对象列表返回到在我创建适配器并显示数据的方法 onServiceResponse 中解析的片段。问题是第二个片段是在第一个片段的 onServiceResponse 方法之前创建的。
您应该从第一个片段进行 api 调用,在获得结果后您应该进行其余的调用。如果您需要有关代码的任何帮助,请告诉我。我认为这应该是直截了当的。
查看您的代码后,有两件事可以将片段膨胀到选项卡上。
- Use single Fragment for all tabs.
- Use individual fragment for every tab.
在第一种情况下,如果您正在调用 APIs 表单片段,就会出现这种问题(就像您的一样)。
在第二种情况APIs中,调用将在单独的片段中进行,不会出现此类问题。
因此,您的问题的第一个解决方案是为每个选项卡使用单独的片段。
如果真的想为每个选项卡使用单个片段,则维护 API 调用每个选项卡片段的每个实例的顺序。
正如您在片段中所做的那样:
if (activity != null) {
service = activity.getService();
activity.setVisibleFragment(this);
}
moviesRv = rootView.findViewById(R.id.movies_list);
moviesRv.setLayoutManager(new LinearLayoutManager(getContext()));
this.update(service, false);
在这种情况下,您正在调用服务,然后您正在阅读设置视图。
场景是这里的 API 调用将在后台执行,但 API 调用下面的代码将执行。因此,如果 API 任何片段的响应到来,那么该片段视图将被填充。因此,该场景的解决方案是将 API 调用方法放在片段中,然后调用 APIs 并保持调用。
如果有任何帮助只是评论。谢谢。
我认为接受的答案不是很清楚,所以对于以后遇到这个问题的任何人,这就是我所做的。我从 activity 的 on create 方法调用我的 REST API 托管片段和 viewpager 并通过创建片段 [=15] 的 6 个实例为 6 个选项卡使用单个片段 class =].但这里的问题是,不要在 onCreate 中设置 viewpager,而是在 API 调用收到成功响应后,在数据已保存在某个对象内后设置它。因此,现在数据已准备好在首次呈现时显示在片段中。
您应该将此代码添加到您的片段之一。
Handler().postDelayed({
//api call
}, 3000)
这样当您使用 viewpager 时,两个片段不能同时 api 调用。
我有一个导航抽屉 activity,其中一个片段具有视图分页器和选项卡。所有 4 个片段都从服务器获取数据。我的问题是视图寻呼机正在加载前 2 个片段,因此我的第一个片段一开始没有显示内容,因为其余片段 api 的延迟。因此,在解析和显示第一个片段中的数据之前,将创建并显示第二个片段。我该如何解决?
这是我的片段容器
public class FragmentMoviesContainer extends KFragment {
private MainActivity activity;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies_container, container, false);
activity = (MainActivity) getActivity();
assert activity != null;
activity.setVisibleFragment(this);
SectionsPagerAdapter mSectionsPagerAdapter = new SectionsPagerAdapter(getChildFragmentManager());
// Set up the ViewPager with the sections adapter.
ViewPager mViewPager = rootView.findViewById(R.id.container);
TabLayout tabLayout = rootView.findViewById(R.id.tabs);
mViewPager.setAdapter(mSectionsPagerAdapter);
tabLayout.setupWithViewPager(mViewPager);
return rootView;
}
@Override
public void onResume() {
super.onResume();
ActionBar actionBar = activity.getSupportActionBar();
if (actionBar != null)
actionBar.setTitle(R.string.movies);
activity.getNavigationView().setCheckedItem(R.id.nav_movies);
activity.setElevation(true);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return replaceFragmentMovies(Constants.STRINGS.UPCOMING);
case 1:
return replaceFragmentMovies(Constants.STRINGS.NOW_PLAYING);
case 2:
return replaceFragmentMovies(Constants.STRINGS.POPULAR);
case 3:
return replaceFragmentMovies(Constants.STRINGS.TOP_RATED);
default:
return null;
}
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getString(R.string.coming_soon);
case 1:
return getString(R.string.now_playing);
case 2:
return getString(R.string.popular);
case 3:
return getString(R.string.top_rated);
default:
return "";
}
}
@Override
public int getCount() {
return 4;
}
private FragmentMovies replaceFragmentMovies(String type) {
FragmentMovies fragmentMovies = new FragmentMovies();
fragmentMovies.setType(type);
return fragmentMovies;
}
}
@Override
public void serviceResponse(int responseID, List<KObject> objects) {
}
@Override
public void update(ModelService service, boolean reload) {
}
}
这是我在选项卡中显示的片段
public class FragmentMovies extends KFragment implements MoviesAdapter.OnLoadMoreListener {
private MainActivity activity;
private ModelService service;
private RecyclerView moviesRv;
private String type;
public void setType(String type) {
this.type = type;
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies, container, false);
activity = (MainActivity) getActivity();
if (activity != null) {
service = activity.getService();
activity.setVisibleFragment(this);
}
moviesRv = rootView.findViewById(R.id.movies_list);
moviesRv.setLayoutManager(new LinearLayoutManager(getContext()));
this.update(service, false);
return rootView;
}
@Override
public void serviceResponse(int responseID, List<KObject> objects) {
if ((objects != null && !objects.isEmpty()) && (responseID == Constants.UPCOMING || responseID == Constants.NOW_PLAYING || responseID == Constants.POPULAR
|| responseID == Constants.TOP_RATED)) {
Section section = (Section) objects.get(0);
MovieListAdapter adapter = new MovieListAdapter(getContext(), section.getMovieList());
moviesRv.setAdapter(adapter);
}
}
@Override
public void update(final ModelService service, final boolean reload) {
boolean hasConnection = Connection.isNetworkAvailable(getContext());
if (hasConnection && service != null) {
final int responseId = getResponseID();
service.getMovies(type, "", false, responseId, reload);
} else {
// progressBar.setVisibility(View.GONE);
DialogHelper.noConnectionDialog(getContext());
}
}
private int getResponseID() {
switch (type) {
case Constants.STRINGS.UPCOMING:
return Constants.UPCOMING;
case Constants.STRINGS.NOW_PLAYING:
return Constants.NOW_PLAYING;
case Constants.STRINGS.POPULAR:
return Constants.POPULAR;
case Constants.STRINGS.TOP_RATED:
return Constants.TOP_RATED;
default:
return 0;
}
}
@Override
public void onLoadMore(MoviesAdapter adapter) {
}
@Override
public void onResume() {
super.onResume();
if (activity.getSupportActionBar() != null)
activity.getSupportActionBar().setTitle("Movies");
activity.getNavigationView().setCheckedItem(R.id.nav_movies);
activity.setElevation(true);
activity.getAddFab().hide();
}
@Override
public void onDestroy() {
super.onDestroy();
}
}
方法 update 调用其余 api url 并获取数据。这是我基于 AsyncTask 创建的框架。然后对象列表返回到在我创建适配器并显示数据的方法 onServiceResponse 中解析的片段。问题是第二个片段是在第一个片段的 onServiceResponse 方法之前创建的。
您应该从第一个片段进行 api 调用,在获得结果后您应该进行其余的调用。如果您需要有关代码的任何帮助,请告诉我。我认为这应该是直截了当的。
查看您的代码后,有两件事可以将片段膨胀到选项卡上。
- Use single Fragment for all tabs.
- Use individual fragment for every tab.
在第一种情况下,如果您正在调用 APIs 表单片段,就会出现这种问题(就像您的一样)。
在第二种情况APIs中,调用将在单独的片段中进行,不会出现此类问题。
因此,您的问题的第一个解决方案是为每个选项卡使用单独的片段。
如果真的想为每个选项卡使用单个片段,则维护 API 调用每个选项卡片段的每个实例的顺序。
正如您在片段中所做的那样:
if (activity != null) {
service = activity.getService();
activity.setVisibleFragment(this);
}
moviesRv = rootView.findViewById(R.id.movies_list);
moviesRv.setLayoutManager(new LinearLayoutManager(getContext()));
this.update(service, false);
在这种情况下,您正在调用服务,然后您正在阅读设置视图。
场景是这里的 API 调用将在后台执行,但 API 调用下面的代码将执行。因此,如果 API 任何片段的响应到来,那么该片段视图将被填充。因此,该场景的解决方案是将 API 调用方法放在片段中,然后调用 APIs 并保持调用。
如果有任何帮助只是评论。谢谢。
我认为接受的答案不是很清楚,所以对于以后遇到这个问题的任何人,这就是我所做的。我从 activity 的 on create 方法调用我的 REST API 托管片段和 viewpager 并通过创建片段 [=15] 的 6 个实例为 6 个选项卡使用单个片段 class =].但这里的问题是,不要在 onCreate 中设置 viewpager,而是在 API 调用收到成功响应后,在数据已保存在某个对象内后设置它。因此,现在数据已准备好在首次呈现时显示在片段中。
您应该将此代码添加到您的片段之一。
Handler().postDelayed({
//api call
}, 3000)
这样当您使用 viewpager 时,两个片段不能同时 api 调用。