2013-08-19 22 views
1

我試圖學習如何使用片段作爲android活動的工作人員。我有以下簡單的XML佈局我的主要活動:使用片段作爲活動的工作人員

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
      android:layout_width="fill_parent" 
      android:layout_height="fill_parent" 
      android:orientation="vertical" > 

<Button 
     android:id="@+id/update" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Press me" /> 

<TextView 
     android:id="@+id/text" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="" /> 

</LinearLayout> 

我定義使用下面的類定義我的片段:

public class UpdateTextFragment extends Fragment { 

public static UpdateTextFragment newInstance() { 
    return new UpdateTextFragment(); 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
} 

public void startUpdateText() { 

    TextView textView = ((TextView) getActivity().findViewById(R.id.text)); 
    textView.setText("I've been pressed!"); 

} 

} 

然後從我的主要活動我只需添加片段,並調用startUpdateText使用該按鈕的onClickListener,即片段的方法,

public void onClick(View arg0) { 

    UpdateTextFragment fragment = UpdateTextFragment.newInstance(); 
    getFragmentManager().beginTransaction().add(fragment, "updateText").commit(); 
    fragment.startUpdateText(); 


} 

代碼編譯和上傳到沒有問題的片劑。我希望它寫出文字「我已經被按下!」到按鈕被按下時的文本視圖,但該應用程序只是與標準的「不幸的應用程序已停止工作」崩潰。我還沒有實現一個類來捕捉這個未被捕獲的異常呢 - 我希望這可能是我明顯失蹤或不明白的東西?

感謝名單

+1

首先,檢查你的logcat的實際錯誤。它應該包含一個stracktrace。其次,這不是Fragments如何工作以及它們的用途。在開發者文檔中首先閱讀使用Fragments和他們的目標。 –

+0

謝謝Stefan。logcat提示java.lang.NullPointerException。將進一步調查。另外,爲什麼不使用這樣的片段?我不打算用它來簡單地在某處改變文本,而是作爲AsyncTask的工作者,因此它可以在方向改變之間保持其狀態(上面只是試圖理解它的實現)。該文件似乎建議你可以使用片段作爲工人,但請讓我知道如果我失去了一些重要的東西。 –

+0

片段是活動內託管的可重用'UI元素'。目標是讓某些UI部件可重複使用,適用於不同的佈局。因此,Fragment擁有自己的視圖xml,並且非常獨立。它不是爲了一個簡單的任務而開始構建,在Activity上做些事情並關閉。如果你想要這樣的工作者,你應該看看線程和服務。您的Nullpointer可能是'fragment'爲null,或者在您的片段中爲'textview'。 –

回答

2

Altough這是一個老問題,我想回答這個問題,因爲我很困惑,爲什麼你的示例代碼沒有工作。

你得到NullPointerException的原因是,你實例化Fragment並立即調用一個方法,要求將該活動注入到Fragment中。活性由FragmentManager/FragmentTransaction#commit方法注入但這種方法不會立即評估交易(如從JavaDoc中):

時刻表一個提交該事務的。提交確實不會立即發生 ;它將被安排在主線程 上工作,待下一次線程準備就緒時完成。

這意味着

getFragmentManager().beginTransaction().add(fragment, "updateText").commit(); 
fragment.startUpdateText(); 

將產生在startUpdateText()的NPE(作爲交易尚未執行的!)。

通過在提交後立即添加方法調用getFragmentManager().executePendingTransactions();立即執行事務並將注入到片段中的活動執行。 getActivity()Fragment現在返回它附有活動和您的樣本工程:)

由於從你的問題下面的評論:這是事實,片段是內部的託管的可重複使用的「UI元素」活動。@Stefan de Bruijn),而且片段不需要成爲活動佈局的一部分;你也可以使用一個沒有自己UI的片段作爲活動的隱形工作者。(官方Android doc說)。

因此,片段不一定是GUI組件(即MVC中的視圖),而且還充當具有其自己的生命週期的控制器。