【问题标题】:Pass Data from Fragment to Fragment Through Button Click通过按钮单击将数据从片段传递到片段
【发布时间】:2023-03-23 10:19:01
【问题描述】:

在我的 Android 应用中,我有两个片段。一个片段有一个 onClickListener ,基本上我想做的是创建一个计数器/日志。每次单击按钮时,我都想更新一个整数,然后将 String.valueOf(integer) 传递给另一个片段中的 TextView。

这是第一个 Fragment,带有 onClickListener:

 public class StartingFragment extends Fragment implements View.OnClickListener {

        public static final String TEA_TYPE_POS = "tea_navdrawer_position";
        public static int COUNT = 0;
        private TeaCounterFragment mTeaCounterFragment;

        // onCreateView method - Returning the layout file
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflating the layout
            View v = inflater.inflate(R.layout.starting_fragment, container, false);


            /* From this point, you do everything in regards to the "v" object */
            Button tea_type1 = (Button) v.findViewById(R.id.tea_type1);
            Button tea_type2 = (Button) v.findViewById(R.id.tea_type2);
            Button tea_type3 = (Button) v.findViewById(R.id.tea_type3);
            Button tea_type4 = (Button) v.findViewById(R.id.tea_type4);
            Button tea_type5 = (Button) v.findViewById(R.id.tea_type5);
            Button tea_type6 = (Button) v.findViewById(R.id.tea_type6);
            Button tea_type7 = (Button) v.findViewById(R.id.tea_type7);
            Button set_timer = (Button) v.findViewById(R.id.set_your_own_timer);




            tea_type1.setText("Oolong");
            tea_type1.setOnClickListener(this);

            tea_type2.setText("White");
            tea_type2.setOnClickListener(this);

            tea_type3.setText("Blooming");
            tea_type3.setOnClickListener(this);

            tea_type4.setText("Black");
            tea_type4.setOnClickListener(this);

            tea_type5.setText("Herbal");
            tea_type5.setOnClickListener(this);

            tea_type6.setText("Green");
            tea_type6.setOnClickListener(this);

            tea_type7.setText("Mate");
            tea_type7.setOnClickListener(this);

            set_timer.setText("Set Your Own Timer");
            set_timer.setOnClickListener(this);

            /* Do your manipulation to your views here, onClick listeners and such */

            // Return the "v" object
            return v;
        }

        @Override
        public void onClick(View view) {
            switch (view.getId()) {
            /*
             * Use the View interface with OnClickListener to get the Button ID's
             * Then you can run a switch on the Buttons (because normally switches
             * cannot be run on buttons
             */

                case R.id.tea_type1:
                    Builder oolongBuilder = new AlertDialog.Builder(StartingFragment.this.getActivity(),
                            AlertDialog.THEME_HOLO_LIGHT);

                    oolongBuilder.setPositiveButton("Hot",
                            //Starts OolongTeaActivity for hot tea when clicked
                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface arg0, int arg1) {
                                    Intent i = new Intent(StartingFragment.this.getActivity(),
                                            OolongTeaActivity.class);
                                    StartingFragment.this.getActivity().startActivity(i);
                                }
                            });

                    oolongBuilder.setNeutralButton("Iced",

                            new DialogInterface.OnClickListener() {

                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Intent i = new Intent(StartingFragment.this.getActivity(),
                                            ColdOolongTeaActivity.class);
                                    StartingFragment.this.getActivity().startActivity(i);

                                }
                            });

                    oolongBuilder.setTitle("Oolong Tea");
                    oolongBuilder.setMessage("How Do You Like Your Tea?");

                    AlertDialog oolongDialog = oolongBuilder.create();
                    oolongDialog.show();

                    COUNT++;
                    Fragment fragment = new Fragment();
                    final Bundle bundle = new Bundle();
                    bundle.putString("id_User", String.valueOf(COUNT));
                    Log.i("BUNDLE", bundle.toString());
                    fragment.setArguments(bundle);

                    break;

以及我希望 valueOf(integer) 转到的片段。

public class TeaCounterFragment extends Fragment {

    public TeaCounterFragment() {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.fragment_tea_counter, container, false);

        TextView oolongCounterText = (TextView) rootView.findViewById(R.id.counter_tv);

        Bundle args = getArguments();
        if (args  != null && args.containsKey("id_User")){
            String userId = args.getString("id_User");
            oolongCounterText.setText(userId);
        }

        return rootView;
    }

我已经意识到 TextView 将恢复到其原始状态,但如果我至少可以在单击按钮后让它更新,那么我可以在以后弄清楚如何永久保存它。

我查看了 Android 开发者文档,确实说两个 Fragment 不应该直接通信,但我不明白为什么我现在使用的方法不应该工作。

编辑:尝试了另一种解决此问题的方法,但我得到了 NullPointerException。我决定在一个 Fragment 中创建一个界面,并通过 NavDrawer (MainActivity) 类,尝试更新 TextView。

pastebin.com/1dx5rEVv (MainActivity) --- pastebin.com/7wKW1zq1 (StartingFragment)

此时,我只想使用任一方法或尚未使用的方法更新 TextView(即使在应用程序完全关闭后仍保留它)。

