1

У меня есть приложение с tabhost и viewpager. У меня есть одна вкладка, фрагмент фиксированный. Мне нужно добавить вкладку, фрагменты динамически по щелчку переключателя в радиогруппе из первого фрагмента.android viewpager с фрагментами с использованием FragmentPageAdapter dynamic add, remove

MyPagerAdapter класс:

import java.util.ArrayList; 
import java.util.List; 
import android.support.v4.app.Fragment; 
import android.support.v4.app.FragmentManager; 
import android.support.v4.app.FragmentPagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.view.View; 
import android.view.ViewGroup; 

public class MyViewPageAdapter extends FragmentPagerAdapter { 

    private List<Fragment> fragments = new ArrayList<Fragment>(); 
    FragmentManager fm; 

    public List<Fragment> getFragments() { 
     return fragments; 
    } 

    public void setFragments(List<Fragment> fragments) { 
     this.fragments = fragments; 
    } 

    public MyViewPageAdapter(FragmentManager fm, List<Fragment> fragments) { 
     super(fm); 
     this.fm = fm; 
     this.fragments = fragments; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return fragments.get(position); 
    } 

    @Override 
    public int getCount() { 
     return fragments.size(); 
    } 

    public void addFragment(Fragment fragment) { 
     this.fragments.add(fragment); 
     notifyDataSetChanged(); 
    } 

