1

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

  1. android.support.v4.app 中的项目列表列表片段
  2. com.google.android.gms.maps 中地图上的标记。支持MapFragment

以上两种都是使用加载器模式来获取相同的数据(扩展LoaderCallbacks,查询ContentProvider等)

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

为这两个片段同步当前选定的列表项/标记的最佳策略是什么?(想想“我的地点”编辑 UI,或谷歌地图的“路线”,左侧窗格和中间的地图)。

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

  1. 使每个片段通过回调接口手动通知其对应的选择更改(这可能涉及协调片段间通信的底层活动,正如 Android 文档所建议的那样)。
  2. 不知何故,让两个片段使用相同的光标,甚至是 ListAdapter(无论它对地图意味着什么,因为现在它直接从光标填充)。
  3. (还有什么?)

也许有人已经处理过这个确切的案例?(我肯定会找到一些解决方案,只是想避免“重新发明轮子”。抱歉,这个问题太概念化了。)

编辑(解决方案)

我认为 Maciej 已经回答了我的确切问题(“最佳策略”等..),所以答案是12 ;-)

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

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

  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();
    }
    

奖励:通知流可视化

4

1 回答 1

1

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

我只是很难理解为什么要从ContentProvider两次加载相同的数据。为什么不在共享对象中加载一次呢?里面的一些对象Application,注入单例或什至另一个Fragment,它通知Activity数据加载完成并将数据推送到您的两个Fragments

于 2013-05-22T10:12:23.123 回答