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


}

コードは問題なくコンパイルされ、タブレットにアップロードされます。「私は押されました!」というテキストを書くと思います。ボタンを押すとテキストビューに移動しますが、アプリは標準の「残念ながらアプリが機能しなくなりました」でクラッシュします。このキャッチされていない例外をキャッチするためのクラスをまだ実装していません。不足している、または理解していないことが明らかであることを期待していましたか?

ありがとう

4

1 に答える 1

2

これは古い質問ですが、サンプル コードが機能しない理由がわかりにくかったので、回答したいと思います。

を取得する理由NullPointerExceptionは、インスタンスを作成Fragmentし、アクティビティをフラグメントに注入する必要があるメソッドをすぐに呼び出すためです。アクティビティはFragmentManager/FragmentTransaction#commitメソッドによって注入されますが、このメソッドはトランザクションをすぐには評価しません (JavaDocs のように):

このトランザクションのコミットをスケジュールします。コミットはすぐには行われません。次回のスレッドの準備ができたときに実行されるように、メイン スレッドでの作業としてスケジュールされます。

つまり

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

startUpdateText()(トランザクションがまだ実行されていないため!) NPE が生成されます。

getFragmentManager().executePendingTransactions();コミットの直後にメソッド呼び出しを追加すると、トランザクションがすぐに実行され、アクティビティがフラグメントに挿入されます。getActivity()今でFragmentは、それが添付されたアクティビティを返し、サンプルが機能します:)

あなたの質問の下のコメントからのように:フラグメントがアクティビティ内でホストされる再利用可能な「UI要素」であることは事実です。( @Stefan de Bruijn ) だけでなく、[...] フラグメントはアクティビティ レイアウトの一部である必要はありません。アクティビティの目に見えないワーカーとして、独自の UI を持たないフラグメントを使用することもできます。(公式のAndroidドキュメントが言うように)。

そのため、フラグメントは必ずしも GUI コンポーネント (つまり、MVC のビュー) ではなく、独自のライフタイム/ライフサイクルを持つコントローラーとしても機能します。

于 2015-04-21T11:49:15.183 に答える