1

So my main activity contains two fragments. With in the activity_main.xml layout file I have one (List)fragment and then a frame layout which will act as a container for the second fragment.

Each time an item is clicked on the list fragments list view, details corresponding to the item clicked should be displayed with in the second fragment contained in the frame layout.

That is fine, that works. However when I used the fragment transaction reference to create a backStack, the backStack does not work as expected.

What I EXPECTED:

1) user clicks on an item in list view, details corresponding to the itemClicked will be displayed on the second fragment (with in the frame layout).

2) user clicks on another item in list view, the details corresponding to that item will replace the details that were corresponding to the previous click.

3) user clicks the back button and the previous item clicked on the list view will be displayed along with the details corresponding to that item in the second fragment.

What actually OCCURS:

I repeat steps one and two above. However on step 3, the app exits, as in the onStop method is called followed by the onDestroy method.

This is the main Activity.

    import android.app.FragmentTransaction;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;

    public class MainActivity extends AppCompatActivity implements WorkoutListFragment.WorkoutListListener {

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

        @Override
        public void itemClicked(long id) {
            WorkoutDetailFragment details = new WorkoutDetailFragment();
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            details.setWorkout(id);
            ft.replace(R.id.fragment_container, details);
            ft.addToBackStack(null);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            ft.commit();
        }
    }

EDIT:

(LOGCAT REQUIRED BY USER):

08-27 22:18:10.850  12699-12699/? I/art﹕ Not late-enabling -Xcheck:jni (already on)
08-27 22:18:11.088  12699-12716/ramansb.workout D/OpenGLRenderer﹕ Use EGL_SWAP_BEHAVIOR_PRESERVED: true
08-27 22:18:11.092  12699-12699/ramansb.workout D/﹕ HostConnection::get() New Host Connection established 0xb3ee7f00, tid 12699
08-27 22:18:11.106  12699-12699/ramansb.workout D/Atlas﹕ Validating map...
08-27 22:18:11.169  12699-12716/ramansb.workout D/﹕ HostConnection::get() New Host Connection established 0xb3fef0a0, tid 12716
08-27 22:18:11.186  12699-12716/ramansb.workout I/OpenGLRenderer﹕ Initialized EGL, version 1.4
08-27 22:18:11.192  12699-12716/ramansb.workout D/OpenGLRenderer﹕ Enabling debug mode 0
08-27 22:18:11.217  12699-12716/ramansb.workout W/EGL_emulation﹕ eglSurfaceAttrib not implemented
08-27 22:18:11.217  12699-12716/ramansb.workout W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xb3fe5080, error=EGL_SUCCESS

EDIT:

WORKOUT DETAIL FRAGMENT:

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


    public class WorkoutDetailFragment extends Fragment {
        //All fragments require an empty constructor ( no args )
        public WorkoutDetailFragment(){}


        private long workoutId;

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

            if(savedInstanceState != null){
                workoutId = savedInstanceState.getLong("workoutId");
            }

            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_workout_detail, container, false);
        }

        public void onStart() {
            super.onStart();
            View view = getView(); //gets Fragment's root view, gets activity class name
            if (view != null) {
                TextView title = (TextView) view.findViewById(R.id.textTitle);
                Workout workout = Workout.workouts[(int) workoutId];
                title.setText(workout.getName());
                TextView description = (TextView) view.findViewById(R.id.textDescription);
                description.setText(workout.getDescription());
            }
        }

        public void setWorkout(long id){
            this.workoutId = id;
        }

        @Override
        public void onSaveInstanceState(Bundle savedInstanceState) {
            savedInstanceState.putLong("workoutId", workoutId);
        }
    }

WORKOUTLIST FRAGMENT:

    import android.app.Activity;
    import android.app.ListFragment;
    import android.os.Bundle;
    import android.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.ListView;
    import android.widget.TextView;

    /**
     * A simple {@link Fragment} subclass.
     */

    //Extends ListFragment as the fragment is a list fragment
    public class WorkoutListFragment extends ListFragment{


        interface WorkoutListListener{
            void itemClicked(long id);
        }

        private WorkoutListListener listener;


        @Override
        public void onAttach(Activity activity) {
            super.onAttach(activity);
            //The activity has implemented the WorkoutListListener interface therefore it can be casted to a type of WorkoutListListner
            this.listener = (WorkoutListListener) activity;



        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            if(listener != null){
                listener.itemClicked(id);
            }
        }

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

            //Creating array of workout names
            String[] names = new String[Workout.workouts.length];
            for(int i=0; i<names.length; i++){
                names[i] = Workout.workouts[i].getName();
            }
            //Creating ArrayAdapter, such that the ListView(Subclass of adapter view) can use data from a java Array.
            ArrayAdapter<String> listAdapter = new ArrayAdapter<String>(inflater.getContext(), android.R.layout.simple_list_item_1,
                    names);
            setListAdapter(listAdapter);

            return super.onCreateView(inflater, container, savedInstanceState);
            //Calling the super class returns the default layout for ListFragments

        }


    }

WORKOUT CLASS CONTAINING DATA:

public class Workout {

        private String name;
        private String description;

        public static final Workout[] workouts = {
                new Workout("The Limb Loosener", "5 Handstand push-ups\n10 1-legged squats\n15 Pull-ups"),
                new Workout("Core Agony", "100 Pull-ups\n100 Push-ups\n100 Sit-ups\n100 Squats"),
                new Workout("The Wimp Special", "5 Pull-ups\n10 Push-ups\n15 Squats"),
                new Workout("Strength and Length", "500 meter run\n21 x 1.5 pood kettleball swing \n21 x pull-ups")
        };

        //Each Workout has a name and description
        private Workout(String name, String description){
            this.name = name;
            this.description = description;
        }

        public String getDescription(){
            return description;
        }

        public String getName(){
            return name;
        }

        public String toString(){
            return this.name;
        }

        }
RamanSB
  • 1,162
  • 9
  • 26
  • what is the log cat saying ? copy/paste it here please – Tudor Aug 30 '15 at 19:33
  • @PopTudor Logcat added in edit – RamanSB Aug 30 '15 at 19:55
  • I want to see your fragment class because I managed to reproduce your program and to me it's working alright, no problems... – Tudor Aug 30 '15 at 20:09
  • @PopTudor check edit... also are you running it on an avd or a physical device? – RamanSB Aug 30 '15 at 20:13
  • well I don't know what's the problem but here is what I've found: 1- I don't get the crash. 2-if I hit the back button it automatically stops the app by closing the main activity. 3 - overriding the following method stops the activity from being closed until you are left with 0 fragments @Override // public void onBackPressed() { FragmentManager fragmentManager = getFragmentManager(); // fragmentManager.popBackStack(); // if (fragmentManager.getBackStackEntryCount() == 0) // super.onBackPressed(); // } – Tudor Aug 30 '15 at 20:35

1 Answers1

0
@Override
public void onBackPressed() {
        FragmentManager fragmentManager = getFragmentManager();
        fragmentManager.popBackStack();
        if (fragmentManager.getBackStackEntryCount() == 0)
            super.onBackPressed();

    }

also check out this post Use Host GPU. I couldn't get the error by testing on Nexus 7 4.4.4 physical device and Nexus 5 api 21 on emulator

Community
  • 1
  • 1
Tudor
  • 1,510
  • 1
  • 18
  • 17