Обновите изображения на FragmentStatePagerAdapter при возобновлении активности

Я создал действие, которое использует FragmentStatePagerAdapter для предоставления небольшой галереи. Однако я не могу заставить его обновляться, когда активность возобновляется (например, после возвращения из другой активности). Каждый раз, когда первые два снимка будут пустыми, и только после того, как я проведу два снимка в сторону, они будут освежены. Ни один из ответов, которые я нашел, не работает (особенно переопределение getItemPosition() )

Я настроил это так:

 mPagerAdapter = new PhotosPagerAdapter(getSupportFragmentManager()); mPager = (ViewPager) findViewById(R.id.photosViewPager); mPager.setAdapter(mPagerAdapter); 

Тогда у меня есть класс FragmentStatePagerAdapter:

 private class PhotosPagerAdapter extends FragmentStatePagerAdapter{ public PhotosPagerAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return photos.size(); } @Override public Fragment getItem(int position) { ImageFragment f = new ImageFragment(position); return f; } @Override public int getItemPosition(Object object) { throw new RuntimeException(); //return POSITION_NONE; } } 

Как вы, вероятно, заметили, я выбрал RuntimeException в getItemPosition, потому что я хотел проверить, когда он вызван. И он не вызывается, пока я не добавлю что-то в список, содержащий мои фотографии. Затем класс ImageFragment:

 public class ImageFragment extends Fragment{ int position; Bitmap mBitmap; int width; int height; ImageView img; public ImageFragment(){ } public ImageFragment(int position){ this.position = position; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { img = new ImageView(container.getContext()); img.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); width = container.getWidth(); height = container.getHeight(); loadBitmap(); return img; } public void loadBitmap(){ if (img == null){ return; } final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(photos.get(position), options); options.inSampleSize = calculateInSampleSize(options, width/2, height/2); options.inJustDecodeBounds = false; mBitmap = BitmapFactory .decodeFile(photos.get(position), options); img.setImageBitmap(mBitmap); } @Override public void onDestroyView() { mBitmap.recycle(); super.onDestroyView(); } } 

Код выглядит бесполезным после того, как я попытался его исправить … Но: удаление onDestroyView() не работает. Я поместил mPagerAdapter.notifyDataSetChanged() в несколько мест, которые должны быть вызваны (например, onResume() ), без результата. Я получаю от этого отчаяние.

Работа с адаптерами пейджера фрагментов может быть PITA.

Вот несколько полезных советов:

ViewPager PagerAdapter не обновляет вид

Обновлять ViewPager динамически?

Вообще говоря, это работает 99% времени …

Переопределите getItemPosition в своем PagerAdapter следующим образом:

 @Override public int getItemPosition(Object object) { return POSITION_NONE; } 

Иногда даже те не работают, я должен использовать метод «грубой силы» и снова воссоздать весь вид (начиная с onCreate) …

У меня была такая же проблема, как и у вас, после некоторых исследований я создал хороший сценарий, который не позволяет воссоздавать фрагменты, которые уже существуют, но в то же время позволяет вам обновлять все видимые / инициированные фрагменты.

 import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.view.ViewGroup; import java.util.WeakHashMap; /** * Created by TheCobra on 9/17/15. */ public abstract class FragmentAdvanceStatePagerAdapter extends FragmentStatePagerAdapter { private WeakHashMap<Integer, Fragment> mFragments; public FragmentAdvanceStatePagerAdapter(FragmentManager fm) { super(fm); mFragments = new WeakHashMap<Integer, Fragment>(); } @Override public Fragment getItem(int position) { Fragment item = getFragmentItem(position); mFragments.put(Integer.valueOf(position), item); return item; } @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); Integer key = Integer.valueOf(position); if (mFragments.containsKey(key)) { mFragments.remove(key); } } @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); for (Integer position : mFragments.keySet()) { //Make sure we only update fragments that should be seen if (position != null && mFragments.get(position) != null && position.intValue() < getCount()) { updateFragmentItem(position, mFragments.get(position)); } } } @Override public int getItemPosition(Object object) { //If the object is a fragment, check to see if we have it in the hashmap if (object instanceof Fragment) { int position = findFragmentPositionHashMap((Fragment) object); //If fragment found in the hashmap check if it should be shown if (position >= 0) { //Return POSITION_NONE if it shouldn't be display return (position >= getCount()? POSITION_NONE : position); } } return super.getItemPosition(object); } /** * Find the location of a fragment in the hashmap if it being view * @param object the Fragment we want to check for * @return the position if found else -1 */ protected int findFragmentPositionHashMap(Fragment object) { for (Integer position : mFragments.keySet()) { if (position != null && mFragments.get(position) != null && mFragments.get(position) == object) { return position; } } return -1; } public abstract Fragment getFragmentItem(int position); public abstract void updateFragmentItem(int position, Fragment fragment); } 

Скопируйте этот код в имя файла «FragmentAdvanceStatePagerAdapter.java». Теперь в вашем адаптере, простирайтесь от этого и переопределите «getFragmentItem ()» и «updateFragmentItem ()». Всякий раз, когда вы вызываете notifydatachange (), updateFragmentItem () будет вызываться со всем уже созданным фрагментом. Когда адаптеру необходимо создать новый фрагмент, будет вызван getFragmentItem ().

Надеюсь, что сэкономить и помочь многим людям 🙂

Удачи и счастливого программирования !!!

PS ваш адаптер «getItem ()» должен быть «getFragmentItem ()», если вы используете этот класс.

Вместо того, чтобы снова возвращать POSITION_NONE и создавать все фрагменты, вы можете сделать так, как я предложил здесь: обновить ViewPager динамически?

Никогда не используйте POSITION_NONE

 if(fragmentManager.getFragments().contains(object)) return POSITION_NONE; else return POSITION_UNCHANGED; 

Для исключения Fatal Exception: java.lang.IllegalStateException Fragment {} в настоящее время отсутствует в FragmentManager