ViewPager не обновляется с помощью FragmentStatePagerAdapter

У меня есть два fragments : Fragment A и Fragment B Fragment A перечислены все продукты, а Fragment B показывает подробную информацию о продукте и его изображениях.

Fragment A вызывает Fragment B и Fragment B извлекает данные из веб-службы и устанавливает на ViewPager с помощью Adapter . Первоначально он отображает правильное изображение, но после этого он всегда имеет одинаковое изображение.

Если мы adapter.notifyDataSetChanged() из adapter.notifyDataSetChanged() из любого события клика в Fragment B, то он работает отлично, но мы должны отображать, как только отображается фрагмент B

Посмотрите на код.

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

Фрагмент 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.setPageTransformer(true, new DepthPageTransformer()); vPager.setAdapter(mAdapter); mAdapter.notifyDataSetChanged(); 

Фрагмент 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); } } }); } } 

ОБНОВИТЬ

  // 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); 

ПОСЛЕДНЕЕ ОБНОВЛЕНИЕ

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

Любая помощь / идея высоко ценится.

Вы можете использовать следующий базовый класс PagerFragment для своих фрагментов и при необходимости применять метод onVisible:

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

Или вы просто предварительно загружаете данные на Fragment A и уведомляете адаптер при загрузке данных, а затем изменяете их. Всегда можно добавлять и удалять фрагменты динамически из ViewPager. Таким образом, вы также можете попытаться удалить фрагмент со старыми данными и впоследствии создать новый.

Вы не показали критической части, то есть MyTabActivity.navigateFragment() .

Я считаю, что вы пытаетесь повторно использовать существующий экземпляр фрагмента B и передавать новые данные с помощью Fragment.setArguments()

SetArguments не работает после создания фрагмента

или

  1. Каждый раз создавайте новый экземпляр фрагмента B и заменяйте существующий, или
  2. Передавать новые данные с помощью пользовательских функций в фрагменте

Я бы предложил метод 1, потому что, делая это, ваши данные сохраняются даже при активном отдыхе, например, при вращении экрана. Для метода 2 вам потребуется дополнительная работа по обработке воссоздания активности.

Если я правильно вас понимаю, вы можете попробовать использовать onPageSelected и в зависимости от позиции обновить фрагменты, на которых выбрана страница.

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

Как вы знаете, вы загружаете изображение в фоновом режиме. Т.е. используя библиотеку волейбола .

Ваш adapter.notifyDataSetChanged() вызывается еще до завершения процесса. Но, как вы сказали, когда вы называете это нажатием кнопки, он работает, тогда решение прост.

После завершения фонового процесса adapter.notifyDataSetChanged() свой adapter.notifyDataSetChanged() .

Т.е. внутри: –

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

Когда вы используете FragmentStatePagerAdapter, getItem () вызывается только один раз, поэтому изначально у вас есть правильное изображение, но тогда оно остается неизменным.

Вы должны перезагрузить свои данные с помощью интерфейса обратного вызова. Поэтому, когда выбран один из элементов в вашем фрагменте A, вы перезагружаете данные в своем фрагменте B. Для этого вам нужно будет добавить

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

Затем создайте интерфейс обратного вызова в Fragment A, как это

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

Внедрить этот интерфейс в действие, которое содержит оба фрагмента

в

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

Наконец я решил ответ. Fragment B сохранялся в navigateFragment , его предотвращала следующая строка, и это сработало.

  if (mCurrentFragment != null) { if (mCurrentFragment instanceof GetProducts) saveFragmentState(mCurrentFragment.getClass().getName(), mCurrentFragment); } 
Intereting Posts
Android TransitionDrawable: изменения масштабирования изображения при возобновлении фрагмента Как разрешить ошибку «com.android.internal.R невозможно решить», когда я использую файл android MultiAutoCompleteTextView.java, Как обнаружить компиляцию с помощью android ndk в файле C / C ++? Flurry не регистрирует ничего в android Вложенная проблема RecyclerView с AppBarLayout Исключение Null Pointer, затрудняющее передачу массива с использованием ksoap Сбой с NoSuchMethodError после proguard с ссылками на методы Как установить все приложение только в портретном режиме? Android отправить видеофайл (mp4) на php-сервер Braintree с Cordova для покупок в приложении для обновления функций Блокировать прокрутку вместе с панелью Развернуть / свернуть Складную панель Эта зависимость дает мне две версии одной банки. Как это исправить? В андроиде я могу создать разные фрагменты / действия в каждой вкладке, которые сохраняются во вкладках? Android-приложение сразу после загрузки Почему INSERT и UPDATE более медленны на Android 4.0?