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