android - 恢复 fragment 时如何维护在ViewPager中 fragment 的onCreateView中创建的 View 实例?

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

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

这是我的代码,

主 Activity .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;
    }

}

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

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)

最佳答案

你必须做这样的事情:

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

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

关于android - 恢复 fragment 时如何维护在ViewPager中 fragment 的onCreateView中创建的 View 实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42418148/

相关文章:

android: 如何使用 FragmentStatePagerAdapter 简单的方法?

android - 单击项目重新创建相同的 ListView

android - 处理 Activity 和 Thread 之间关系的常见做法是什么

android - 我应该在 imeActionId 上放什么?

android - 不将状态栏的颜色更改为 colorPrimary

android - 无法创建平台 OpenGL 上下文

android - 方向改变时处理 SQLiteOpenHelper

Android,FragmentTabHost - 如何去除蓝色?

java - 如何通过容器 View 重新显示和恢复以前添加的 fragment

Android AsyncTask ProgressDialog轮换配置不同