フラグメントとそのコンテナアクティビティの間でデータを渡すにはどうすればよいですか?インテントを介してアクティビティ間でデータを渡すことに似たものはありますか?
私はこれを読みましたが、あまり役に立ちませんでした:http :
//developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
フラグメントとそのコンテナアクティビティの間でデータを渡すにはどうすればよいですか?インテントを介してアクティビティ間でデータを渡すことに似たものはありますか?
私はこれを読みましたが、あまり役に立ちませんでした:http :
//developer.android.com/guide/topics/fundamentals/fragments.html#CommunicatingWithActivity
回答:
フラグメントでは、を呼び出すことができますgetActivity()
。
これにより、フラグメントを作成したアクティビティにアクセスできるようになります。そこから、アクティビティ内にあるあらゆる種類のアクセサメソッドを呼び出すことができます。
たとえばgetResult()
、アクティビティで呼び出されるメソッドの場合:
((MyActivity) getActivity()).getResult();
インターフェイスを使用してみてください。
データを含むアクティビティにデータを返す必要があるフラグメントは、データを処理して渡すためのインターフェースを宣言する必要があります。次に、包含アクティビティがこれらのインターフェースを実装していることを確認します。例えば:
JAVA
フラグメントで、インターフェースを宣言します...
public interface OnDataPass {
public void onDataPass(String data);
}
次に、インターフェースの包含クラスの実装を、次のようにonAttachメソッドのフラグメントに接続します。
OnDataPass dataPasser;
@Override
public void onAttach(Context context) {
super.onAttach(context);
dataPasser = (OnDataPass) context;
}
フラグメント内で、データの受け渡しを処理する必要がある場合は、dataPasserオブジェクトで呼び出すだけです。
public void passData(String data) {
dataPasser.onDataPass(data);
}
最後に、実装する アクティビティでOnDataPass
...
@Override
public void onDataPass(String data) {
Log.d("LOG","hello " + data);
}
コトリン
ステップ1.インターフェイスを作成する
interface OnDataPass {
fun onDataPass(data: String)
}
ステップ2.次に、インターフェースの包含クラスの実装を、次のようにonAttachメソッド(YourFragment)のフラグメントに接続します。
lateinit var dataPasser: OnDataPass
override fun onAttach(context: Context) {
super.onAttach(context)
dataPasser = context as OnDataPass
}
ステップ3.フラグメント内で、データの受け渡しを処理する必要がある場合は、dataPasserオブジェクトで呼び出すだけです。
fun passData(data: String){
dataPasser.onDataPass(data)
}
ステップ4.最後に、アクティビティにOnDataPassを実装します
class MyActivity : AppCompatActivity(), OnDataPass {}
override fun onDataPass(data: String) {
Log.d("LOG","hello " + data)
}
ActionBar.TabListener
おり、インターフェースを追加する必要がありました。
最も簡単なアプローチですが推奨されません
フラグメントからアクティビティデータにアクセスできます。
アクティビティ:
public class MyActivity extends Activity {
private String myString = "hello";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
...
}
public String getMyData() {
return myString;
}
}
断片:
public class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
MyActivity activity = (MyActivity) getActivity();
String myDataFromActivity = activity.getMyData();
return view;
}
}
MyActivity
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Bundle b = getActivity().getIntent().getExtras();
wid = b.getString("wid");
rid = b.getString("rid");
View view = inflater.inflate(R.layout.categoryfragment, container, false);
return view;
}
フラグメントとそのコンテナアクティビティの間でデータを受け渡す
アクティビティ:
Bundle bundle = new Bundle();
bundle.putString("message", "Alo Elena!");
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();
断片:
フラグメントの値を読み取る
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("message");
...
...
...
}
これが最善の方法かどうかわかりませんが、Buをフラグメントからコンテナアクティビティに渡す方法を見つけるためにGoogleでかなり長い間検索してきましたが、代わりにアクティビティからフラグメントにデータを送信するだけでした。 (私は初心者なので、少し混乱しました)。
後で私は自分の好きなものを試しました。ここに投稿します。私のような人が同じものを探しています。
// Fragmentからデータを渡します。
Bundle gameData = new Bundle();
gameData.putStringArrayList(Constant.KEY_PLAYERS_ARR,players);
gameData.putString(Constant.KEY_TEAM_NAME,custom_team_name);
gameData.putInt(Constant.KEY_REQUESTED_OVER,requestedOver);
Intent intent = getActivity().getIntent();
intent.putExtras(gameData);
//コンテナのアクティビティからバンドルからデータを取得します。
Bundle gameData = getIntent().getExtras();
if (gameData != null)
{
int over = gameData.getInt(Constant.KEY_REQUESTED_OVER);
ArrayList<String> players = gameData.getStringArrayList(Constant.KEY_PLAYERS_ARR);
String team = gameData.getString(Constant.KEY_TEAM_NAME);
}
else if (gameData == null)
{
Toast.makeText(this, "Bundle is null", Toast.LENGTH_SHORT).show();
}
インターフェイスは最高のソリューションの1つです。
接着インターフェース:
public interface DataProviderFromActivity {
public String getName();
public String getId);
}
MyActivity:
public class MyActivity implements DataProviderFromActivity{
String name = "Makarov";
String id = "sys533";
... ... ... ... ... .... ....
... ... ... ... ... .... ....
public String getName(){
return name;
};
public String getId(){
return id;
};
}
MyFragment:
public class MyFragment extends Fragment{
String fragName = "";
String fragId = "";
... ... ... ... ... .... ....
... ... ... ... ... .... ....
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
DataProviderFromActivity myActivity= (DataProviderFromActivity) getActivity();
fragName = myActivity.getName();
fragId = myActivity.getId();
... ... ... ... ... .... ....
... ... ... ... ... .... ....
updateFragmentView();
}
}
日付リスナーを実装するAppCompatActivityを使用しました。私は日付範囲セレクターをコーディングする必要があったので、フラグメントは必要として来ました。また、選択した日付を受け取って親アクティビティに戻すためのコンテナーも必要でした。
コンテナアクティビティの場合、これはクラス宣言です。
public class AppCompatDateRange extends AppCompatActivity implements
DateIniRangeFragment.OnDateIniSelectedListener, DateFimRangeFragment.OnDateFimSelectedListener
そして、コールバックのインターフェース:
@Override
public void onDateIniSelected(String dataIni) {
Log.i("data inicial:", dataIni);
}
@Override
public void onDateFimSelected(String dataFim) {
Log.i("data final:", dataFim);
}
日付はクエリ選択のパラメータであるため、コールバックは文字列です。
フラグメントのコード(最初の日付フラグメントに基づく):
public class DateIniRangeFragment extends Fragment {
OnDateIniSelectedListener callbackIni;
private DatePicker startDatePicker;
public DateIniRangeFragment() {
///required empty constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
///through this interface the fragment sends data to the container activity
public interface OnDateIniSelectedListener {
void onDateIniSelected(String dataIni);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
///layout for the fragment
View v = inflater.inflate(R.layout.date_ini_fragment, container, false);
///initial date for the picker, in this case, current date
startDatePicker = (DatePicker) v.findViewById(R.id.start_date_picker_appcompat);
Calendar c = Calendar.getInstance();
int ano = c.get(Calendar.YEAR);
int mes = c.get(Calendar.MONTH);
int dia = c.get(Calendar.DAY_OF_MONTH);
startDatePicker.setSpinnersShown(false);
startDatePicker.init(ano, mes, dia, dateSetListener);
return v;
}
///listener that receives the selected date
private DatePicker.OnDateChangedListener dateSetListener = new DatePicker.OnDateChangedListener() {
public void onDateChanged(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
if (view.isShown()) { ///if the datepicker is on the screen
String sDataIni = year + "-" + (monthOfYear + 1) + "-" + dayOfMonth;
callbackIni.onDateIniSelected(sDataIni); //apply date to callback, string format
}
}
};
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
/*
* this function guarantees that the container activity implemented the callback interface
* */
try {
callbackIni = (OnDateIniSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " deve implementar OnDateIniSelectedListener");
}
}
}
コンテナー+フラグメントを構成するために、FragmentPagerAdapterを拡張するカスタムクラスでViewPager(AppCompat)を使用しました。ダイアログはありません。
単にあなたが使用することができますEventBusを、それは簡単で、作業素晴らしいです
3ステップのEventBus
イベントを定義します。
public static class MessageEvent { /* Additional fields if needed */ }
サブスクライバーの準備:サブスクライブメソッドを宣言して注釈を付け、オプションでスレッドモードを指定します。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
サブスクライバーを登録および登録解除します。たとえばAndroidでは、アクティビティとフラグメントは通常、ライフサイクルに従って登録する必要があります。
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
イベントを投稿:
EventBus.getDefault().post(new MessageEvent());
これは遅いかもしれないことを知っています。しかし、私も常にこの質問に迷っていました。私はこのリンクを共有しています...これはおそらくこれが私がこれについてウェブで見つけた最も良い説明であるためです。これはFragment to ActivityおよびFragment to Fragmentを解決します!
public class Fragmentdemo extends Fragment {
public interface onDemoEventListener {
public void demoEvent(String s);
}
onDemoEventListener demoEventListener;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
demoEventListener = (onDemoEventListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement onDemoEventListener");
}
}
final String LOG_TAG = "TAG";
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragmentdemo, null);
Button button = (Button) v.findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
demoEventListener.someEvent("Test text to Fragment1");
}
});
enter code here
return v;
}
}
別のアクティビティから渡されたデータを、コンテナアクティビティのフラグメントで取得する別の簡単な方法:
Activity_A => Activity_B(フラグメント)
Activity_Aで、別のアクティビティにデータ(ここでは文字列)を送信するようなインテントを作成します。
Intent intent = new Intent(getBaseContext(),Activity_B.class);
intent.putExtra("NAME", "Value");
startActivity(intent);
あなたのフラグメントで、あなたのActivity_Bに含まれています:
String data = getActivity().getIntent().getExtras();
getBaseContext()
次のエラーが表示されます:The method getBaseContext() is undefined for the type new View.OnClickListener(){}