为了账号安全,请及时绑定邮箱和手机立即绑定

Viewpager+fragment+FragmentPageAdapter 数据更新问题解析

标签:
Android

Viewpager+fragment数据更新问题解析

Viewpager+fragment数据更新问题解析

解决问题:A fragment 刷新数据 B fragment 更新


 在一个 Android 应用中,我们可以使用 FragmentPageAdapter 来 处理多 Fragment 页面的横向滑动。但是当 Fragment 对应的数据集发生改变时,我们都希望能够通过调用 mAdapter.notifyDataSetChanged() 来触发 Fragment 页面使用新的数据调整或重新生成其内容,可是当我们使用 notifyDataSetChanged() 后,我们会发现这个方法不会生效。那为什么会这样呢,之前遇到了相同的问题一直没法解决,在网上给出的乱七八糟的答案感觉也不是正解,终于在今早彻底解决 了这个问题。我们先来了解下FragmentPagerAdapter的源代码。

[java] view plaincopy

@Override    
public Object instantiateItem(ViewGroup container, int position) {    
    if (mCurTransaction == null) {    
        mCurTransaction = mFragmentManager.beginTransaction();    
    }    
    
    final long itemId = getItemId(position);    
    
    // Do we already have this fragment?    
    String name = makeFragmentName(container.getId(), itemId);    
    Fragment fragment = mFragmentManager.findFragmentByTag(name);    
    if (fragment != null) {    
        if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment);    
        mCurTransaction.attach(fragment);    
    } else {    
        fragment = getItem(position);    
        if (DEBUG) Log.v(TAG, "Adding item #" + itemId + ": f=" + fragment);    
        mCurTransaction.add(container.getId(), fragment,    
                makeFragmentName(container.getId(), itemId));    
    }    
    if (fragment != mCurrentPrimaryItem) {    
        fragment.setMenuVisibility(false);    
        fragment.setUserVisibleHint(false);    
    }    
    
    return fragment;    
}


       我们特别关注下以下这句

[java] view plaincopy

String name = makeFragmentName(container.getId(), itemId);    
Fragment fragment = mFragmentManager.findFragmentByTag(name);


     根 据原代码我们可以知道系统给每一个Fragment都打上了一个标签,通过标签来寻找相应的fragment,所以当我们第二次进入fragment的时 候,fragment的oncreate,oncreateView方法都不会被调用的,因为FragmentPageAdapter中 的getitem()方法根本不会被调用,因为系统会根据标签找到相应的fragment,如果已经存在,就不会被调用,fragment有一个缓存机制 在这里。那么如果我们一定要更新fragment,那么我们又该如何处理呢,我们就可以以其人之道,还治其人之身,我们可以通过tag标签找到我们相应的 fragment,就可以对该fragment进行更新。那么我们现在就开始吧。

    我们先来定义一个list<String> tagList 来存储一下tag

[java] view plaincopy

private List<String> tagList;

    第二部重写instantiateItem方法,把fragment对应的标签存储在taglist集合里

[java] view plaincopy

public Object instantiateItem(ViewGroup container, int position) {    
    tagList.add(makeFragmentName(container.getId(), getItemId(position)));    
    return super.instantiateItem(container, position);    
}

         makeFragmentName()是FragmentPageAdapter源码里打fragment标签的方法

[java] view plaincopy

public static String makeFragmentName(int viewId, int index) {  
        return "android:switcher:" + viewId + ":" + index;  
    }

   第三步我们再adapter里自己写一个update()方法

[java] view plaincopy

public void update(int item) {  
        Fragment fragment = fm.findFragmentByTag(tagList.get(item));  
        if (fragment != null) {  
            switch (item) {  
            case 0:  
  
                break;  
            case 1:  
                ((QueryFragment) fragment).update();  
                break;  
            case 2:  
  
                break;  
            default:  
                break;  
            }  
        }  
    }


      我们可以发现在queryFragment里也有一个update()方法,这个方法呢就是接下来我们用接口回掉机制更新我们相应fragment的要使用的方法,方法里的内容根据自己的需要编译就可以了。

   好的现在万事具备只要实现fragment的数据更新问题就可以了,通过接口回掉机制来实现。

   首先我们定义一个接口,让我们的主Activity来实现


[java] view plaincopy

public interface FragmentListener {    
    
