2012-06-21 110 views
3

我有這樣的結構:在活動和片段之間傳遞數據或行爲

活動A有一個ViewPager。 ViewPager的頁面是已知片段。

活動A有一個複雜對象的列表,我想在頁面中顯示。

當用戶點擊ViewPager活動內的項目時,必須啓動B。活動B還需要具有複雜對象的列表。

所以我要通過這個列表

A - >片段(S) - 「乙

首先,我發現這是不可能使用片段的構造函數將數據傳遞給它。我必須使用parcelable或serializable。在片段然後我必須包裹或再次序列化傳遞給B.

但我不想要序列或地塊只有2次複雜數據的整個列表,通過讓它B.

我想避免使用靜態字段。

然後我想到了將監聽器傳遞給監聽項目單擊的片段,並通知我的活動A,然後活動A隨着數據啓動活動B.這對我來說看起來最清潔,因爲A實際上是數據所屬的一個,所以A用數據開始片段,片段返回到A然後A用數據開始B.我不需要在任何地方傳遞數據(序列化!)。

但是這似乎並不奏效,因爲我如何使用序列化將偵聽器傳遞給片段?在片段中使用監聽器返回活動有什麼問題?

我該如何解決這個問題?

編輯

我發現一個關於對話的片段線程此解決方案:Get data back from a fragment dialog - best practices?

@Override 
public void onAttach(Activity activity) { 
super.onAttach(activity); 
try { 
    mListener = (OnArticleSelectedListener) activity; 
} catch (ClassCastException e) { 
    throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener"); 
} 
} 

所以我加入這個我片段,讓我的活動實現某些接口。

這將解決從片段傳遞數據到B的問題。但我仍然需要將列表從A傳遞到片段。也許我將不得不使用一個Parcelable ...

編輯:我試過Parcelable,它的工作原理。但是,例如,我列表中的對象在它們之間也有很多字段也是地圖。編寫Parcelable代碼(寫入/讀取)是疼痛。也許我只是堅持靜態數據...

+0

我得到了同樣的問題。我的複雜數據使用片段計算並顯示在活動A的列表中,但細節將顯示在任一活動B中使用片段或兩個窗格佈局中的同一活動中,但具有不同的詳細信息片段。我完全不知道,但是可以將我的詳細數據加以分類,這是一種痛苦...你有沒有想出更好的想法?例如把它作爲中間介質放在應用程序對象中? – Zordid

回答

2

您發現的聽衆解決方案非常好,實際上由Google推薦(http://developer.android.com/training/basics/fragments/communicating.html)。

至於將數據傳遞給片段的剩餘問題,您確定需要傳遞整個列表,而不僅僅是ViewPager中每個片段的列表元素嗎?如果你只需要一個元素,你可以這樣做:

/* 
    * An adapter for swiping through the fragments we have. 
    */ 
    private class CustomPagerAdapter extends FragmentStatePagerAdapter { 

     List<Thing> things; 

     public CustomPagerAdapter(FragmentManager fragmentManager, List<Thing> things) { 
      super(fragmentManager); 
      this.things = things; 
     } 

     @Override 
     public int getCount() { 
      return things.size(); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      return ThingFragment.newInstance(things.get(position)); 
     } 
    } 

    /* 
    * Loads a view based on the thing. 
    */ 
    private static class ThingFragment extends Fragment { 

     private String name; 

     static ThingFragment newInstance(Thing thing) { 

      ThingFragment f = new ThingFragment(); 

      // add some arguments to our fragment for onCreateView 
      Bundle args = new Bundle(); 
      args.putString("name", thing.getName()); 
      f.setArguments(args); 

      return f; 
     } 

     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      name = getArguments().getString("name"); 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 

      View v = inflater.inflate(R.layout.thing_fragment_layout, container, false); 
        TextView t = (TextView)v.findViewById(R.id.thingText); 
      t.setText(name); 
      return v; 
     } 
    } 

並將你的列表傳遞給適配器。當然,這需要動態地創建動態,但是擴充xml片段非常簡單。

如果你確實需要傳遞整個列表,是的,你可能必須製作單獨的複雜對象Parcelable,然後像Bundle.putParcelableArray()一樣將它添加到你的Fragment參數中。

+0

感謝您的回答。在每個片段中,我正在顯示一個網格,並且想要傳遞網格的模型項目列表。我嘗試了Parcelable,但實現很糟糕(我的數據類型有很多字段,也有類型映射等等,編寫代碼來序列化和反序列化是一個真正的痛苦)。而且它也很慢,我的屏幕一會兒空白。所以我想我必須使用靜態數據。 – Ixx

+0

呃,對不起,屏幕是空白的,因爲別的東西,而不是可parcelable。 – Ixx

+1

我想,假設你確定了你的條件,你可以通過演員獲得onAttach中的信息:@Override public void onAttach(Activity activity){ mFragmentList =((MyActivity)activity).getList(); }' – Makario