android android-fragments android-asynctask android-viewpager

android - ¿Cómo mantener las instancias de vista creadas en onCreateView de Fragment en ViewPager cuando se reanuda el fragmento?



android-fragments android-asynctask (2)

Finalmente obtuve la solución. Es muy sencillo.

  1. Eliminé la implementación de la interfaz FragmentLifecycle.
  2. Se agregó el siguiente método a cada fragmento.

    @Override public void setUserVisibleHint(boolean isVisibleToUser) { super.setUserVisibleHint(isVisibleToUser); if(isVisibleToUser && !isDataLoaded){ getVocalistList(Gender.All); isDataLoaded = true; } }

Funciona como magia. No necesito preocuparme por perder la instancia de RecyclerView ya que no era nula cuando se setUserVisibleHint método setUserVisibleHint .

La historia es que hay cinco fragmentos en ViewPager y cada fragmento tiene que ejecutar una AsyncTask cuando aparece en ViewPager. Estoy intentando exactamente lo mismo que la respuesta correcta aquí . Puse mi AsyncTask onResumeFragment y funciona bien. Pero el problema comienza cuando actualizo la vista después de que AsyncTask ejecute correctamente. Porque la vista (RecyclerView) que creé en onCreateView está siendo nula cuando actualizo el conjunto de datos. También probé setRetainInstance(true) dentro onActivityCreated . No funcionó.

Aquí está mi código,

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; } }

Aquí está mi código del 2 ° Fragmento, los fragmentos restantes están en blanco hasta el momento.

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(); }

He estado tratando de resolver ese problema desde hace una semana. ¿Alguna idea? (PD estoy usando Android Asynchronous Http Client en lugar de AsyncTask )