android4.4.2fragment不显示,Android Fragment 数据动态更新的问题

getItem()

一个该类中新增的虚函数。

函数的目的为生成新的 Fragment 对象。

Fragment.setArguments() 这种只会在新建 Fragment 时执行一次的参数传递代码,可以放在这里。

由于 FragmentStatePagerAdapter.instantiateItem() 在大多数情况下,都将调用 getItem() 来生成新的对象,因此如果在该函数中放置与数据集相关的 setter 代码,基本上都可以在 instantiateItem() 被调用时执行,但这和设计意图不符。毕竟还有部分可能是不会调用 getItem() 的。因此这部分代码应该放到 instantiateItem() 中。

instantiateItem()

除非碰到 FragmentManager 刚好从 SavedState 中恢复了对应的 Fragment 的情况外,该函数将会调用 getItem() 函数,生成新的 Fragment 对象。新的对象将被 FragmentTransaction.add()。

FragmentStatePagerAdapter 就是通过这种方式,每次都创建一个新的 Fragment,而在不用后就立刻释放其资源,来达到节省内存占用的目的的。

讨论

之前看到一些解决办法,有的认为这是一个

bug,应该被修复;有的

建议不用 FragmentPagerAdapter,而改用 FragmentStatePagerAdapter,并且重载 getItemPosition() 并返回 POSITION_NONE,以触发销毁对象以及重建对象。从上面的分析中看,后者给出的建议确实可以达到调用 notifyDataSetChanged() 后,Fragment 被以新的参数重新建立的效果。

但是问题在于,如果我们只能这么解决这个问题,岂不是 FragmentPagerAdapter 就用不上了?最关键的是,二者对应的情况不同。对于页面相对较少的情况,我仍旧希望能够将生成的 Fragment 保存在内存中,在需要显示的时候直接调用,而不要产生生成、销毁对象的额外的开销,这样效率更高。这种情况下,选择 FragmentPagerAdapter 是更适合,不加考虑的选择 FragmentStatePagerAdapter 是不合适的。我们不能够因噎废食。

因此,对于 FragmentPagerAdapter 的解决方案就是,分别重载 getItem() 以及 instantiateItem() 对象。getItem() 只用于生成新的与数据无关的 Fragment;而 instantiateItem() 函数则先调用父类中的 instantiateItem() 取得所对应的 Fragment 对象,然后,根据对应的数据,调用该对象对应的方法进行数据设置。

当然,不要忘记重载 getItemPosition() 函数,返回 POSITION_NONE,这个两个类的解决方案都需要的。二者不同之处在于,FragmentStatePagerAdapter 在会在因 POSITION_NONE 触发调用的 destroyItem() 中真正的释放资源,重新建立一个新的 Fragment;而 FragmentPagerAdapter 仅仅会在 destroyItem() 中 detach 这个 Fragment,在 instantiateItem() 时会使用旧的 Fragment,并触发 attach,因此没有释放资源及重建的过程。

这样,当 notifyDataSetChanged() 被调用后,会最终触发 instantiateItem(),而不管 getItem() 是否被调用,我们都在重载的 instantiateItem() 函数中已经将所需要的数据传递给了相应的 Fragment。在 Fragment 接下来的 onCreateView(), onStart() 以及 onResume() 的事件中,它可以正确的读取新的数据,Fragment 被成功复用了。

这里需要注意一个问题,在 Fragment 没有被添加到 FragmentManager 之前,我们可以通过 Fragment.setArguments() 来设置参数,并在 Fragment 中,使用 getArguments() 来取得参数。这是常用的参数传递方式。但是这种方式对于我们说的情况不适用。因为这种数据传递方式只可能用一次,在 Fragment 被添加到 FragmentManager 后,一旦被使用,我们再次调用 setArguments() 将会导致

java.lang.IllegalStateException: Fragment already active 异常。因此,我们这里的参数传递方式选择是,在继承的 Fragment 子类中,新增几个 setter,然后通过这些 setter 将数据传递过去。反向也是类似。相关信息可以参考 [5]。哦,这些 setter 中要注意不要操作那些 View,这些 View 只有在 onCreateView() 事件后才可以操作。

针对 FragmentPagerAdapter 的解决办法如下列代码所示:

@Override

public Fragment getItem(int position) {

MyFragment f = new MyFragment();

return f;

}

@Override

public Object instantiateItem(ViewGroup container, int position) {

MyFragment f = (MyFragment) super.instantiateItem(container, position);

String title = mList.get(position);

f.setTitle(title);

return f;

}

@Override

public int getItemPosition(Object object) {

return PagerAdapter.POSITION_NONE;

}

参考

Android 文档:

Android 源代码:

Android Issue List:

在C语言中,直接评估一个是否值得深入交往通常涉及到主观判断,这并不适合用编程语言去实现,因为程序设计主要是处理数据和逻辑,而非情感分析。但是,你可以设计一些规则或算法来衡量朋友间的互动、共同兴趣等因素,然后通过用户输入的数据进行分析。 例如,你可以创建一个简单的命令行程序,其中包含几个变量来记录朋友的行为,如共享活动次数、互相帮助的情况等。然后编写函数对这些变量进行评分,并设置阈值来决定是否达到值得深交的程度。但这需要为设定规则,并非真正的智能决策。 以下是粗略的伪代码示例: ```c #include <stdio.h> // 定义友情分数结构体 typedef struct { int activity_score; int help_score; // ... 其他相关字段 } FriendshipScore; // 计算友谊得分函数 FriendshipScore calculateFriendship(int activities, int helps) { FriendshipScore score = {0}; score.activity_score = activities; score.help_score = helps; // ... 根据你的规则计算总分 return score; } int main() { int activities, helps; printf("请输入你们一起参与的活动次数:"); scanf("%d", &activities); printf("请输入你曾帮助过对方的次数:"); scanf("%d", &helps); FriendshipScore friendship = calculateFriendship(activities, helps); if (friendship.total_score >= MIN_DEEP_FRIENDSHIP_SCORE) { printf("这个值得你深入交往。\n"); } else { printf("这个可能还不足以成为深度朋友。\n"); } return 0; } ``` 请注意,这个例子仅作为理论上的说明,实际应用中你需要根据具体的评判标准来编写代码。而且,这并不是一种技术上可行的情感智能或社交网络分析,而更像是一个简单的用户输入处理程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值