同步ListFragment和SupportMapFragment选择

时间:2013-05-22 09:21:13

标签: android google-maps android-listfragment supportmapfragment otto

我有2个基本相同数据的视图:

  1. List android.support.v4.app中的项目。 ListFragment
  2. com.google.android.gms.maps中map上的标记。 SupportMapFragment
  3. 上述两种方法都使用loader模式来获取相同的数据(扩展 LoaderCallbacks ,查询 ContentProvider 等等)

    两者都托管在ViewPager中的单个activity内。

    同步这些片段的当前所选列表项/标记的最佳策略是什么? (想想“我的地方”编辑用户界面或Google地图的“方向”及其左侧窗格和中心地图)。

    到目前为止,我正在考虑的情景:

    1. 通过回调接口手动通知每个片段关于选择更改的对应物(这可能涉及协调片段间通信的基础活动,如Android文档所建议的那样)。
    2. 不知何故使两个片段使用相同的Cursor,甚至是ListAdapter(无论它对地图意味着什么,因为现在它直接从光标填充)。
    3. (别的什么?)
    4. 也许有人已经处理了这个确切的案例? (我肯定会找到一些解决方案,只是想避免“重新发明轮子”。抱歉这是一个过于概念化的问题。)

      编辑(解决方案)

      我认为Maciej已经回答了我的确切问题(“最佳策略”,等等......),所以答案都是 1 2 ; - )< / p>

      进入更多细节,我的实现是这样的:

      起初我害怕处理Java中的发布者/订阅者模式(涉及接口,找到适当的回调位置,以及什么不是)的巨大开销。幸运的是,Otto总线实现引起了我的注意,这使得片段之间的通信变得微不足道。不仅可以通知所有订户有关选择更改的信息,而且整个Loader Patter也非常适合:

      1. 从Otto的示例代码中借用BusProvider类。

      2. 创建一些消息合同来传送通知数据:

        public class LocationSelectedEvent {  
            public long id;  
        }  
        
        public class LocationsLoadedEvent {  
            public Cursor cursor;  
        }  
        
      3. 使用@Subscribe在片段中注释“接收器”方法(下面的例子是针对装载器的情况,选择更改它并不复杂):

        @Subscribe
        public void onLoadFinished(LocationsLoadedEvent event) {  
            final CursorAdapter a = (CursorAdapter) getListAdapter();  
            a.swapCursor(event.cursor);  
        }  
        
      4. 让片段“收听”通知:

        @Override  
        public void onActivityCreated(Bundle savedInstanceState) {  
            BusProvider.getInstance().register(this);  
        }  
        
      5. 当片段“不活着”时,将片段设置为停止监听(特别适用于片段API,请严格学习):

        @Override  
        public void onDestroy() {  
            super.onDestroy();  
            BusProvider.getInstance().unregister(this);  
        }  
        
      6. 最后,根据需要触发通知(下面的示例说明了在加载游标时如何通过 LocationList 活动进行通知):

        @Override
        public void onResume() {
            if(null == getLoaderManager().getLoader(0)) {
                getSupportLoaderManager().initLoader(0, null, new LoaderCallbacks<Cursor>() {
                    @Override
                    public Loader<Cursor> onCreateLoader(int paramInt, Bundle paramBundle) {
                        return new CursorLoader(LocationsList.this, Locations.CONTENT_URI, null, null, null, null);
                    }
        
                    @Override
                    public void onLoadFinished(Loader<Cursor> paramLoader, Cursor cursor) {
                        BusProvider.getInstance().post(new LocationsLoadedEvent(cursor));
                    }
        
                    @Override
                    public void onLoaderReset(Loader<Cursor> paramLoader) {
                        BusProvider.getInstance().post(new LocationsLoadedEvent(null));
                    }
                });
            }
            super.onResume();
        }
        
      7. 奖励:通知流可视化

1 个答案:

答案 0 :(得分:1)

对于点击协调,您的第1点就是我要做的,当然使用Activity和接口。

我很难理解为什么要从ContentProvider加载两次相同的数据。为什么不在共享对象中加载一次? Application内的某个对象,注入单个或{q} {}},它会通知Fragment数据加载完成并将数据推送到您的两个Activity