обновление фрагментов в ViewPager

у меня проблемы с попыткой обновить/заменить фрагменты в ViewPager. проблема в том, что старые фрагменты просто не заменятся новыми. Я прочитал пару решений в stackoverflow и попробовал их, но это все равно не работает. у кого-нибудь есть идеи, почему? я объясню, что я пытаюсь сделать ниже.

у меня есть класс Pojo

public class Pojo {
 public String text;
 public Pojo(String text) { this.text = text; }
}

у меня есть групповой класс, PojoGroup

public class PojoGroup {
 public String title;
 public List<Pojo> pojos;
 public PojoGroup(String title, List<Pojo> pojos) {
  this.title = title;
  this.pojos = pojos;
 }
}

идея в том, что я привяжу PojoGroup к фрагменту. XML фрагмента pojogroup_frag.xml выглядит следующим образом. как видите, я установлю для tvTitle значение PojoGroup.title и привяжу список Pojo к ListView.

<LinearLayout xmlns:android="..."
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">
 <TextView android:id="@+id/tvTitle" android:layout_width="..." android_layout_height="..."/>
 <ListView android:id="@+id/listView" android:layout_width="..." android_layout_height="..."/>
</LinearLayout>

для полноты, вот мой адаптер pojo для привязки списка pojo к ListView.

public class PojoAdapter extends ArrayAdapter<Pojo> {
 public PojoAdapter(Context ctx, int resId, List<Pojo> objects) {
  super(ctx, resId, objects);
 }
 public View getView(int pos, View convertView, ViewGroup parent) {
  View v = convertView;
  if(null == v) {
    Context ctx = getContext();
    LayoutInflater vi = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    v = vi.inflat(R.layout.pojo_row, null);
  }
  TextView tv = (TextView)v.findViewById(R.id.tvText);
  Pojo pojo = getItem(pos);
  tv.setText(pojo.text);
 }
}

мой файл pojo_row.xml выглядит следующим образом.

<LinearLayout xmlns:android="..."
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical">
 <TextView android:id="@+id/tvText" android:layout_width="..." android_layout_height="..."/>
</LinearLayout>

мой main.xml имеет кнопку и ViewPager. мой класс MainActivity выглядит следующим образом.

public class MainActivity extends FragmentActivity {
 PojoGroupPagerAdapter pagerAdapter;
 ViewPager viewPager;

 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  Button b = (Button)findViewById(R.id.bReplace);
  b.setOnClickListener(new View.OnClickListener() {
   public void onClick(View v) { generateAndReplaceFrags(); }
  });

  pagerAdapter = new PojoGroupPagerAdapter(getSupportFragmentManager());
  viewPager = (ViewPager)findViewById(R.id.pager);
  viewPager.setAdapter(pagerAdapter);
 }

 void generateAndReplaceFrags() {
  //PojoGroupFactory just generates a random List of PojoGroups
  List<PojoGroup> groups = PojoGroupFactory.getPojoGroups();
  pagerAdater.setPojoGroups(groups);
 }
}

мой фрагмент pojo, PojoFrag, выглядит следующим образом.

public class PojoFrag extends Fragment {
 PojoGroup pojoGroup;
 View view;
 TextView tvTitle;
 ListView listView;

 public PojoFrag(PojoGroup group) { pojoGroup = group; }

 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  view = inflater.inflate(R.layout.pojogroup_frag, null);
  listView = (ListView)view.findViewById(R.id.listView);
  tvTitle = (TextView)view.findViewById(R.id.tvTitle);

  List<Pojo> objects = pojoGroup.getPojos();
  listView.setAdapter(new PojoAdapter(getActivity(), R.id.tvText, objects));
  tvTitle.setText(pojoGroup.title);
  return view;
 }
}

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

public class PojoGroupPagerAdapter extends FragmentPagerAdapter {
 List<PojoGroup> pojoGroups;
 Map<Integer, Fragment> fragments;

 public PojoGroupPagerAdapter(FragmentManager fm) {
  super(fm);
  fragments = new HashMap<Integer, Fragment>();
 }

 public Fragment getItem(int position) {
  Integer key = new Integer(position);
  if(fragments.containsKey(key)) {
   return fragments.get(key);
  }

  PojoGroup group = pojoGroups.get(position);
  PojoFrag frag = new PojoFrag(group);
  fragments.put(key, frag);
  return frag;
 }

 public int getCount() {
  return (null == pojoGroups) ? 0 : pojoGroups.size();
 }

 public int getItemPosition(Object object) {
  if(!fragments.containsKey(object)) 
   return POSITION_NONE;
  return POSITION_UNCHANGED;
 }

 public void setPojoGroups(List<PojoGroup> pojoGroups) {
  this.pojoGroups = pojoGroups;
  fragments.clear();
  int total = pojoGroups.size();
  for(int i=0; i < total; i++) {
   Integer key = new Integer(i);
   PojoGroup group = pojoGroups.get(i);
   PojoFrag frag = new PojoFrag(group);
   fragments.put(key, frag);
  }
  notifyDataSetChanged();
 }
}

как видите, я переопределил метод getItemPosition(Object), но это все равно не помогает заменить старое представление новым. я также играл с FragmentTransaction, но это тоже не работает. я пытаюсь создать новый объект ViewPager и добавить его в основной вид. однако я получаю какое-то странное исключение (вероятно, потому, что я понятия не имею, как построить AttributeSet).

любая помощь с этой проблемой приветствуется.

вот ссылка на демонстрационный проект: http://www.box.com/s/xbtm3amtkj7f13j2llm4


person Jane Wayne    schedule 23.02.2012    source источник
comment
есть идеи? мне действительно нужна помощь.   -  person Jane Wayne    schedule 06.03.2012


Ответы (1)


хорошо, давайте посмотрим мой FragmentPagerAdapter

public class StudentPagerAdapter extends FragmentStatePagerAdapter {

    private List<Fragment> listFragments;

    public StudentPagerAdapter(FragmentManager fm, List<Fragment> _listFragments) {
        super(fm);
        this.listFragments = _listFragments;
    }

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

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

    @Override
    public CharSequence getPageTitle(int position) {
        return "Page " + (position + 1);
    }
}

ViewPager имеет viewPagerAdapter, в данном случае это ваш класс PojoGroupPagerAdapter
PojoGroupPagerAdapter имеет много фрагментов (это ваш класс PojoFrag), viewPager каждый раз отображает 1 фрагмент.
поэтому при нажатии кнопки вы должны вызывать

    int currentItem = viewPageAdapter.getCurrentItem()//current frangment
    PojoGroupPagerAdapter adapter = (PojoGroupPagerAdapter ) viewPagerApdater.getAdapter();
PojoFrag pojoFrag = adapter.getItem(currentItem)

вы можете использовать pojoFrag, чтобы получить заданное значение для фрагмента, когда закончите, вы должны позвонить

viewPagerAdapter.notifyDataSetChanged()//or adapter of current fragment
person nebula    schedule 21.06.2013