【问题讨论】:

    标签: java android android-fragments buttonclick pass-data


    【解决方案1】:

    您可以在 Fragments 的 Parent Activity 中使用变量轻松传递数据。将该变量设为静态

    public static Bundle myBundle = new Bundle();
    

    现在从第一个片段更新为

     YourParentActivityName.myBundle.putString("id_User", String.valueOf(COUNT));
    

    现在在第二个片段中,您可以通过

    String myValue = YourParentActivityName.myBundle.get("id_User");
    

    【讨论】:

      【解决方案2】:

      我认为您的“TextView 将设置回其原始状态”的问题在于超时单击按钮,您实例化了一个新的TeaCounterFragment

      在您的第一个片段上,创建一个 TeaCounterFragment 并在您的 onCreate 函数上实例化它。

      public class YourFirstFragment extends Fragment {
      
          private TeaCounterFragment mTeaCounterFragment;
      
          @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
      
              if (savedInstanceState == null) {
                  mTeaCounterFragment = new TeaCounterFragment();
                  getFragmentManager().beginTransaction()
                          .add(R.id.container, mTeaCounterFragment)
                          .commit();
              }
          }
      }
      

      在第一个片段的 onClick 上,只需将其添加到 TeaCounterFragment 上所需的更新中。

      @Override
      public void onClick(View view) {
          ...
          COUNT++;
          mTeaCounterFragment.UpdateCount(COUNT);
          ...
      }
      

      在 TeaCounterFragment 上,创建一个公共函数来更新您的 UI 并使用它修改您的 onCreateView。

      public class TeaCounterFragment extends Fragment {
      
          private TextView mTeaCounterText;
      
          public TeaCounterFragment() {
      
          }
      
          @Override
          public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                   Bundle savedInstanceState) {
      
              View rootView = inflater.inflate(R.layout.fragment_tea_counter, container, false);
              mTeaCounterText = (TextView) rootView.findViewById(R.id.counter_tv);
              return rootView;
          }
      
          public void UpdateCount(int count)
          {
              mTeaCounterText.setText(String.valueOf(count));
          }
      }
      

      希望这能解决您的问题。

      【讨论】:

      • 我这里有点糊涂,因为我有的是两个Fragment,所以没有onCreate()方法,只有onCreateView()
      • 默认情况下,创建的片段上没有 onCreate()。您可以简单地覆盖该函数。
      • 好的。我试过你的方法,它确实有效。但是,有一个问题。我的 TeaCounterFragment 是它自己的片段,当我单击导航抽屉中的第二个项目时会显示它。我的 StartingFragment 是我的应用程序中默认显示的片段,当我单击导航抽屉中的第一项时也是如此。 NavigationDrawer.java 是我的片段的父活动。在您给我的 onCreate() 代码中,它最终同时显示了 StartingFragment 和 TeaCounterFragment,并且没有更新在我的导航抽屉中单击第二个项目后显示的 TeaCounterFragment
      • 然后我建议在你的主要活动中添加 TeaCounterFragment 而不是第一个片段。这样你就可以在你的活动上实现和接口监听器。
      【解决方案3】:

      您正在创建片段类的对象。 您需要创建 TeaCounterFragment 类。

              TeaCounterFragment fragment = new TeaCounterFragment ();
              final Bundle bundle = new Bundle();
              bundle.putString("id_User", String.valueOf(COUNT));
              Log.i("BUNDLE", bundle.toString());
              fragment.setArguments(bundle);
      

      另一个错误可能是你没有使用这个创建的片段对象来展示你的视图。 确保您使用相同的实例来呈现视图。

      【讨论】:

      • 如果在不同的片段中创建相同的实例,我将如何使用它?如果我在另一个名为 StartingFragment 的 Fragment 中实例化一个新的 TeaCounterFragment 对象,我如何使用 TeaCounterFragment 类中的同一个实例。
      • 使用 FragmentManager,最好先通过任何教程来了解 Fragments。
      • 哦。好的。我了解 Fragments,只是我不完全确定如何处理它(+ 心理障碍)
      • 太棒了!,希望这个答案对你有帮助...... :),
      • 我无法让它与这种方法一起工作......我实际上对如何使用 FragmentManager 解决这个问题感到困惑。但是我确实尝试了其他方法,但我得到了 NullPointerException pastebin.com/1dx5rEVv (MainActivity) --- pastebin.com/7wKW1zq1 (StartingFragment)
      【解决方案4】:

      在 Fragment 类中定义接口后,您还需要确保该接口由 Activity 使用片段中的onAttach 方法实现,如下所示:

      @Override
      public void onAttach(Activity activity) {
          super.onAttach(activity);
          try {
              listener = (updateFragment) activity;
          } catch (ClassCastException e) {
              throw new ClassCastException(activity.toString()
                      + " must implement the interface");
          }
      }
      

      然后,要从您的活动中更新片段,请执行以下操作:

      @Override
      public void onButtonClick(String message) {
      
      TeaCounterFragment fragment = new TeaCounterFragment();
      final Bundle bundle = new Bundle();
      bundle.putString("id_User", String.valueOf(COUNT));
      Log.i("BUNDLE", bundle.toString());
      fragment.setArguments(bundle);
      
      FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
      transaction.replace(R.id.fragment_replace, fragment);
      transaction.addToBackStack(null);
      transaction.commit();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-21
        • 1970-01-01
        相关资源
        最近更新 更多