是否存在创建,更新和向Android中的片段或活动传递数据的约定?
我有这个活动( Foo
)来托管这个Fragment( Bar
),它充满了来自另一个Activity的信息。
过程如下:
MainActivity→Bundle→Foo→Bar→收集数据并返回MainActivity。
- 我应该将这些信息存储在
onCreate
的Foo
活动的私有字段中,只是让Fragment使用它们吗? - 我应该直接将Bundle作为参数传递给我的
Bar
Fragment吗? - 我应该从收到的Bundle中创建一个新的Bundle并将新的Bundle传递给Fragment吗?
- 我是否应该在每次数据更改时完全替换整个片段,还是仅在用户不直接提供数据时更新视图,例如通过Dialog?
片段只有一个视图,其值可能会更改,但必须格式化此值(它是从Dialog接收的)。
- 我应该只在我的Activity的私有字段中存储该更改值,并在我必须更新视图或在完成时检索Activity的结果时访问它吗?
- 我应该在这样的视图上实现适配器,以便存储值,但是向用户显示格式化的信息吗?
- 我应该将格式化的值存储在视图中并将其解析回原始值,当我必须返回收集的数据时,我需要接收它所包含的信息吗?
- 我是否应该存储收集的所有信息,用以前收集的信息(使用第一部分中的方法之一)替换新片段?
是否存在涵盖将数据从一个活动传递到另一个活动的约定,以及如何在第二个活动的生命周期中使用数据? 或者至少是某种最佳做法 ?
编辑:
我知道如何做到以上所有要点,所以我不是要求代码; 问题是我发现如何将数据从主活动传递给子活动,如何将其传递给片段以及如何在数据更改的情况下更新片段之间缺乏同质性。
我认为您正在寻找将数据从Fragment bar
传递给Activity foo
方法称为onAttach
。 当活动第一次启动片段并传递给片段本身时,会调用此方法。 为片段用于将数据传递回Activity的活动创建接口。 活动可以直接将数据传递给片段。
-
问题是我发现如何将数据传递给活动之间缺乏同质性
您可以通过接口将数据从片段传递给活动
-
我如何将它传递给片段
通过公共方法直接将数据传递给片段(即如果片段是活动的。如果要实例化一个,请使用Bundle和Arguments)
-
以及如何在数据更改的情况下更新片段
如果活动中的值已更改,并且您希望通知片段显示新内容,请创建公共方法并从活动中调用该方法。 mFragment.updateView();
我知道你没有要求代码,但这是基本概念。
接口:
public interface MyActivityInterface { public void passInformationToActivity(Object obj); }
活动:
public class MyActivity implements MyActivityInterface { private MyFragment myFragment; @Override public void passInformationToActivity(Object obj) { Log.e(TAG, "Information was passed to the activity"); } public void sendInformationToFragment(Object obj) { myFragment.sendInformation(obj); } }
分段:
public class MyFragment extends Fragment { private MyActivityInterface mInterface; @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mInterface = (MyActivityInterface) activity; catch (ClassCastException e) { Log.e(TAG, "Calling activity must implement MyActivityInterface"); throw e; } } @Override public void onDetatch() { super.onDetatch(); mInterface = null; } private void notifyActivityOfObject(Object obj) { mInterface.passInformationToActivity(obj); } public void sendInformation(Object obj) { Log.e(TAG, "Object received by Fragment"); } }
片段可以通过MyActivityInterface
与活动对话,Activity可以通过直接调用公共方法与片段进行通信。
希望这有助于/回答您的问题。 如果没有,我很乐意尝试提供更多帮助
对于Activity – > AnotherActivity
你使用Intents
对于活动 – >片段
在创建时使用setArguments(),最好使用newInstance()方法
class MyFragment extends Fragment { private static final String ARG_1 = "arg1"; private static final String ARG_2 = "arg2"; public static MyFragment newInstance(String arg1, int arg2) { MyFragment fragment = new MyFragment(); Bundle args = new Bundle(); args.putString(ARG_1, arg1); args.putInt(ARG_2, arg2); fragment.setArguments(args); return fragment; } public MyFragment() { // Required empty public constructor } }
要向现有片段发送内容,您可以从FragmentManager引用此片段,或将其保存在Activity中的类范围变量中。 您可以在要调用的片段中定义公共方法。
例如:
class MyFragment extends Fragment { public static final String TAG = "my_fragment_tag"; public void updateSomething(String newValue) { //do what you need here } } class MyActivity extends FragmentActivity { private MyFragment myFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager fragmentManager = getSupportFragmentManager(); myFragment = fragmentManager.findFragmentByTag(MyFragment.TAG); //if it is not null there was configuration change and fragment got recreated //use fragment lifecycle methods to get correct state if(myFragment==null) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); myFragment = MyFragment.newInstance("arg1",2); fragmentTransaction.add(R.id.main, myFragment, MyFragment.TAG); fragmentTransaction.commit(); } } }
在这个例子中,我在myFragment
继续引用MyFragment,所以如果需要,我可以调用myFragment.updateSomething()
来自Activity。
对于片段 – >活动
使用界面
class MyFragment extends Fragment { private OnMyFragmentInteractionListener mListener; public interface OnMyFragmentInteractionListener { public void onMyFragmentInteraction(int arg); } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (OnMyFragmentInteractionListener) activity; } catch (ClassCastException e) { throw new ClassCastException(activity.toString() + " must implement OnMyFragmentInteractionListener"); } } @Override public void onDetach() { super.onDetach(); mListener = null; } public void onSomethinfHappend(int arg) { mListener.onMyFragmentInteraction(arg); } } class MyActivity extends FragmentActivity implements MyFragment.OnMyFragmentInteractionListener { public void onMyFragmentInteraction(int arg) { //receive message from MyFragment } }
对于Fragment – > AnotherFragment
你需要经历活动所以你将拥有
片段 – >活动 – > AnotherFragment
并且您使用上述方法实现它。
另外,您可以从fragment中获取startActivityForResult()
并在片段中接收结果,但如果在Activity
中调用了startActivityForResult()
则片段将不会收到结果。 关于这一点在这里
要回答关于Bundle的问题,如果此包包含数据您需要传递给片段然后是,您可以使用相同的Bundle。 您可以使用newInstance()
方法将Bundle作为参数或重载它。
将数据从活动传递到活动的推荐做法是通过意图捆绑。 对于片段 – 活动或片段 – 片段通信,建议使用接口。 通过两种方式实现将包传递到片段。
- 第一个fragment.setArguments(bundle); 然后提交fragmenttransaction
-
第二种方法是定义一个静态的newInstance()方法。
public class FiveFragment extends Fragment { public FiveFragment() { } // for id public static FiveFragment newInstance(Bundle bundle) { FiveFragment myFragment = new FiveFragment(); myFragment.setArguments(bundle); return myFragment; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.fragment_five, container, false); return view; } @Override public void onStart() { // TODO Auto-generated method stub super.onStart(); if (getArguments() != null) { // bundle arguments fetch } } } }
更新:
我应该创建一个新的Bundle还是通过相同的Bundle
如果您需要的数据已经在当前包中,我认为没有必要创建一个新数据只是为了传递它。
如果数据发生变化,我应该只更新视图,还是应该创建一个新片段并替换上一个片段。
如果数据变化不是那么多,那么更新视图会更好。 但是,如果大多数数据发生变化,那么实例化一个新的片段似乎对我来说是合乎逻辑的。