简体   繁体   中英

Pass Data from Fragment to Fragment Through Button Click

In my Android app, I have two fragments. One fragment has an onClickListener and essentially what I am trying to do is create a counter/log of sorts. Every time a button is clicked, I want to update an integer, and then pass String.valueOf(integer) to a TextView in another fragment.

Here is the first Fragment, with the 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;

And the Fragment to which I want the valueOf(integer) to go.

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;
    }

I've realized that the TextView will set back to its original state, but if I can at least get it to update after a button click, then I can figure out how to save it permanently at a later time.

I've looked at the Android developer documentation, and it does say that two Fragments should not communicate directly, but I don't see why the method I'm using right now shouldn't work.

EDIT: Attempted another way of solving this problem, but I get a NullPointerException. I decided to create an interface in one Fragment, and through the NavDrawer (MainActivity) class, I tried to update the TextView.

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

At this point, I just want to update the TextView (and keep it even after the app is closed completely) using either approach, or an approach that hasn't already been used.

You can easily pass Data by using a Variable in Parent Activity of Fragments. Make that variable as static

public static Bundle myBundle = new Bundle();

Now update it from first fragment as

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

Now in Second fragment you can get this value by

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

I think the problem why your "TextView will set back to its original state" is that overtime the button is clicked, you instantiate a new TeaCounterFragment .

On your First Fragment, create a TeaCounterFragment and instantiate it on your onCreate function.

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();
        }
    }
}

And on the onClick of the first fragment, just add this on your desired update on the TeaCounterFragment.

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

On the TeaCounterFragment, create a public function to update your UI and modify your onCreateView with this.

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));
    }
}

Hope this solves your problem.

You are creating an object of Fragment Class. You need to create of TeaCounterFragment class.

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

Another mistake might be you are not using this created fragment object to present your view. Ensure you are using the same instance to present the view.

After defining an interface in the Fragment class, you also need to make sure the interface is implemented by the activity using the onAttach method in your fragment like this:

@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");
    }
}

Then, to update the fragment from your activity, do this:

@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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM