如何通过外部点击事件(比如:actionbar),更新ViewPager里的信息
2016-07-11 17:13
525 查看
最近做东西发现了一个问题,用viewPager加载Fragment,无法通过notifyDataSetChanged()进行数据更新,o(╯□╰)o很是郁闷。所以就研究了一番,以下是成果,分享一下
PagerAdapter的工作机制 可以参考一下这篇文章,我也是通过这篇文章得到的启发,在此表示感谢,O(∩_∩)O哈哈~
PagerAdapter主要的工作机制,就是会自动加载,及 卸载view,保留当前及相邻的view,共三个界面
接下来我们来说一下问题
1、如何通过外部点击事件(比如:actionbar),更新ViewPager里的信息
上面链接的博主,提供了一个方案是,重写instantiateItem,当然这也是一种方案。
重写多麻烦呀,我顺便看了一下源码,FragmentPagerAdapter里是这样写的
[java] view
plain copy
@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
plain copy
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
也就是说,给每个fragment都打上了一个tag,如果我们知道了tag,就可以通过tag 来获取Fragment,好的,按着这一个思路,我是这么来实现的
[java] view
plain copy
public Object instantiateItem(ViewGroup container, int position) {
tagList.add(makeFragmentName(container.getId(), getItemId(position)));
return super.instantiateItem(container, position);
}
我们来定义一个list<String> tagList 来存储一下tag,然后再adapter里加一个Update方法,如下
[java] view
plain copy
public void update(int item){
Fragment fragment = fm.findFragmentByTag(tagList.get(item));
if(fragment != null){
switch (item) {
case 0:
((FirstFragment) fragment).update();
break;
case 1:
((SecondFragment) fragment).update();
break;
case 2:
((ThirdFragment) fragment).update();
break;
default:
break;
}
}
}
细心的朋友可能发现了,fragment有了一个update方法,这个其实个人加的,也就是通过tag获取到相应的fragment,然后调用fragment里的一个方法
fragment里的 方法就按自己的需求来了,我是这么写的,显示出当前的时间来
[java] view
plain copy
public void update(){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss",Locale.getDefault());
mTextView.setText(format.format(new Date()));
}
好了,一切搞定,我们就可以在外部的点击事件里通过mAdapter.update()方法来更新相应的fragment了,以下是效果图,点击ActionBar的Update就可以更新section2的时间了
O(∩_∩)O哈哈~,好吧,我暴露了,截图上有个按钮,那就是我们接下来要讨论的问题了
2、fragment之间的数据更新问题
1)首先,我们知道一件事情,现在activity可以向fragment传值了。我们可以借助这个来实现fragment之间的数据更新,流程是这样的
fragment -> activity -> fragment
o(╯□╰)o不会画图,就用文字代替了,敬请原谅,请各位将就着看吧。
2)我们来定义一个接口,让我们当前的activity来实现这个接口
[java] view
plain copy
public interface FragmentListener {
public void onFragmentClickListener(int item);
}
3)在Fragment中,重写一下onAttach
[java] view
plain copy
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (FragmentListener)activity;
} catch (Exception e) {
e.printStackTrace();
Log.i("", "activity 没有实现FragmentListener接口");
}
}
4)这样,我们拿到了FragmentListener,就可以通过回调来调用activity了
[java] view
plain copy
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
listener.onFragmentClickListener(0);
}
}
});
5)我们在activity里实现FragmentListener接口
[java] view
plain copy
public void onFragmentClickListener(int item) {
mSectionsPagerAdapter.update(item);
}
就这样,我们就可以实现Fragment之间的数据更新问题了。
上面的截图中,点击section2里的按钮,就可以在section1中显示当前时间了,O(∩_∩)O哈哈~
版权声明:本文为博主原创文章,未经博主允许不得转载。
Android
Studio 怎么添加使用第三方jar包及无法编译的问题解决方法
动态改变actionbar的menu菜单MenuItem
您还没有登录,请[登录]或[注册]
额 为什么不同getitem直接拿到fragment呢
2016-03-28 15:47
感谢LZ,解决的我的问题~(≧▽≦)/~
2016-01-20 16:07
楼主,跪求源码,给你发私信了。
2015-03-18 19:21
博主,有上传demo吗
2014-10-22 15:08
想操作fragment却一直找不到id,tag,之类的,讲的很清楚,谢谢楼主了
2014-08-29 00:58
非常感谢 困扰了两天的问题终于解决了
2014-08-20 10:20
博主,我也是用viewPager+fragment的,但是我的问题是在一个fragment上弹出一个对话框然后根据选择更新fragment上的显示。可能我还没看懂上面的思想,能不能指教一下
2014-08-08 11:21
回复cltcl:你Dialog是从哪里弹出来的?如果是Fragment弹出来的话,那直接在Fragment里下个refresh方法刷新就可以了。
如果是在嵌套Fragment的Activity里弹出来的话,那首先在Activity里通过getFragmentManager().findFragmentByTag()获取此Fragment,然后调用Fragment里的Refresh方法
2014-08-12 16:16
setTag用来刷新页面挺好用的。谢谢楼主
2014-07-31 12:01
makeFragmentName 这个方法怎么引用不了。要关联码源?
2014-02-22 17:20
回复Bobbybear:把源码里的 makeFragmentName()方法拿出来就可以了
2014-02-25 19:47
我好弱,搞定了,重写的方法错了,仔仔细细的看了一遍,是有viewgroup的,多谢楼主大神
2013-12-18 00:42
群主,178875443@qq.com,求demo
2013-12-18 00:17
楼主我尝试了一下,instantiateItem这个方法没有调用啊!什么情况
2013-12-17 23:19
楼主好强悍,和我想到一起去了,viewpager动态添加的时候,是不能通过findfragmentbyid来查找的,楼主写的文章很好!要是有demo就更好了
2013-12-17 18:30
回复kikyou321:项目里的,我就没有拿出来。
就简单的写了一下思想,只要理解了思想应该问题就不大了
PagerAdapter的工作机制 可以参考一下这篇文章,我也是通过这篇文章得到的启发,在此表示感谢,O(∩_∩)O哈哈~
PagerAdapter主要的工作机制,就是会自动加载,及 卸载view,保留当前及相邻的view,共三个界面
接下来我们来说一下问题
1、如何通过外部点击事件(比如:actionbar),更新ViewPager里的信息
上面链接的博主,提供了一个方案是,重写instantiateItem,当然这也是一种方案。
重写多麻烦呀,我顺便看了一下源码,FragmentPagerAdapter里是这样写的
[java] view
plain copy
@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
plain copy
String name = makeFragmentName(container.getId(), itemId);
Fragment fragment = mFragmentManager.findFragmentByTag(name);
也就是说,给每个fragment都打上了一个tag,如果我们知道了tag,就可以通过tag 来获取Fragment,好的,按着这一个思路,我是这么来实现的
[java] view
plain copy
public Object instantiateItem(ViewGroup container, int position) {
tagList.add(makeFragmentName(container.getId(), getItemId(position)));
return super.instantiateItem(container, position);
}
我们来定义一个list<String> tagList 来存储一下tag,然后再adapter里加一个Update方法,如下
[java] view
plain copy
public void update(int item){
Fragment fragment = fm.findFragmentByTag(tagList.get(item));
if(fragment != null){
switch (item) {
case 0:
((FirstFragment) fragment).update();
break;
case 1:
((SecondFragment) fragment).update();
break;
case 2:
((ThirdFragment) fragment).update();
break;
default:
break;
}
}
}
细心的朋友可能发现了,fragment有了一个update方法,这个其实个人加的,也就是通过tag获取到相应的fragment,然后调用fragment里的一个方法
fragment里的 方法就按自己的需求来了,我是这么写的,显示出当前的时间来
[java] view
plain copy
public void update(){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss",Locale.getDefault());
mTextView.setText(format.format(new Date()));
}
好了,一切搞定,我们就可以在外部的点击事件里通过mAdapter.update()方法来更新相应的fragment了,以下是效果图,点击ActionBar的Update就可以更新section2的时间了
O(∩_∩)O哈哈~,好吧,我暴露了,截图上有个按钮,那就是我们接下来要讨论的问题了
2、fragment之间的数据更新问题
1)首先,我们知道一件事情,现在activity可以向fragment传值了。我们可以借助这个来实现fragment之间的数据更新,流程是这样的
fragment -> activity -> fragment
o(╯□╰)o不会画图,就用文字代替了,敬请原谅,请各位将就着看吧。
2)我们来定义一个接口,让我们当前的activity来实现这个接口
[java] view
plain copy
public interface FragmentListener {
public void onFragmentClickListener(int item);
}
3)在Fragment中,重写一下onAttach
[java] view
plain copy
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (FragmentListener)activity;
} catch (Exception e) {
e.printStackTrace();
Log.i("", "activity 没有实现FragmentListener接口");
}
}
4)这样,我们拿到了FragmentListener,就可以通过回调来调用activity了
[java] view
plain copy
mButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(listener != null){
listener.onFragmentClickListener(0);
}
}
});
5)我们在activity里实现FragmentListener接口
[java] view
plain copy
public void onFragmentClickListener(int item) {
mSectionsPagerAdapter.update(item);
}
就这样,我们就可以实现Fragment之间的数据更新问题了。
上面的截图中,点击section2里的按钮,就可以在section1中显示当前时间了,O(∩_∩)O哈哈~
版权声明:本文为博主原创文章,未经博主允许不得转载。
顶1 踩1
Android
Studio 怎么添加使用第三方jar包及无法编译的问题解决方法
动态改变actionbar的menu菜单MenuItem
您还没有登录,请[登录]或[注册]
tracymac7
额 为什么不同getitem直接拿到fragment呢2016-03-28 15:47
死烤鹅
感谢LZ,解决的我的问题~(≧▽≦)/~2016-01-20 16:07
猴子搬来的救兵WooYun
楼主,跪求源码,给你发私信了。2015-03-18 19:21
qq_19257157
博主,有上传demo吗2014-10-22 15:08
很多圈
想操作fragment却一直找不到id,tag,之类的,讲的很清楚,谢谢楼主了2014-08-29 00:58
_陈龙飞
非常感谢 困扰了两天的问题终于解决了2014-08-20 10:20
JimiChen0
博主,我也是用viewPager+fragment的,但是我的问题是在一个fragment上弹出一个对话框然后根据选择更新fragment上的显示。可能我还没看懂上面的思想,能不能指教一下2014-08-08 11:21
shadow066
回复cltcl:你Dialog是从哪里弹出来的?如果是Fragment弹出来的话,那直接在Fragment里下个refresh方法刷新就可以了。如果是在嵌套Fragment的Activity里弹出来的话,那首先在Activity里通过getFragmentManager().findFragmentByTag()获取此Fragment,然后调用Fragment里的Refresh方法
2014-08-12 16:16
xoxo4326
setTag用来刷新页面挺好用的。谢谢楼主2014-07-31 12:01
极客公园
makeFragmentName 这个方法怎么引用不了。要关联码源?2014-02-22 17:20
shadow066
回复Bobbybear:把源码里的 makeFragmentName()方法拿出来就可以了2014-02-25 19:47
kikyou321
我好弱,搞定了,重写的方法错了,仔仔细细的看了一遍,是有viewgroup的,多谢楼主大神2013-12-18 00:42
kikyou321
群主,178875443@qq.com,求demo2013-12-18 00:17
kikyou321
楼主我尝试了一下,instantiateItem这个方法没有调用啊!什么情况2013-12-17 23:19
kikyou321
楼主好强悍,和我想到一起去了,viewpager动态添加的时候,是不能通过findfragmentbyid来查找的,楼主写的文章很好!要是有demo就更好了2013-12-17 18:30
shadow066
回复kikyou321:项目里的,我就没有拿出来。就简单的写了一下思想,只要理解了思想应该问题就不大了
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories