2013-01-09 75 views
39

這個問題主要是爲了徵求意見,以處理我的應用程序的最佳方式。我有三個片段被一個活動處理。片段A有一個可點擊的元素照片,片段B有4個可點擊的元素按鈕。另一個片段僅顯示單擊照片時的詳細信息。我正在使用ActionBarSherlock。片段和活動之間的溝通 - 最佳實踐

Screen shot

的前進和後退按鈕需要分別更改照片到下一個或前一個姿勢。我可以將照片和按鈕保留在同一個片段中,但是想要將它們分開以防我想在平板電腦中重新排列它們。

我需要一些建議 - 我應該結合碎片A和B嗎?如果沒有,我將需要弄清楚如何實現3個可點擊項目的界面。

我考慮過使用Roboguice,但我已經使用SherlockFragmentActivity進行了擴展,所以這是一個不行。我看到了Otto的提及,但是我沒有看到關於如何包含在項目中的很好的教程。你認爲最好的設計實踐應該是什麼?

我還需要幫助弄清楚如何在片段和活動之間進行通信。我想在應用程序中保留一些「全局」數據,例如pose ID。除了股票android開發人員的信息之外,是否還有一些示例代碼?這並不是那麼有用。

順便說一句,我已經存儲了關於SQLite數據庫中每個姿勢的所有信息。這是很容易的部分。

+0

其實你可以使用Rogoguice和ActionbarSherlock,看看https://github.com/rtyley/roboguice-sherlock。 – rubenlop

+0

Otto更簡單,打包爲一個獨立的.jar文件,您可以將它放在您應用程序的libs /文件夾中。 – rubenlop

+1

@ rubenlop88添加一個庫只是爲了將一些數據從Fragment傳遞給Activity? –

回答

54

在活動和片段之間進行通信的最簡單方法是使用接口。這個想法基本上是在給定片段A中定義一個接口,並讓活動實現該接口。

一旦它實現了這個接口,你就可以在它覆蓋的方法中做任何你想做的事情。

接口的另一個重要部分是,您必須從片段中調用抽象方法,並記住將其轉換爲您的活動。如果不正確,它應該捕獲一個ClassCastException。

關於Simple Developer Blog有關於如何做這種事情的很好的教程。

我希望這對你有幫助!

+2

這就是我所做的。謝謝。 –

+1

有誰知道爲什麼android開發人員頁面上有關使用警報對話框的示例不使用接口與活動進行通信? http://developer.android.com/reference/android/app/DialogFragment.html#AlertDialog – cjayem13

+1

或使用EventBus https://github.com/greenrobot/EventBus – powder366

1

我不確定我真的明白你想要做什麼,但建議的片段之間通信的方式是使用回調與活動,不要直接在片段之間。看到這裏http://developer.android.com/training/basics/fragments/communicating.html

+0

是的,這樣看起來很混亂,我有2個片段需要以某種方式通過活動彼此溝通。有沒有關於如何做到這一點的更好的教程? –

+1

@KristyWelsh:我想知道你是否開發了自己的'碎片'真正的概念以及它們如何工作,而不是理解'碎片'設計目標的實際概念。使用'interfaces'與'Activity'通信的概念與'Activity'實現'View.OnClickListener'沒有什麼不同,所以'Button'按鈕導致一個項目被添加到'ListView'中(例如)。你可能有一個帶有FragmentA和FragmentB而不是FragmentC的Activity,在這種情況下,讓FragmentA「知道」如何直接與FragmentC交談的概念是多餘的。 – Squonk

20

建議的片段之間通信的方法是使用由您的主要活動管理的回調\監聽器。

我覺得這個頁面上的代碼是很清楚的: http://developer.android.com/training/basics/fragments/communicating.html

您也可以參考的IO 2012計劃應用程序,它被設計成一個事實上的參考應用程序。它可以在這裏找到: http://code.google.com/p/iosched/

