如何在恢复片段时维护ViewPager中onCreateView of Fragment中创建的视图实例?

时间:2017-02-23 14:11:04

标签: android android-fragments android-asynctask android-viewpager

故事是 ViewPager 中有五个片段,每个片段在ViewPager上出现时都必须运行 AsyncTask 。我尝试与正确答案here完全相同。我将AsyncTask放在onResumeFragment中,它运行正常。但是,在AsyncTask成功运行后更新视图时,问题就开始了。因为我在更新数据集时在 onCreateView 内创建的视图(RecyclerView)是 null 。我还在setRetainInstance(true)内尝试onActivityCreated。它没有用。

这是我的代码,

MainActivity.java

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

    //Tab & Pager

    viewPager = (ViewPager) findViewById(R.id.main_tab_content);
    adapter = new ViewPagerAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapter);
    addPagerListener();
}

private void addPagerListener(){
    viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {

        @Override
        public void onPageSelected(int newPosition) {
            FragmentLifecycle fragmentToShow = (FragmentLifecycle)adapter.getItem(newPosition);
            fragmentToShow.onResumeFragment();

            FragmentLifecycle fragmentToHide = (FragmentLifecycle)adapter.getItem(currentPosition);
            fragmentToHide.onPauseFragment();

            currentPosition = newPosition;
        }

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position){
            case 0: return new HomeFragment();
            case 1: return new ArtistFragment();
            case 2: return new AlbumsFragment();
            case 3: return new CollectionsFragment();
            case 4: return new SavedFragments();
            default: return null;
        }
    }

    @Override
    public int getCount() {
        return 5;
    }

}

这是我的第二个片段代码,其余片段到目前为止都是空白的。

public class ArtistFragment extends Fragment implements FragmentLifecycle{

@BindView(R.id.recyclerview_frag_artist)
RecyclerView mRecyclerView;

RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;

@BindView(R.id.radioBtnAll_frag_artist)
RadioButton radioAll;

@BindView(R.id.radioBtnMale_frag_artist)
RadioButton radioMale;

@BindView(R.id.radioBtnFemale_frag_artist)
RadioButton radioFemale;

ArrayList<String> vocalistNameList;
Context context;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_artists, container, false);
    ButterKnife.bind(this, rootView);
    mRecyclerView.setHasFixedSize(true);
    mLayoutManager = new LinearLayoutManager(rootView.getContext());
    mRecyclerView.setLayoutManager(mLayoutManager);
    vocalistNameList = getDummyDS();
    mAdapter = new MyListAdapter(vocalistNameList);
    mRecyclerView.setAdapter(mAdapter);
    radioAll.setChecked(true);
    return rootView;
}

@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    setRetainInstance(true);
}

private ArrayList<String> getDummyDS(){
    ArrayList<String> dataset = new ArrayList<>();
    dataset.add("test");
    dataset.add("test");
    dataset.add("test");
    dataset.add("test");
    dataset.add("test");
    dataset.add("test");
    dataset.add("test");
    return dataset;
}

private void getVocalistList(Gender gender){
    RequestParams params = new RequestParams();
    params.put("action","query");
    params.put("list","allcategories");
    params.put("acprefix","Vocalist-");
    params.put("format","json");
    params.put("aclimit","5000");

    MyRestClient.get("", params, new JsonHttpResponseHandler(){
        ProgressDialog progress;
        @Override
        public void onStart() {
            progress = ProgressDialog.show(AppConstants.activity, "Please wait",
                        "Loading data..", true);
            progress.setCancelable(true);
        }

        @Override
        public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
            progress.dismiss();
            vocalistNameList = new ArrayList<String>();
            try {
                JSONArray vocalListJsonArray = response.getJSONObject("query").getJSONArray("allcategories");
                for(int i=0; i<vocalListJsonArray.length(); i++){
                    String vocalListName = vocalListJsonArray.getJSONObject(i).getString("*").replace("Vocalist-","");
                    vocalistNameList.add(vocalListName);
                }
                mAdapter = new MyListAdapter(vocalistNameList);
                mRecyclerView.setAdapter(mAdapter); // <= RecyclerView is null and app is crashing
                mAdapter.notifyDataSetChanged();
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
            progress.dismiss();
            Log.i("failure", "failed "+statusCode);
        }
    });
}

@Override
public void onPauseFragment() {
    Toast.makeText(AppConstants.applicationContext, "onPauseFragment():", Toast.LENGTH_SHORT).show();
}

@Override
public void onResumeFragment() {
    getVocalistList(Gender.All);
    Toast.makeText(AppConstants.applicationContext, "onResumeFragment(): Artist", Toast.LENGTH_SHORT).show();
}

一周以来,我一直试图解决这个问题。任何的想法? (P.S我使用Android Asynchronous Http Client代替AsyncTask

1 个答案:

答案 0 :(得分:1)

你必须做这样的事情:

pager.setOffscreenPageLimit([quantity of tabs that you would like to keep in memory]);

看看这个答案。 ViewPager inside Fragment loses content when returning to it