AndroidステップアップのFragmentとActivity間のデータインタラクション
13154 ワード
1コンセプト
1なぜ
FragmentはActivityと同様にライフサイクルがあるため,一般的なbeanではなく構造関数を介して値を伝達し,異常をもたらす.
2参照リンク
ActivityとFragmentがデータを渡す2つの方法
【Fragment奥行きシリーズ4】FragmentとActivity間のデータインタラクション
2 Activity Fragmentに値を渡す
2.1最も一般的な方法は、Bundleを使用してパラメータを渡すことです。
(1)宿主Activity/FragmentAdapter:
Bundle bundle = new Bundle();
bundle.putString(Constant.INTENT_ID, productId);
Fragment fragment = null;
switch (position) {
case 0:
fragment = new ProductImageDetailFragment();
break;
case 1:
fragment = new ProductParamFragment();
break;
case 2:
fragment = new ProductCommentFragment();
break;
default:
break;
}
fragment.setArguments(bundle);
(2)Activity/FragmentAdapter:
FragmentのonCreatView/onStart()メソッドでは、getArgments()メソッドでbundleオブジェクトを取得し、getStringのkey値で私たちが渡した値を取得します.
@Override
public void onStart() {
super.onStart();
if (isAdded()) {// Fragment Activity
productId = getArguments().getString(Constant.INTENT_ID);
}
}
2.2第2の方法は、ホストActivityでメソッドを定義し、渡す値をFragmentに渡し、FragmentのonAttachメソッドでこの値を取得することである。
(1)宿主activityにおけるgetTitles()メソッド
public String getTitles(){
return "hello";
}
(2)FragmentにおけるonAttachメソッド
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
titles = ((MainActivity) activity).getTitles();// activity,
}
2.3第三の方法は、Fragmentの作成と数値の伝達を拡張することです。
(1)宿主activityでFragmentを作成する
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.fade_in,android.R.anim.fade_out);
fragment1 = MyFragment.newInstance(" fragment");// , fragment
fragment2 = MyFragment.newInstance(" fragment");
(2)Fragment中
// newInstance()
static MyFragment newInstance(String s){
MyFragment myFragment = new MyFragment();
Bundle bundle = new Bundle();
bundle.putString("DATA",s);
myFragment.setArguments(bundle);
return myFragment;
}
// , onCreatView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//......
Bundle bundle = getArguments();
String data = bundle.getString("DATA");
}
3 Fragment Activityに値を渡す
3.1手順
(1)fragmentに内部コールバックインタフェースを定義し、fragmentを含むactivityにコールバックインタフェースを実装させることで、fragmentはコールバックメソッドを呼び出してactivityにデータを渡すことができる.実はインタフェースコールバックの原理はすべて同じで、以前のブログでは、インタフェースコールバックはjavaの異なるオブジェクト間のデータ相互作用の共通の方法だと話していました.
(2)activity実装済みインタフェースはどのようにさっきのfragmentに伝わりますか?fragmentがactivityに追加されるとfragmentのメソッドonAttach()が呼び出されます.このメソッドでは、activityがOnArticleSelectedListenerインタフェースを実装しているかどうかを確認するのに適しています.チェックメソッドは、受信したactivityのインスタンスをタイプ変換し、fragmentで定義したインタフェースに値を付与することです.
(3)あるfragmentがactivityから剥離されるとonDetachメソッドが呼び出され,このとき伝達されたactivityオブジェクトを解放しなければactivityの破棄に影響し,不要なエラーが発生する.注意onAttachメソッドのコードを見て、付与する前にActivityでこのインタフェースが実装されているかどうかを判断し、instanceofを使用します.インタフェースが実装されていない場合は、例外を放出します.
3.2例
(1)宿主activityでFragmentを作成する
public class MainActivity extends Activity implements MenuFragment.FragmentInteraction{
private TextView textView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView = (TextView) findViewById(R.id.content_text);
}
// 3.2 + ,
@Override
public void process(String str) {
if (str != null) {
textView.setText(str);
}
}
}
(2)Fragment中
public class MenuFragment extends Fragment implements View.OnClickListener {
// 2.1 activity , activity
private FragmentInteraction listterner;
// 1 activity
public interface FragmentInteraction {
void process(String str);
}
// FRagmen activity
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(activity instanceof FragmentInteraction) {
listterner = (FragmentInteraction)activity; // 2.2 activity
} else{
throw new IllegalArgumentException("activity must implements FragmentInteraction");
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_menu, container, false);
View btn = view.findViewById(R.id.tv_button);
View btn_m = view.findViewById(R.id.movie_button);
if (btn != null||btn_m!=null) {
btn.setOnClickListener(this);
btn_m.setOnClickListener(this);
}
return view;
}
@Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.tv_button:
listterner.process(" "); // 3.1
break;
case R.id.movie_button:
listterner.process(" ");
break;
}
}
// activity
@Override
public void onDetach() {
super.onDetach();
listterner = null;
}
}
4 FragmentとFragmentの間の伝達値
ActivityにFragmentをロードする場合、複数のFragmentを使用して切り替え、別のFragment、つまり2つのFragment間でパラメータの伝達を行う場合があります.2つの方法があります.
4.1共通のActivityによる伝達(主な方法)
Activityにフィールドを追加し、その値を保存します.Activityでフィールドを定義し、setメソッドとgetメソッドを追加します.
(1)宿主activityにおいて
public class DemoActivity {
private String mTitle;
public String getmTitle() {
return mTitle;
}
public void setmTitle(String title) {
this.mTitle = title;
}
}
(2)Fragment中
// 、
((DemoActivity)getActivity()).getmTitle();
4.1 Bundleによる伝達(本質はActivity->Fragment)
(1)宿主activityにおいて
ft.hide(getActivity().getSupportFragmentManager().findFragmentByTag(""));
DemoFragment demoFragment = new DemoFragment();
Bundle bundle = new Bundle();
bundle.putString("key", " ");
demoFragment.setArguments(bundle);
ft.add(R.id.fragmentRoot, demoFragment, SEARCHPROJECT);
ft.commit();
(2)Fragment中
String string = getArguments().getString("key");