【问题标题】:Passing data between fragments contained in an activity在活动中包含的片段之间传递数据
【发布时间】:2015-03-27 19:43:32
【问题描述】:

我有一个包含 3 个片段的活动 A。每个片段相互替换,因此在给定时间只有 1 个可见。

HomeFragment 在 2 个卡片视图中包含 2 个文本视图。每个卡片视图代表一个来自 Fragment1 和 Fragment2 的文本值。当我点击说 Card1 时,我到达 Fragment1。

Fragment1 有一些卡片视图,当我选择其中任何一个时,我会导航回 HomeFragment 并根据我在 Fragment1 中的选择更新卡片视图文本。这是 switch 语句,具体取决于用户选择的卡片,我将其放入捆绑包中并将其传递给 HomeFragment。

 switch (v.getId()) {
        case R.id.card_view0:

            Fragment1Bundle.putString("Test", "Testing");
            bundle.putBundle("Fragment1Bundle", Fragment1Bundle);
            fragmentTransaction.setCustomAnimations(R.anim.slideup, R.anim.slidedown, R.anim.slideup, R.anim.slidedown);
            fragmentTransaction.replace(R.id.content_frame, fragment);
            fragment.setArguments(bundle);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();

            break;

Fragment2 与 Fragment 1 具有相同的行为。

switch (v.getId()) {
        case R.id.card_view0:

            Fragment2Bundle.putString("Test2", "Tetsing");
            bundle.putBundle("Fragment2Bundle", Fragment2Bundle);
            fragmentTransaction.setCustomAnimations(R.anim.slideup, R.anim.slidedown, R.anim.slideup, R.anim.slidedown);
            fragmentTransaction.replace(R.id.content_frame, fragment);
            fragment.setArguments(bundle);
            fragmentTransaction.addToBackStack(null);
            fragmentTransaction.commit();

            break;

我的挑战是我正在使用捆绑包在片段之间传递数据,我的主片段使用来自片段 1 的数据进行更新,但是当我转到片段 2 并在选择返回主片段后,我的片段 1 数据是设置为默认值。这就是我在 Home Fragments onCreateView() 中所做的

  try {
          bundle1 = getArguments().getBundle("Fragment1Bundle");
          bundle2 = getArguments().getBundle("Fragment2Bundle");


          tv.setText(bundle1.getString("Test") == null ? null : bundle1.getString("Test"));

            tv2.setText(bundle2.getString("Test2") == null ? nul : bundle2.getString("Test2"));

   } catch (NullPointerException e) {
        Log.d(TAG, e.printStackTrace());
    }

我知道我在 fragment1 和 fragment2 的片段事务中创建了一个新的 Homefragment,我怎样才能只保留 1 个 Home 片段实例。

【问题讨论】:

  • 我想我会简单地创建一个单独的单例类来保存共享值,然后 fragment1 通过执行类似TextHolder.getInstance().setTest1("Test1") 的操作来写入,类似于 fragment2 TextHolder.getInstance().setTest2("Test2")。最后在您的主片段的onResume 中读取TextHolder.getInstance().getTest1()TextHolder.getInstance().getTest2() 的值。或者,您可以使用 EventBus 之类的东西来保留一个公共对象,但结果最终会大致相同。
  • @Noble6,你目前进展如何?我会做与你的问题类似的事情。
  • @TheOriginalAndroid,我现在正在使用单例模型类并对其进行读写数据。如果您需要任何帮助,请告诉我。
  • @Noble6,我可以理解你使用单例静态(我假设)的技术是如何工作的,对你有好处!但是,当用户按 Home 键或切换到另一个应用程序(不按 Back 键)时,可能会出现问题。

标签: android android-fragments


【解决方案1】:

Google 推荐的另一种设计是使用主 Activity 和 2 个片段(在您的例子中是 Fragment1 和 Fragment2)。我可以看到您将数据包传递给 HomeFragment 的问题。这个建议的设计使用MainActivity,它被声明为静态(范围问题可能需要)。它使用接口在Activity和Fragment之间建立。我认为界面比将 bundle 传回 HomeFragment 更容易。

Google 网页是@Communicating with Other Fragments。这不仅仅是我的意见。我认为一个好的 SO 链接是 How to pass data between fragments

来自网页的代码 sn-p...

Fragment 到 Activity 通信的示例:

public class HeadlinesFragment extends ListFragment {
   OnHeadlineSelectedListener mCallback;

   // Container Activity must implement this interface
   public interface OnHeadlineSelectedListener {
       public void onArticleSelected(int position);
   }
...

Activity 到 Fragment 通信的示例:

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article
    }
}

注意:

  • OnHeadlineSelectedListener是Fragment创建的接口。
  • 创建的方法onArticleSelected有一个参数position,来自ListFragment中的ListView(在示例中)。
  • 您仍然可以设置数据包并在 Activity 和 Fragment 之间发送数据。但是我还没有将数据从 Fragment 发送回 Activity。我通常使用 Fragment 来处理大部分 UI 更新。

【讨论】:

    【解决方案2】:

    如何将值从活动传递到已经打开的片段并更新数组列表请帮助我。当我使用接口时,数组列表大小为零我该怎么办?不要使用捆绑方法。

    公共类 Main2Activity 扩展 AppCompatActivity{

    String desc = "data";
    OnDataPassedListener onDataPassedListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        String passedArg = getIntent().getExtras().getString("id");
        Log.d("data",passedArg);
        Scription scription = new Scription();
        onDataPassedListener = (OnDataPassedListener)scription;
        onDataPassedListener.onDataPassed(passedArg,desc);
    
    }
    public interface OnDataPassedListener {
        void onDataPassed(String text,String name);
    }
    

    }

    public class Test extends Fragment implements 
    

    Main2Activity.OnDataPassedListener{

    。 . . . @覆盖

    public void onDataPassed(String text,String name) {
        monthlylists.get(Integer.valueOf(text)).setFood_type(name);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 1970-01-01
      • 2016-02-11
      • 2016-11-21
      相关资源
      最近更新 更多