8

Вопрос по android-viewpager, android – FragmentPagerAdapter с ViewPager и двумя фрагментами. Перейти к первому из второго и обновить первый текст

Я не знаком сFragmentPagerAdapterтак что это будет один из тех вопросов, которые мы (вы) читаем в описании критически.

Structure: у меня естьFragmentPagerAdapter (код ниже), который будет содержать два фрагмента за раз. Первый отображает выдержки из книг, а второй - список названий книг.

Goal: Я хочу добиться того, что описано в заголовке: пользователь может перейти ко второму фрагменту в пейджере, щелкнуть заголовок, а затем я хочу переместить пользователя обратно к первому фрагменту и указать первому фрагменту обновить текст , Первый фрагмент имеетtriggerRefresh метод для этого.

Code: Я считаю, что моя проблема происходит из-за способаFragmentPagerAdapter повторно использует / создает фрагменты (которые я не понимаю). Это мой класс:

static class MyFragmentPagerAdapter extends FragmentPagerAdapter {

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

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

    @Override
    public Fragment getItem(int position) {
        switch(position) {
        case 0:
            return new ExcerptsFragment();
        case 1:
            return new BookListFragment();
        default:
            throw new IllegalArgumentException("not this many fragments: " + position);
        }
    }
}

Вот как я создал соответствующих участников:

ViewPager mViewPager = (ViewPager) findViewById(R.id.pager);
MyFragmentPagerAdapter mFragmentPagerAdapter = new MyFragmentPagerAdapter(getSupportFragmentManager());
mViewPager.setAdapter(mFragmentPagerAdapter);

И это то, что я пробовал в другом месте в своей деятельности, когда я получал обратный вызов из названий книг Фрагмент с выбранным названием:

mViewPager.setCurrentItem(0); // back to excerpts screen page. It's OK.
// Here's the problem! How to identify the fragment 0 
// to ExcerptsFragment and call its triggerRefresh()?!?

Series of problems:

Вызов адаптераgetView() не будет работать, потому что он вернет новый экземплярExcerptsFragment, который в данный момент не прикреплен (как и ожидалось, выдает исключение).

Я видел много людей здесь (пример) просто храню фрагменты вgetView(), Это правильно? Потому что, глядя на официальные примеры, мне кажется, что это анти-шаблон (победить автоматическую ссылку, удерживая предметы). И это тоже мнениеВот а такжеВот (и смотрит прямо на меня).

Какие-либо предложения? Я не удивлюсь, если не пойму всего этого ...

  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceeded

    от davidcesarino
  • Error: User Rate Limit ExceededinstantiateItemError: User Rate Limit Exceeded

    от
  • Error: User Rate Limit ExceededwillError: User Rate Limit Exceeded

    от davidcesarino
  • Error: User Rate Limit Exceeded

    от
  • Error: User Rate Limit Exceededstackoverflow.com/questions/14035090/…

    от
  • 0

    Я решил эту проблему

    используя WeakReferences для фрагментов при создании. Увидеть :https://stackoverflow.com/a/23843743/734151

    Если вы нашли что-то не так с этим подходом, пожалуйста, прокомментируйте.

  • 7

    Отказ от ответственности

    Although this had worked perfectly fine for me before, you should be aware of the classic pitfalls of depending on internal, private behavior. While I wrote tests that would eventually warn me if the internal implementation changed, I have since moved on to зеленые пастбища, И ты должен тоже. Таким образом, ценность этого вопроса и его ответ являются только историческими, на мой взгляд.

    Извините за этот вопрос, я думаю, что это был час.

    Чтобы решить эту проблему, я реализовалэто решение как есть. Кажется, работает просто отлично. Итак, я полагаю, что это был просто вопрос поиска (в настоящее время присоединенного) экземпляра фрагмента путем выяснения, как называется его Id. Ссылка выше объясняет, как это сделано.

    Я решил ответить на свой вопрос вместо того, чтобы удалять его, потому что я полагаю, что новички, подобные мне на этих пейджерах, извлекут выгоду из «сценария реального случая». Большинство ответов, которые я видел, больше всего говорят о теории, которая является правильным путем, кстати ... но без реального примера работы с такими людьми, как я, теряются.

    Во всяком случае, вот последний кусок кода, который мне нужен (прокомментированная часть выше):

    int n = 0;
    mViewPager.setCurrentItem(n); // in the question I had stopped here.
    
    ExcerptsFragment f = (ExcerptsFragment) ContainerActivity.this
            .getSupportFragmentManager().findFragmentByTag(getFragmentTag(n));
    f.triggerRefresh();
    
    // ... below the helper method: used the solution from the link.
    
    private String getFragmentTag(int pos){
        return "android:switcher:"+R.id.pager+":"+pos;
    }
    

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

    Of course, if you have something to add, to show us, to tell what is wrong in doing it or what can be improved, I'll be glad to hear from you.

  • 2

    Я сам некоторое время искал решение этой проблемы. Ваш подход в принци

    пе работает, но он сломает ваш код, если когда-либо изменится код создания тега фрагмента в реализации базового класса Android. Это довольно неприятная зависимость!

    Более элегантным подходом было бы перевернуть проблему и сохранить экземпляр вашей базовой активности в своем фрагменте. Реализуйте установщик для тега в своей деятельности и вызывайте его внутри фрагмента при создании - тег там просто доступен с помощью getTag ().

    Пример реализации можно найтиВот.