通过寻呼机通知视图的活动

时间:2012-12-14 05:36:34

标签: android android-asynctask android-fragments android-viewpager

我在Android应用中实现功能时遇到了问题。

以下是设置:

  • ItemPagerActivity:包含显示寻呼机的片段的活动。
  • ItemPagerFragment:包含加载其他片段的寻呼机的片段。游标用于加载片段。
  • ItemFragment:寻呼机中的片段,它执行异步任务以加载其数据。

我想要的是以下内容:

  • 作为I滑动页面,当前显示的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分配一个监听器。

我假设这种模式(通知滑动到视图中的片段中的数据活动)可能很常见,所以我想知道这种模式是否有任何好的解决方案,以及三种具体的解决方案我上面提到的问题。

2 个答案:

答案 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()也有帮助。