我在Android应用中实现功能时遇到了问题。
以下是设置:
ItemPagerActivity
:包含显示寻呼机的片段的活动。 ItemPagerFragment
:包含加载其他片段的寻呼机的片段。游标用于加载片段。ItemFragment
:寻呼机中的片段,它执行异步任务以加载其数据。我想要的是以下内容:
ItemFragment
中的数据会传达给ItemPagerActivity
(具体而言,该项目的名称将用作活动的标题)。我在ItemFragment
中定义了一个监听器,用于通知何时加载数据:
public class ItemFragment ... {
public interface OnItemLoadedListener {
public void onItemLoaded(Item item);
}
private Collection<OnItemLoadListener> listeners;
private class LoadItemTask extends AsyncTask<...> {
...
public void onPostExecute(Item item) {
notifyItemLoaded(item);
...
}
}
}
如果此片段被Activity
包裹,那么我只需执行以下操作即可设置活动的标题:
public class ItemActivity {
public void onCreate(...) {
...
ItemFragment fragment = new ItemFragment();
fragment.registerItemLoadedListener(new ItemLoadedListener() {
public void onItemLoaded(Item item) {
setTitle("Item: " + item.getName());
}
});
...
}
}
所以这很容易,并按预期工作:当活动开始时,它会创建片段,加载项目,通知活动,标题更新正确。
但是对于ItemPagerFragment
,片段是先发制人加载的:滑动到片段3可能意味着片段4和片段5被创建。在加载项目时从ItemFragment
类接收通知在此处不正确,因为显示的片段可能与执行上次加载的片段不匹配。
现在ViewPager
类有OnPageChangeListener
这可能是一个解决方案:当我滑动时,使用当前页码调用此侦听器。从该页码开始,我需要(以某种方式)从适配器获取表示该页面的片段,从片段中获取Item
数据,并通知侦听器Item
现在已加载:
public class ItemPagerFragment ... {
private Collection<OnItemLoadedListener> listeners;
public View onCreateView(...) {
...
ViewPager pager = (ViewPager) view.findViewById(R.id.pager):
pager.setOnPageChangeListener(new OnPageChangeListener() {
public void onPageChange(int pageNumber) {
ItemFragment fragment = getItemFragment(pageNumber);
Item item = fragment.getLoadedItem();
notifyItemLoaded(item);
}
});
...
}
}
然后ItemPagerActivity
类将在ItemPagerFragment
类中注册为侦听器,如下所示:
class ItemPagerActivity ... {
public void onCreate(...) {
...
ItemPagerFragment fragment = new ItemPagerFragment();
fragment.registerOnItemLoadedListener(new OnItemLoadedListener() {
public void onItemLoaded(Item item) {
setTitle("Item: " + item.getName());
}
});
...
}
}
这看起来不错,但有很多问题:
可以在片段加载其数据之前调用OnPageChangeListener
(即,在异步加载项目之前将片段刷入视图中)。因此,对fragment.getLoadedItem()
的调用可能会返回null
。
不会为初始页面调用OnPageChangeListener
(仅在页面更改时,例如在滑动操作后),因此初始页面的活动标题将不正确。
ViewPager
班只允许一个OnPageChangeListener
。这是一个问题,因为我也在使用ViewPageIndicator
库,它想要为ViewPager
分配一个监听器。
我假设这种模式(通知滑动到视图中的片段中的数据活动)可能很常见,所以我想知道这种模式是否有任何好的解决方案,以及三种具体的解决方案我上面提到的问题。
答案 0 :(得分:0)
...所以我想知道这种模式是否有任何好的解决方案, 以及我上面提到的三个具体问题。
我不知道我是否会将其称为模式,但OnPageChangeListener
是可行的方式。
可以在加载片段之前调用OnPageChangeListener 其数据(即,在项目具有之前将片段刷入视图中 异步加载)。所以对fragment.getLoadedItem()的调用可能会 return null。
首先,您的代码应该从一开始就处理“无数据可用情况”。您的AsyncTasks
将负责加载数据,并且仅当更新标题时,他们正在使用的片段是可见的片段(ItemFragment
中的位置字段针对ViewPager
的{{1}}方法进行了测试。 getCurrentItem()
将在数据加载后处理标题的更新,因为用户在页面之间切换并且数据可用(如果没有可用的数据,它将返回null)。要获得某个职位的OnPageChangeListener
,您可以使用以下代码:
ItemFragment
不会为初始页面调用OnPageChangeListener(仅限 当页面改变时,例如在刷卡动作之后)所以活动标题 对于初始页面将不正确。
见上文。
ViewPager类只允许一个OnPageChangeListener。这是 一个问题,因为我也在使用ViewPageIndicator库 想要将监听器分配给ViewPager
我承认我对 ItemFragment itf = getSupportFragmentManager()
.findFragmentByTag(
"android:switcher:" + R.id.theIdOfTheViewPager + ":"
+ position);
if (itf != null) {
Item item = fragment.getLoadedItem();
notifyItemLoaded(item);
}
图书馆的了解不多,但我在网站上看到了:{/ p>
(可选)如果您将OnPageChangeListener与您的视图寻呼机一起使用 应该在指标中而不是直接在寻呼机上设置它。
ViewPagerIndicator
我看不出限制在哪里。
答案 1 :(得分:0)
出于我的目的,当片段可见时,ViewPager.OnPageChangeListener.onPageSelected()
与Fragment.onActivityCreated()
一起使用可以执行操作。 Fragment.getUserVisibleHint()
也有帮助。