ViewPager non si aggiorna con FragmentStatePagerAdapter

Ho due fragments , Fragment A e Fragment B Fragment A elenca tutti i prodotti e il Fragment B mostra i dettagli sul prodotto e sulle sue immagini.

Fragment A chiama Fragment B e Fragment B recupera i dati dal servizio Web e imposta a ViewPager utilizzando Adapter . Inizialmente visualizza un'image corretta, ma in seguito ha sempre la stessa image.

  • Gradle non rioutput dopo l'aggiornamento a 3.0
  • Eccezione di null sull'applicazione di chiamata di Android
  • Come leggere dal tag NFC rilevato (messaggio NDEF). Android NFC
  • Elemento di visualizzazione non visualizzabile con divisorio visibile
  • Analizzare JSON con GSON
  • Android: Problema nell'immaginare l'image e il suo URI tra due attività
  • Se adapter.notifyDataSetChanged() da qualsiasi evento di clic nel frammento B, allora funziona perfettamente ma dobbiamo mostrare non appena il frammento B è visibile

    Si prega di guardare il codice.

      public class ImageAdapter extends FragmentStatePagerAdapter { private List<String> pImageURL; public ImageAdapter(FragmentManager fm, List<String> imageURL) { super(fm); // TODO Auto-generated constructor stub pImageURL = imageURL; Utility.showLog("PagerAdapter URL", pImageURL.toString()); } @Override public Fragment getItem(int position) { // TODO Auto-generated method stub String imageURL = pImageURL.get(position); PImageFragment imageFragment = (PImageFragment) PImageFragment.getInstance(); imageFragment.setProductImage(imageURL); return imageFragment; } @Override public int getItemPosition(Object object) { PImageFragment pFragment = (PImageFragment) object; String URL = pFragment.getProductImage(); int position = pImageURL.indexOf(URL); if (position>=0) URL = pImageURL.get(position); if (position>=0) return position; else return POSITION_NONE; } @Override public int getCount() { // TODO Auto-generated method stub return pImageURL.size(); } } 

    Frammento B

      // Image Loading Process String p_images = model.getProdutImageURL(); imageUrl = new ArrayList<String>(); if (p_images.contains(",")) imageUrl.addAll(Arrays.asList(p_images.split(","))); else imageUrl.add(p_images); mAdapter = new ImageAdapter(getChildFragmentManager(), imageUrl); vPager.setPageTransformsr(true, new DepthPageTransformsr()); vPager.setAdapter(mAdapter); mAdapter.notifyDataSetChanged(); 

    Frammento di PImage

     public class PImageFragment extends Fragment { private static final String TAG = "Product_Images_Fragment"; private View rootView; private ImageView ivProductImage; private String imageURL; @Override @Nullable public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub rootView = inflater.inflate(R.layout.p_detail_images, container, false); bindComponents(rootView); loadImages(imageURL); return rootView; } public static Fragment getInstance() { Fragment fragment = new PImageFragment(); return fragment; } public void setProductImage(String image_url) { imageURL = image_url; Utility.showLog(TAG + "Received URL : ", imageURL.toString()); } public String getProductImage() { return imageURL; } private void bindComponents(View v) { // TODO Auto-generated method stub ivProductImage = (ImageView) v.findViewById(R.id.ivProductImage); } private void loadImages(String image_url) { Utility.showLog(TAG, "http://baryapp.com/kickzexchange/assets/products/" + image_url); final ProgressBar pBar = (ProgressBar) rootView .findViewById(R.id.pBarLoader); pBar.setVisibility(View.VISIBLE); ImageLoader imgLoader = VolleySingleton.getInstance().getImageLoader(); imgLoader.get("http://baryapp.com/kickzexchange/assets/products/" + image_url, new ImageListener() { @Override public void onErrorResponse(VolleyError vError) { // TODO Auto-generated method stub Utility.showLog(TAG, vError.getLocalizedMessage() + ""); } @Override public void onResponse(ImageContainer response, boolean result) { // TODO Auto-generated method stub if (response.getBitmap() != null) { ivProductImage.setImageBitmap(response.getBitmap()); pBar.setVisibility(View.GONE); } } }); } } 

    AGGIORNARE

      // This is how fragment A calls fragment B ProductDetail pDetail = new ProductDetail(); Bundle bundle = new Bundle(); bundle.putString("product_id", productList.get(position).getProductID()); bundle.putString("product_title", productList.get(position).getProductTitle()); pDetail.setArguments(bundle); ((MyTabActivity) mActivity).navigateFragment(Utility.BUY_TAB, pDetail, true); 

    ULTIMO AGGIORNAMENTO

      public void navigateFragment(String tag, Fragment fragment, boolean shouldAdd) { FragmentManager manager = getSupportFragmentManager(); FragmentTransaction ft = manager.beginTransaction(); if (shouldAdd) mStacks.get(tag).push(fragment); // push fragment on stack if (mCurrentFragment != null) { saveFragmentState(mCurrentFragment.getClass().getName(), mCurrentFragment); } mCurrentFragment = fragment; restoreFragmentState(fragment.getClass().getName(), fragment); ft.replace(android.R.id.tabcontent, fragment); ft.commit(); } @Override protected void onSaveInstanceState(Bundle outState) { // TODO Auto-generated method stub super.onSaveInstanceState(outState); Bundle fragmentStates = new Bundle(mFragmentStates.size()); for (Map.Entry<String, Fragment.SavedState> entry : mFragmentStates.entrySet()) { fragmentStates.putParcelable(entry.getKey(), entry.getValue()); } outState.putParcelable(KEY_FRAGMENT_STATES, fragmentStates); } private void saveFragmentState(String id, Fragment fragment) { Fragment.SavedState fragmentState = getSupportFragmentManager().saveFragmentInstanceState(fragment); mFragmentStates.put(id, fragmentState); } private void restoreFragmentState(String id, Fragment fragment) { Fragment.SavedState fragmentState = mFragmentStates.remove(id); if (fragmentState != null) { if (!fragment.isAdded()) fragment.setInitialSavedState(fragmentState); } } 

    Ogni aiuto / idea è altamente apprezzato.

  • Come get la posizione della torre corrente dall'operatore di networking su android
  • Un modo ideale per impostare l'exception globale gestore in Android
  • Cordova 5.0.0 app Android non è in grado di connettersi a Internet utilizzando android 4.0.0
  • in android, anteprima della telecamera in streaming su una vista
  • rendere la mia forma in Android si alza quando apparirà la tastiera
  • android aggiungere due toolbars nella stessa attività?
  • 6 Solutions collect form web for “ViewPager non si aggiorna con FragmentStatePagerAdapter”

    È ansible utilizzare la seguente class di base PagerFragment per i tuoi frammenti e implementare il metodo onVisible se necessario:

     public abstract class PagerFragment extends Fragment { private boolean mCalled = false; private boolean mWasVisible = false; private boolean mIsResumed = false; private boolean mIsPaused = false; protected void onVisible() { mCalled = true; } protected void onHide() { mCalled = true; } /** * {@inheritDoc} * * @see android.app.Fragment#onAttach(android.app.Activity) */ @Override public void onAttach(Activity activity) { super.onAttach(activity); } /** * {@inheritDoc} * * @see android.app.Fragment#onDetach() */ @Override public void onDetach() { super.onDetach(); } /** * {@inheritDoc} * * @see android.app.Fragment#onResume() */ @Override public void onResume() { super.onResume(); mIsPaused = false; mIsResumed = true; setUserVisibleHint(getUserVisibleHint()); } /** * {@inheritDoc} * * @see android.app.Fragment#onPause() */ @Override public void onPause() { mIsPaused = true; mIsResumed = false; setUserVisibleHint(getUserVisibleHint()); super.onPause(); } /** * {@inheritDoc} * * @see android.app.Fragment#setUserVisibleHint(boolean) */ @Override public void setUserVisibleHint(boolean visible) { super.setUserVisibleHint(visible); mCalled = false; if (mIsResumed) { if (visible) { performVisible(); mWasVisible = visible; } else { performHide(); mWasVisible = visible; } } else if (mIsPaused && mWasVisible) { performHide(); mWasVisible = visible; } } private void performVisible() { onVisible(); if (!mCalled) { throw new SuperNotCalledException("PagerFragment " + this + " did not call through to super.onVisible()"); } } private void performHide() { onHide(); if (!mCalled) { throw new SuperNotCalledException("PagerFragment " + this + " did not call through to super.onHide()"); } } } 

    Oppure caricate semplicemente i dati sul Fragment A e notificate l'adattatore quando i dati sono stati caricati e quindi modificati le pagine. È sempre ansible aggiungere e rimuovere frammenti dynamicmente da un ViewPager. Quindi puoi anche provare a eliminare il frammento con i vecchi dati e crearne di nuovo.

    Non hai mostrato la parte critica, vale a dire MyTabActivity.navigateFragment() .

    Credo che si sta tentando di riutilizzare l'istanza esistente di Frammento B e di passare nuovi dati per Fragment.setArguments()

    setArguments non ha alcuna utilità dopo che viene creato il frammento

    o

    1. creare una nuova istanza del frammento B each volta e sostituire l'esistente, oppure
    2. passare i nuovi dati utilizzando funzioni personalizzate nel frammento

    Vorrei suggerire il metodo 1, perché facendo questo, i tuoi dati vengono mantenuti anche se attività ricreazione, ad esempio rotazione dello schermo. Per il metodo 2, è necessario un lavoro aggiuntivo per gestire l'attività ricreata.

    Se ti capisco correttamente, puoi provare a utilizzare l'onPageSelected e, a seconda dell'aggiornamento della posizione, i tuoi frammenti sulla pagina selezionata.

      viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { //use this to run when your fragment is visible } @Override public void onPageScrollStateChanged(int state) { } }); 

    Come si potrebbe sapere che si sta caricando l'image in un process di background. cioè utilizzando la libreria volley .

    il tuo adapter.notifyDataSetChanged() viene chiamato anche prima che il process sia terminato. Ma come ha detto quando lo chiama sul button fa clic funziona, quindi la soluzione è semplice.

    Chiamate l' adapter.notifyDataSetChanged() dopo che il process di background è completato.

    cioè dentro: –

      @Override public void onResponse(ImageContainer response, boolean result) { // TODO Auto-generated method stub if (response.getBitmap() != null) { ivProductImage.setImageBitmap(response.getBitmap()); pBar.setVisibility(View.GONE); adapter.notifyDataSetChanged(); } } }); 

    Quando si utilizza FragmentStatePagerAdapter, getItem () viene chiamato solo una volta, quindi inizialmente hai l'image corretta, ma rimane lo stesso.

    È necessario ricaricare i dati utilizzando un'interface di richiamata. Quindi, quando viene selezionato uno degli elementi nel frammento A, ricaricare i dati nel frammento B. Per questo è necessario aggiungere

     public void reloadData() { //relaod your data here } 

    Quindi creare un'interface di callback nel frammento A come questo

     public interface itemSelectedListener { void onItemSelected(View view, int position) } 

    Implementare questa interface in attività che contiene entrambi i frammenti

    in

     onItemSelected() { MyFragmentB myFragmentB = ...//get your fragment myFragmentB.reloadData(); } 

    Finalmente ho risolto la risposta. Fragment B stato salvato in navigateFragment , è stato impedito dalla seguente row e ha funzionato.

      if (mCurrentFragment != null) { if (mCurrentFragment instanceof GetProducts) saveFragmentState(mCurrentFragment.getClass().getName(), mCurrentFragment); } 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.