最近,在使用ViewPager和FragmentPagerAdapter时遇到如下问题(为了说明问题先上图):
图一
图二
功能描述:该页面为ViewPager的实现,且一共有两个Fragment:Fragment01与Fragment03;左右滑动可实现Fragment01与Fragment03的切换。现有需求:
点击button01与button02可进行Fragment01与Fragment02的替换,即Fragment03不会发生变化,只在原Fragment01上进行UI的替换。
其效果为图一与图三的切换。
图三
实现代码(注意里面的注释):
1.MainActivity 用到了xutils3中的注解
public class MainActivity extends AppCompatActivity {
private int buttonClickTime = 0 ;
@ViewInject (R.id.button)
private Button button;
@ViewInject (R.id.turn01_bn)
private Button turn01_bn;
@ViewInject (R.id.turn02_bn)
private Button turn02_bn;
@ViewInject (R.id.viewPager)
private ViewPager viewPager;
private MyViewPagerAdapter adapter;
@Event (value = {R.id.button, R.id.turn01_bn, R.id.turn02_bn}, type = View.OnClickListener.class)
private void buttonOnClickListener (View v) {
switch (v.getId()) {
case R.id.turn01_bn:
adapter.button01IsClicked = true ;
adapter.notifyDataSetChanged();
break ;
case R.id.turn02_bn:
adapter.button02IsClicked = true ;
adapter.notifyDataSetChanged();
break ;
}
}
@Override
protected void onCreate (Bundle savedInstanceState) {
super .onCreate(savedInstanceState);
x.view().inject(this );
initView();
}
private void initView () {
adapter = new MyViewPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled (int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected (int position) {
if (position == 1 ){
turn01_bn.setVisibility(View.GONE);
turn02_bn.setVisibility(View.GONE);
}else {
turn01_bn.setVisibility(View.VISIBLE);
turn02_bn.setVisibility(View.VISIBLE);
}
}
@Override
public void onPageScrollStateChanged (int state) {
}
}
);
}
}
运行后你会发现adapter.notifyDataSetChanged()并不能进行当前页面的更新(这里的更新是根据button01IsClicked 和button02IsClicked返回不同的Fragment)。这是由FragmentPagerAdapter的缓存机制造成的;具体原因如下:调用adapter.notifyDataSetChanged()方法后adapter会调用getItemPosition(),getItemPosition()会根据当前Fragment判断是否在缓存中,如果是直接从缓存中获取Fragment,否则会调用instantiateItem(ViewGroup container, int position)这个方法。所以,为了实现同一位置的Fragment,必须复写这两个方法,具体代码如下:
2.MyViewPagerAdapter
public class MyViewPagerAdapter extends FragmentPagerAdapter {
private android.support.v4.app.FragmentManager fm;
public List<Fragment> list;
private Test02Fragment fr02;
public boolean button01IsClicked = false ;
public boolean button02IsClicked = false ;
public MyViewPagerAdapter (android.support.v4.app.FragmentManager fm) {
super (fm);
this .fm = fm;
list = new ArrayList<Fragment>();
list.add(new Test01Fragment());
list.add(new Test03Fragment());
fr02 = new Test02Fragment();
}
@Override
public int getCount () {
return list.size();
}
@Override
public Fragment getItem (int position) {
return list.get(position);
}
@Override
public int getItemPosition (Object object) {
if (object.getClass().getName().contains("Test01Fragment" ) || object.getClass().getName().contains("Test02Fragment" )) {
return POSITION_NONE;
} else {
return super .getItemPosition(object);
}
}
@Override
public Object instantiateItem (ViewGroup container, int position) {
Fragment fragment = (Fragment) super .instantiateItem(container,
position);
boolean isTwo = fragment.getClass().getName().contains("Test02Fragment" );
String fragmentTag = fragment.getTag();
if (position == 0 ) {
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
if (button01IsClicked && isTwo) {
ft.remove(fragment);
fragment = list.get(0 );
ft.add(container.getId(), fragment, fragmentTag);
ft.attach(fragment);
ft.commit();
}
if (button02IsClicked && !isTwo) {
ft.remove(fragment);
fragment = fr02;
ft.add(container.getId(), fragment, fragmentTag);
ft.attach(fragment);
ft.commit();
}
}
button01IsClicked = false ;
button02IsClicked = false ;
return fragment;
}
}
到这里就可以实现点击按钮替换Fragment了
demo地址:http://download.csdn.net/detail/niuzhucedenglu/9461414
参考资料:
http://my.oschina.net/8048/blog/531070?fromerr=x6bUiu15
http://blog.csdn.net/zmldlut/article/details/17689011
http://blog.sina.com.cn/s/blog_783ede03010173b4.html
http://blog.csdn.net/dreamzml/article/details/9951577
http://www.blog4app.com/?p=62
http://www.tuicool.com/articles/eua2mm
http://blog.csdn.net/dreamzml/article/details/9951577