    public void onFragmentClickListener(int item);    
}

  


   之后比如我们在A Fragment 里头插入了数据,需要BFragment对该数据进行显示,那么我们现在AFragment的onAttach方法中

[java] view plaincopy

public void onAttach(Activity activity) {    
    super.onAttach(activity);    
    try {    
        listener = (FragmentListener)activity;    
    } catch (Exception e) {    
        e.printStackTrace();    
         
    }    
}

    然后对数据更新的时候,我们就在Afragment调用这个接口

[java] view plaincopy

if (listener != null) {  
   listener.onFragmentClickListener(1);  
}


   然后我们回到Activity实现该接口里的方法,更新BFragment界面

[java] view plaincopy

public void onFragmentClickListener(int item) {  
        adapter.update(item);  
        adapter.update(item);  
    }

  


   大功告成了,贴一下完整的MainAcitivity代码吧!

[java] view plaincopy

package com.example.account.main;  
  
import java.util.ArrayList;  
  
import java.util.List;  
  
import com.example.account.add.AddFragment;  
import com.example.account.query.QueryFragment;  
import com.example.account.setting.SettingFragment;  
import com.example.account.utils.PagerSlidingTabStrip;  
import com.melhc.xiji.R;  
  
import android.annotation.SuppressLint;  
import android.content.Intent;  
import android.graphics.Color;  
import android.os.Bundle;  
import android.os.Handler;  
import android.os.Message;  
import android.support.v4.app.Fragment;  
import android.support.v4.app.FragmentActivity;  
import android.support.v4.app.FragmentManager;  
import android.support.v4.app.FragmentPagerAdapter;  
  
import android.support.v4.view.ViewPager;  
  
import android.util.DisplayMetrics;  
  
import android.util.TypedValue;  
  
import android.view.KeyEvent;  
import android.view.ViewGroup;  
import android.widget.Toast;  
  
public class MainActivity extends FragmentActivity implements FragmentListener{  
    private MyPagerAdapter adapter;  
    private AddFragment addFragment;  
    private List<String> tagList;  
    private SettingFragment settingFragment;  
    private boolean isExit;  
    private QueryFragment queryFragment;  
    private ViewPager pager;  
    private PagerSlidingTabStrip tabs;  
    private FragmentManager fm;  
    private DisplayMetrics dm;  
    private List<Fragment> list;  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  
        pager = (ViewPager) findViewById(R.id.pager);  
        tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);  
        initFragment();  
        fm = getSupportFragmentManager();  
        tagList = new ArrayList<String>();  
        adapter = new MyPagerAdapter(fm);  
        pager.setAdapter(adapter);  
        tabs.setViewPager(pager);  
      
    }  
  
    public void initFragment() {  
        list = new ArrayList<Fragment>();  
        addFragment = new AddFragment();  
        queryFragment = new QueryFragment();  
        settingFragment = new SettingFragment();  
        list.add(addFragment);  
        list.add(queryFragment);  
        list.add(settingFragment);  
    }  
  
  
  
    public class MyPagerAdapter extends FragmentPagerAdapter {  
  
        public MyPagerAdapter(FragmentManager fm) {  
  
            super(fm);  
        }  
  
        private final String[] titles = { "1", "2", "3" };  
  
        @Override  
        public CharSequence getPageTitle(int position) {  
            return titles[position];  
        }  
  
        @Override  
        public int getCount() {  
            return titles.length;  
        }  
  
        @Override  
        public Fragment getItem(int position) {  
            return list.get(position);  
        }  
  
        public Object instantiateItem(ViewGroup container, int position) {  
            tagList.add(makeFragmentName(container.getId(),  
                    (int) getItemId(position)));  
            return super.instantiateItem(container, position);  
        }  
  
        public void update(int item) {  
            Fragment fragment = fm.findFragmentByTag(tagList.get(item));  
            if (fragment != null) {  
                switch (item) {  
                case 0:  
  
                    break;  
                case 1:  
                    ((QueryFragment) fragment).update();  
                    break;  
                case 2:  
  
                    break;  
                default:  
                    break;  
                }  
            }  
        }  
  
    }  
  
    public static String makeFragmentName(int viewId, int index) {  
        return "android:switcher:" + viewId + ":" + index;  
    }  
  
  
  
    public void onFragmentClickListener(int item) {  
        adapter.update(item);  
        adapter.update(item);  
    }  
      
  
}

原文链接:http://www.apkbus.com/blog-509632-59097.html

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消