75

私には1つの活動があります- MainActivity。このアクティビティ内に2つのフラグメントがあり、どちらもxml内で宣言的に作成しました。

Stringユーザーが入力しFragment Aたテキストをのテキストビューに渡そうとしていますFragment B。ただし、これは非常に困難であることが証明されています。誰かが私がこれを達成する方法を知っていますか?

フラグメントは、を使用してそのアクティビティへの参照を取得できることを認識していgetActivity()ます。だから私はそこから始めると思いますか?

4

14 に答える 14

126

Android 開発者ページをご覧ください: http://developer.android.com/training/basics/fragments/communicating.html#DefineInterface

基本的に、フラグメント A でインターフェイスを定義し、アクティビティにそのインターフェイスを実装させます。Fragment でインターフェイス メソッドを呼び出すと、Activity がイベントを受け取ります。アクティビティで、2 番目の Fragment を呼び出して、受け取った値でテキストビューを更新できます。

あなたのアクティビティはあなたのインターフェースを実装します (以下の FragmentA を参照してください)

public class YourActivity implements FragmentA.TextClicked{
    @Override
    public void sendText(String text){
        // Get Fragment B
        FraB frag = (FragB)
            getSupportFragmentManager().findFragmentById(R.id.fragment_b);
        frag.updateText(text);
    }
}

フラグメント A はインターフェイスを定義し、必要に応じてメソッドを呼び出します

public class FragA extends Fragment{

    TextClicked mCallback;

    public interface TextClicked{
        public void sendText(String text);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (TextClicked) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                + " must implement TextClicked");
        }
    }

    public void someMethod(){
        mCallback.sendText("YOUR TEXT");
    }

    @Override
    public void onDetach() {
        mCallback = null; // => avoid leaking, thanks @Deepscorn
        super.onDetach();
    }
}

フラグメント B には、テキストで何かを行うパブリック メソッドがあります。

public class FragB extends Fragment{

    public void updateText(String text){
        // Here you have it
    }
}
于 2012-12-04T10:41:50.027 に答える
4

私の 2 つのフラグメント A と B を考えてみましょう。B から A にデータを渡す必要があるとします。

次に、B でインターフェイスを作成し、メイン アクティビティにデータを渡します。別のインターフェイスを作成し、データをフラグメント A に渡します。

小さな例を共有する:

フラグメントAは次のようになります

public class FragmentA extends Fragment implements InterfaceDataCommunicatorFromActivity {
public InterfaceDataCommunicatorFromActivity interfaceDataCommunicatorFromActivity;
String data;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    return super.onCreateView(inflater, container, savedInstanceState);
}

@Override
public void updateData(String data) {
    // TODO Auto-generated method stub
    this.data = data;
    //data is updated here which is from fragment B
}

@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    try {
        interfaceDataCommunicatorFromActivity = (InterfaceDataCommunicatorFromActivity) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement TextClicked");
    }

}

}

FragmentBは次のようになります

class FragmentB extends Fragment {
public InterfaceDataCommunicator interfaceDataCommunicator;

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);

    // call this inorder to send Data to interface
    interfaceDataCommunicator.updateData("data");
}

public interface InterfaceDataCommunicator {
    public void updateData(String data);
}

@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    try {
        interfaceDataCommunicator = (InterfaceDataCommunicator) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement TextClicked");
    }

}

}

主な活動は

public class MainActivity extends Activity implements InterfaceDataCommunicator {
public InterfaceDataCommunicatorFromActivity interfaceDataCommunicatorFromActivity;

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public void updateData(String data) {
    // TODO Auto-generated method stub
    interfaceDataCommunicatorFromActivity.updateData(data);

}

public interface InterfaceDataCommunicatorFromActivity {
    public void updateData(String data);
}

}
于 2013-10-30T09:59:31.270 に答える
0

Fragment 1.3.0 以降、フラグメント間で通信する新しい方法を利用できるようになりました。

Fragment 1.3.0 の時点で、各 FragmentManager は FragmentResultOwner を実装しています。これは、FragmentManager がフラグメント結果の中央ストレージとして機能できることを意味します。この変更により、チャンクの結果を設定し、それらのコンポーネントが相互に直接参照することなくそれらの結果をリッスンすることで、コンポーネントが相互に通信できるようになります。

フラグメントリスナー:

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResultListener("requestKey") { requestKey, bundle ->
    // We use a String here, but any type that can be put in a Bundle is supported
    val result = bundle.getString("bundleKey")
    // Do something with the result
 }
}

フラグメント エミッター:

button.setOnClickListener {
val result = "result"
// Use the Kotlin extension in the fragment-ktx artifact
setFragmentResult("requestKey", bundleOf("bundleKey" to result))
}
于 2021-11-16T15:24:49.937 に答える
-1

アップデート

この回答は無視してください。うまくいかないわけではありません。しかし、より良い方法があります。さらに、Android は、フラグメント間の直接通信を強く思いとどまらせます。公式ドキュメントを参照してください。ヒントをくれたユーザー @Wahib Ul Haq に感謝します。

元の回答

さて、フラグメント B にプライベート変数とセッターを作成し、フラグメント A 自体から値を設定することができます。

FragmentB.java

private String inputString;
....
....

public void setInputString(String string){
   inputString = string;
}

FragmentA.java

//go to fragment B

FragmentB frag  = new FragmentB();
frag.setInputString(YOUR_STRING);
//create your fragment transaction object, set animation etc
fragTrans.replace(ITS_ARGUMENTS)

または、質問で提案したようにアクティビティを使用できます..

于 2012-12-04T10:33:05.227 に答える