由于休息api延迟,视图寻呼机中的第一个片段未显示

时间:2018-01-23 09:11:29

标签: android rest android-viewpager android-tabs android-networking

我有一个导航抽屉活动,其中一个片段有一个视图寻呼机和标签。所有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();
}
}

方法更新调用其余的api url并获取数据。这是我基于AsyncTask创建的框架。然后将对象列表返回到onServiceResponse方法中解析的片段,我在其中创建适配器并显示数据。问题是第二个片段是在第一个片段的onServiceResponse方法之前创建的。

4 个答案:

答案 0 :(得分:0)

您应该从第一个片段进行api调用,在获得结果后,您应该进行其余的调用。如果您需要任何代码帮助,请告诉我们。我认为这应该是直截了当的。

答案 1 :(得分:0)

查看代码后,有两件事可以将片段扩展到标签页。

  
      
  1. 对所有标签使用单个片段。
  2.   
  3. 为每个标签使用单个片段。
  4.   

在第一种情况下,如果您正在调用API表单片段,则会出现这种问题(与您的一样)。

在第二种情况下的API中,调用将是单独的片段,并且不会出现这种问题 因此,问题的第一个解决方案是为每个选项卡使用单个片段。 如果真的想为每个选项卡使用单个片段,那么为每个选项卡维护片段的每个实例的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调用方法置于片段中,然后调用API并维护调用 如果有任何帮助只是评论。感谢。

答案 2 :(得分:0)

我认为接受的答案不是很解释,因此对于以后遇到此问题的任何人,这就是我所做的。我正在通过托管片段和viewpager的活动的on create方法调用REST API,并通过创建6个fragment class实例来为6个选项卡使用单个片段class。但是这里要注意的是,不要在onCreate中设置viewpager,而是在将数据保存在某个对象中之后,在API调用收到成功响应之后进行设置。因此,现在数据准备好在首次呈现时显示在片段中。

答案 3 :(得分:0)

您应该将此代码添加到您的片段中。

Handler().postDelayed({

//api call 

}, 3000)

使用Viewpager时,两个片段不能同时进行api调用。