Подтвердить что ты не робот

Фрагменты ViewPager со временем уничтожаются?

Я использую пакет Android support.v4 для создания ViewPager, содержащего несколько Fragment s.

Я пытаюсь скрыть Представления, когда пользователь меняет страницу. Итак, я выполнил OnPageChangeListener для прослушивания моего адаптера и вызвал метод update() в моем Fragment, когда происходит смена страницы. Но я получаю NullPointerException, и я не могу понять, почему.

Вот код:

public class MyActivity extends FragmentActivity implements
        OnPageChangeListener {

    private static final int NUM_ITEMS = 2;
    private ViewPager mPager;
    private static SpaceAdapter mAdapter;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_pager);

        mAdapter = new SpaceAdapter(getSupportFragmentManager());
        mPager = (ViewPager) findViewById(R.id.pager);
        mPager.setAdapter(mAdapter);

        mPager.setOnPageChangeListener(this);
}

    public static class SpaceAdapter extends FragmentPagerAdapter {

        public SpaceAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public int getCount() {
            return NUM_ITEMS;
        }

        @Override
        public Fragment getItem(int position) {
            switch (position) {
            case 0:
            return new MyFragment();
            case 1:
            return new MyFragment();
            default:
            return new MyFragment();
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int arg0) {
        Log.i("pagination", "scroll state changed: " + arg0);
}

    @Override
    public void onPageScrolled(int arg0, float arg1, int arg2) {
        // Log.i("pagination", "page scroll: " + arg0 + " with: " + arg1 + ", " + arg2);
        if (mAdapter.getItem(arg0) instanceof IUpdateOnPage) {
            ((IUpdateOnPage) mAdapter.getItem(arg0)).updateOnPage();
        }
    }

    @Override
    public void onPageSelected(int arg0) {
        Log.i("pagination", "page selected: " + arg0);
    }
}

и

public class MyFragment extends Fragment implements
        SurfaceHolder.Callback, IUpdateOnPage {

    private SurfaceView charts;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.crew, null);
        bindViews(v);
        return v;
    }

    private void bindViews(View v) {
        charts = (SurfaceView) v.findViewById(R.id.civ_charts);

        charts.getHolder().addCallback(this);
        Log.i("wtf", "huh " + String.valueOf(charts == null)); // logs false
    }

    @Override
    public void updateOnPage() {
        if (charts != null) {
            Log.i("crew surface", "hidden");
            charts.setVisibility(View.GONE);
        } else {
            Log.i("crew surface", "charts is null");  //THIS HERE gets logged
        }
    }
}

wКогда я копирую/вставляю, я удалил методы SurfaceHolder.Callback, но они есть. Метод bindViews(v) регистрируется, если charts == null, и всегда возвращает false. Когда я страница вызывает updateOnPage, а charts == null возвращает true. Почему это происходит и как мне обойти это?

и это строка 108:

charts.setVisibility(View.GONE);
4b9b3361

Ответ 1

Добавьте, когда вы инициализируете свой ViewPager,

mPager.setOffscreenPageLimit(NUM_ITEMS-1);

В вашем случае это приведет к тому, что количество экранных страниц станет равным 1 (т.е. будет удерживать дополнительную экранную страницу в памяти, когда другая страница находится в фокусе). Это заставит ваш ViewPager сохранить все Fragment, даже если они не находятся в фокусе.

Ответ 2

Я просмотрел ваш код, и я думаю, проблема в том, что в onPageScrolled вы вызываете getItem. Эта реализация (которая на самом деле похожа на большинство ее реализаций в Интернете) каждый раз возвращает новый экземпляр. Однако большинство примеров, которые я видел, не называют getItem, поэтому это обычно хорошо.

В вашем случае я лениво создаю фрагмент в getItem: если он не существует для этой позиции, затем создайте его, а затем вставьте в него в ArrayList или какую-либо другую коллекцию, но если он уже существует, просто верните его из этой коллекции.

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