Preserving the state of Fragments?

476 views Asked by At

I am trying to implement a multiple fragments. Each fragment is viewed in an activity which changes or is replaced when i click my bottom navigation button. Been able to pass the data from frag1 to frag2, however if I click frag2 or any other fragment button the navigation bar i.e. here the stream bar it gets reset and the data is lost.

Here is what I tried out by my self : I implemented onSaveInstanceState in the second fragment, however of no use. Somehow the fragment is getting newly created.

Also tried the solution mentioned here

Just an a idea here is the layout enter image description here

MainActivity

import android.graphics.drawable.Drawable;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.br.tron.bottombar.RadioFragment;
import com.br.tron.bottombar.StreamFragment;
import com.br.tron.bottombar.InfoFragment;

public class MainActivity extends AppCompatActivity implements PushStreamLink{

    BottomNavigationView bottomNavigationView;
    private Fragment fragment;
    private FragmentManager fragmentManager;
    View view;
    //private FragmentTransaction transaction;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        fragmentManager = getSupportFragmentManager();
        fragment = new RadioFragment();
        fragment.setRetainInstance(true);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.main_container, fragment).commit();

        bottomNavigationView = (BottomNavigationView) findViewById(R.id.bottomNavigationBar);
        bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener(){
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                String tag = "";
                switch (item.getItemId()) {
                    case R.id.nav_button_one:
                        fragment = new RadioFragment();
                        fragment.setRetainInstance(true);

                        tag = "radio_fragment";
                        break;
                    case R.id.nav_button_two:
                        fragment = new StreamFragment();
                        fragment.setRetainInstance(true);

                        tag = "stream_fragment";
                        break;
                    case R.id.nav_button_three:
                        fragment = new InfoFragment();
                        fragment.setRetainInstance(true);

                        tag = "info_fragment";
                        break;
                }
                FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.main_container, fragment, tag).commit();

                return true;
            }
        });
    }

    @Override
    public void sendStreamLink(String link) {
        fragment =new StreamFragment();
        fragment.setRetainInstance(true);
        fragmentManager=getSupportFragmentManager();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.main_container, fragment,"stream_fragment").addToBackStack(null).commit();
        getSupportFragmentManager().executePendingTransactions();
        StreamFragment sf=(StreamFragment) getSupportFragmentManager().findFragmentByTag("stream_fragment");
        sf.getUrl(link);
        view = bottomNavigationView.findViewById(R.id.nav_button_two);
        view.performClick();
    }
}

RadioFragment(Frag from which I am sending data)

import android.app.Activity;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

/**
 * Created by Tron on 1/5/2017.
 */

public class RadioFragment extends Fragment implements Button.OnClickListener  {

    Button buttonman;
    View rootView;
    PushStreamLink pushStreamLink;
    Activity a;

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);

        if (context instanceof Activity) {
            //a = (Activity) context;
        }
        if (context instanceof PushStreamLink) {
            pushStreamLink = (PushStreamLink) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement OnFragmentInteractionListener");
        }

    }

    public RadioFragment(){
    };

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

        rootView = inflater.inflate(R.layout.fragment_player, container, false);
        buttonman = (Button)rootView.findViewById(R.id.buttonman);
        buttonman.setOnClickListener(this);
        return rootView;
    }

    @Override
    public void onClick(View v) {
        /*Fragment fragment = new StreamFragment();
        FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.main_container, fragment);
        fragmentTransaction.addToBackStack(null);
        fragmentTransaction.commit();*/
        //((MainActivity)a).performStreamClick();
        pushStreamLink.sendStreamLink("www.zz.com");
    }
}

StreamFragment(frag to which the data is received but is not getting saved in view)

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;


/**
 * Created by Tron on 1/5/2017.
 */

public class StreamFragment extends Fragment {

    String streamUrl="NoLinkFound";
    TextView textView;
    public StreamFragment(){};

    @Override
    public View onCreateView( LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
        View view =  inflater.inflate(R.layout.fragment_stream, container, false);
        if(savedInstanceState==null)
        {

        }
        else
        {
            streamUrl=savedInstanceState.getString("CurrentStreamLink");
            textView =(TextView) getActivity().findViewById(R.id.streamLinkTextView);
            textView.setText(streamUrl);
        }
        return view;
    }

    @Override
    public void onSaveInstanceState(Bundle outState){
        outState.putString("CurrentStreamLink",streamUrl);
        super.onSaveInstanceState(outState);
    }


    @Override
    public void onActivityCreated(Bundle savedInstanceState){
        if (streamUrl!=null) {
//            streamUrl = savedInstanceState.getString("CurrentStreamLink");
            textView = (TextView) getActivity().findViewById(R.id.streamLinkTextView);
            textView.setText(streamUrl);
        }
        super.onActivityCreated(savedInstanceState);
    }

    public void getUrl(String data)
    {
        streamUrl=data;
        if (streamUrl!=null)
        {
            textView=(TextView) getActivity().findViewById(R.id.streamLinkTextView);
            textView.setText(streamUrl);
        }
    }
}
1

There are 1 answers

5
EtherPaul On

instead of

 case R.id.nav_button_three:
                            fragment = new InfoFragment();
    FragmentTransaction transaction = fragmentManager.beginTransaction();
                    transaction.replace(R.id.main_container, fragment, tag).commit();

create instances, for example:

private FragmentManager fragmentManager;
private MyFragment myFragment;

create Fragment manager and all your fragments on MainActivity OnCreate() method, for example:

fragmentManager = getFragmentManager();
myFragment = new MyFragment();

then add method:

public void loadFragment(Fragment fragment) {
        fragmentManager.beginTransaction()
                .replace(R.id.content_frame, fragment)
                .addToBackStack(null)
                .commit();
    }

and after click load the fragment you want:

case R.id.nav_button_three:
loadFragment(myFragment);