    public void removeFragments() { 
     try { 
      List<Fragment> newList = new ArrayList<Fragment>(); 
      Fragment general = fragments.get(0); 
      newList.add(general);   
      this.fragments.clear(); 
      this.fragments = new ArrayList<Fragment>(); 
      this.fragments = newList; 
      notifyDataSetChanged(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    public void removeItemFromFrament(ViewGroup container, int position, Object object) { 
     try { 
      try { 
       container.removeViewAt(position); 
       ((ViewPager) container).setCurrentItem(position - 1);    
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
      notifyDataSetChanged(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

MyPagerFragment класс:

import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 

public class MyViewPageFragment extends Fragment { 

    private static View mView; 

    public static final MyViewPageFragment newInstance(int layoutId) { 
     MyViewPageFragment f = new MyViewPageFragment(); 
     Bundle b = new Bundle(); 
     b.putInt("layout", layoutId); 
     f.setArguments(b); 
     return f; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     int layout = getArguments().getInt("layout"); 
     try { 
      mView = inflater.inflate(layout, container, false); 
     } catch (Exception e) { 
     } 
     return mView; 
    } 

} 

Im пытается добавить фрагменты к адаптеру, как это:

Fragment fragment = MyViewPageFragment.newInstance(R.layout.tab_content_layout); 
((MyViewPageAdapter) mViewPager.getAdapter()).addFragment(fragment); 

Моя проблема: В первый раз , страницы добавляются должным образом , после удаления всех представлений (кроме первого фрагмента) и попытки добавить другой набор вкладок, фрагменты не видны, а getSupportFragmentmanager.getFragments(). size() неверен.

Я попытался удалить точку из ViewPager с менеджером фрагмента

FragmentManager manager = ((Fragment) object).getFragmentManager(); 
FragmentTransaction trans = manager.beginTransaction(); 
trans.remove((Fragment) object); 
trans.commit(); 

После добавления вкладки, фрагменты на pagescrolled в getSupportFragmentManager(). GetFragments.get (arg0) возвращает нуль.

Примечание: я должен поддерживать состояние первого фрагмента, так и FragmentStatePagerAdapter getItemPosition возвращение POSITION_NONE не является приемлемым.

+0

Вы думаете, что это.fragments.clear(); this.fragments = new ArrayList (); this.fragments = newList; 'правильно? Что вам здесь нужно? – SilentKnight

+0

Да, я должен поддерживать первый фрагмент, потому что он является статическим. Поэтому я получаю первый и очищаю все фрагменты и добавляю первый фрагмент в список снова – User0802

+0

можно сослаться http://blog.csdn.net/z13759561330/article/details/40737381 –

ответ

1

Таким же образом, что вы конкретно не называют removeView() на ListView от ListAdapter избавиться от предмета, вы не сразу удалить Fragment с FragmentManager из FragmentPagerAdapter.

Вы должны переопределить getItemPosition(), но вам нужно предоставить немного более интеллектуальную реализацию, чем просто возвращение POSITION_NONE все время.

Если ваш первый фрагмент не изменяет, то всегда возвращают POSITION_UNCHANGED, когда этот фрагмент передается getItemPosition()

Думайте об этом как разговор между вами и ViewPager/FragmentPagerAdapter. Вот пример:

Вы: «Мне нужно изменить фрагменты вокруг». (звонок notifyDataSetChanged)

Адаптер: «Голова, я собираюсь изменить все вокруг». (обратный вызов startUpdate)

Адаптер: «Сколько вкладок вы хотите?» (обратный вызов getCount())

Вы: три. (возврат '3')

Адаптер: «Хорошо, что вы хотите, чтобы я сделал это с первым?» (обратный вызов getItemPosition)

Вы: «Я хочу сохранить это прямо там, где оно есть."(Возвращение POSITION_UNCHANGED)

адаптер: "Отлично, что по этому поводу второй"(обратный вызов getItemPosition)

Вы: "Я хочу, чтобы переместить его на третью вкладку"(возвращение '2')

.

адаптер: «Хорошо, что насчет третьего?» (обратный вызов getItemPosition)

Вы: «Я хочу, чтобы избавиться от этого одного полностью» (возвращение POSITION_NONE)

адаптер: «Хорошо , У меня есть пространство f или вкладку вторых, то, что фрагмент вы хотите, чтобы я использовать «(обратный вызов) getItem

Вы:„ Это один“(вернуть фрагмент для позиции == 1)

адаптер:» Я закончил меняя все, kthxbye. »(обратный вызов finishUpdate)

Возможно, у меня не было порядка звонков, но основная идея есть.

Если вам необходимо поддерживать состояние фрагментов, которые выгоняют, вы можете переопределить getItem() и destroyItem(), чтобы помочь вам в этом:

private FragmentManager mFragmentManager; 

public MyPagerAdapter(FragmentManager fm) { 
    super(fm); 
    mFragmentManager = fm; 
} 

@Override 
public Fragment getItem(int position) { 
    // figure out which fragment you want at this position 
    Fragment fragment = new MyFragment(); 
    // retrieve your savedState from wherever you put it 
    fragment.setInitialSavedState(savedState); 
    return fragment; 
} 

@Override 
public void destroyItem(ViewGroup container, int position, Object object) { 
    Fragment fragment = (Fragment) object; 
    Fragment.SavedState savedState = mFragmentManager.saveFragmentInstanceState(fragment) 
    // save your fragment state somewhere here 
    super.destroyItem(container, position, object); 
} 

Ваши фрагменты должны реализовать saveState() и restoreState() для этого к Работа.

+0

Спасибо за помощь. – User0802

+0

Мне нужно сохранить состояние вновь добавленных фрагментов, пока я не удалю его из списка фрагментов. Поскольку у меня есть edittext во фрагментах, если я возвращаю POSITION_NONE для не-первого фрагмента, я не мог получить предыдущее состояние 2-го и 3-го фрагментов. – User0802

+0

Обновлен мой ответ, чтобы включить некоторый код для сохранения/восстановления состояния фрагмента. –

0

Я пробовал аналогичное требование, как ваш, с FragmentStatePagerAdapter, который работал нормально. Может быть, это может вам помочь.

Чтобы добавить новый фрагмент:

SIZE = SIZE +1; 
adapter.instantiateItem(viewPager, SIZE-1); 
adapter.notifyDataSetChanged(); 

В GetItem(), для "позиции" создать и вернуть новый фрагмент (я использовал переключатель заявление здесь)

Обновление GetCount() метод для возврата нового SIZE.

Дайте мне знать, если вы хотите, чтобы я разделил код.