而且,這裏是好消息一個SO問題: How to pass data between fragments

0

可以創建聲明一個公共接口,在該片段中函數聲明和實施活動中的接口。然後你可以從片段中調用函數。

0

我正在使用意圖溝通行動回到主要活動。主要活動是通過覆蓋onNewIntent(Intent intent)來監聽這些事件。例如,主要活動將這些操作轉換爲相應的片段。

所以,你可以做這樣的事情:任何片段內

public class MainActivity extends Activity { 

    public static final String INTENT_ACTION_SHOW_FOO = "show_foo"; 
    public static final String INTENT_ACTION_SHOW_BAR = "show_bar"; 


    @Override 
    protected void onNewIntent(Intent intent) { 
     routeIntent(intent); 
    } 

    private void routeIntent(Intent intent) { 
     String action = intent.getAction(); 
     if (action != null) {    
      switch (action) { 
      case INTENT_ACTION_SHOW_FOO: 
       // for example show the corresponding fragment 
       loadFragment(FooFragment); 
       break; 
      case INTENT_ACTION_SHOW_BAR: 
       loadFragment(BarFragment); 
       break;    
     } 
    } 
} 

然後顯示foo的片段:

Intent intent = new Intent(context, MainActivity.class); 
intent.setAction(INTENT_ACTION_SHOW_FOO); 
// Prevent activity to be re-instantiated if it is already running. 
// Instead, the onNewEvent() is triggered 
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); 
getContext().startActivity(intent); 
2

有severals方式之間的活動,片段和服務等方面進行交流顯而易見的是使用接口進行通信。但是,這不是一種有效的溝通方式。你必須實現聽衆等。

我的建議是使用事件總線。事件總線是發佈/訂閱模式實現。

您可以訂閱你的活動事件,然後你可以張貼在您的片段等

這裏on my blog post事件,你可以找到關於此模式的更多詳細信息,並an example project顯示的使用。

5

它是通過回調接口來實現的:所有的 首先,我們必須做出一個接口:

public interface UpdateFrag { 
    public void updatefrag(); 
    } 

在活動執行以下代碼:

UpdateFrag updatfrag ; 
public void updateApi(UpdateFrag listener) { 
     updatfrag = listener; 
    } 

從事件從那裏回調必須在活動中觸發:

updatfrag.updatefrag(); 

In Fragment implement the i在CreateView中執行以下代碼:

((Home)getActivity()).updateApi(new UpdateFrag() { 
       @Override 
       public void updatefrag() { 
        .....your stuff...... 
       } 
      }); 
1

我做了一個註釋庫,可以爲您進行強制轉換。看一下這個。 https://github.com/zeroarst/callbackfragment/

@CallbackFragment 
public class MyFragment extends Fragment { 

    @Callback 
    interface FragmentCallback { 
     void onClickButton(MyFragment fragment); 
    }  
    private FragmentCallback mCallback; 

    @Override 
    public void onClick(View v) { 
     switch (v.getId()) { 
      case R.id.bt1 
       mCallback.onClickButton(this); 
       break; 
      case R.id.bt2 
       // Because we give mandatory = false so this might be null if not implemented by the host. 
       if (mCallbackNotForce != null) 
       mCallbackNotForce.onClickButton(this); 
       break; 
     } 
    } 
} 

然後,它產生的片段的子類。只需將其添加到FragmentManager。

public class MainActivity extends AppCompatActivity implements MyFragment.FragmentCallback { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     getSupportFragmentManager().beginTransaction() 
      .add(R.id.lo_fragm_container, MyFragmentCallbackable.create(), "MY_FRAGM") 
      .commit(); 
    } 

    Toast mToast; 

    @Override 
    public void onClickButton(MyFragment fragment) { 
     if (mToast != null) 
      mToast.cancel(); 
     mToast = Toast.makeText(this, "Callback from " + fragment.getTag(), Toast.LENGTH_SHORT); 
     mToast.show(); 
    } 
}