Before I start, yes I have read countless related questions. I still can't seem to track down the issue.
I have a SherlockFragmentActivity:
package com.kicklighterdesignstudio.floridaday;
import android.os.Bundle;
import android.support.v4.app.Fragment;
public class FragmentActivity extends BaseActivity {
public static final String TAG = "FragmentActivity";
public static final int SCHEDULE_FRAGMENT = 0;
public static final int MAP_FRAGMENT = 1;
public static final int FOOD_FRAGMENT = 2;
public static final int TWITTER_FRAGMENT = 3;
public static final int HASHTAG_FRAGMENT = 4;
private Fragment mContent;
public FragmentActivity() {
super(R.string.main_activity_title);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_frame);
switchContent(SCHEDULE_FRAGMENT);
setBehindContentView(R.layout.menu_frame);
}
public void switchContent(int id) {
getFragment(id);
getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, mContent)
.commit();
getSlidingMenu().showContent();
}
private void getFragment(int id) {
switch (id) {
case 0:
mContent = new ScheduleFragment();
break;
case 1:
mContent = new FoodFragment();
break;
case 2:
mContent = new MapFragment();
break;
case 3:
mContent = new TwitterFragment();
break;
case 4:
mContent = new HashtagFragment();
break;
}
}
}
It extends BaseActivity:
package com.kicklighterdesignstudio.floridaday;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import com.actionbarsherlock.view.MenuItem;
import com.slidingmenu.lib.SlidingMenu;
import com.slidingmenu.lib.app.SlidingFragmentActivity;
public class BaseActivity extends SlidingFragmentActivity {
// private int mTitleRes;
protected ListFragment mFrag;
public BaseActivity(int titleRes) {
// mTitleRes = titleRes;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setTitle(mTitleRes);
setTitle("");
// set the Behind View
setBehindContentView(R.layout.menu_frame);
if (savedInstanceState == null) {
FragmentTransaction t = this.getSupportFragmentManager().beginTransaction();
mFrag = new MenuFragment();
t.replace(R.id.menu_frame, mFrag);
t.commit();
} else {
mFrag = (ListFragment) this.getSupportFragmentManager().findFragmentById(
R.id.menu_frame);
}
// customize the SlidingMenu
SlidingMenu sm = getSlidingMenu();
sm.setShadowWidthRes(R.dimen.shadow_width);
sm.setShadowDrawable(R.drawable.shadow);
sm.setBehindOffsetRes(R.dimen.slidingmenu_offset);
sm.setFadeDegree(0.35f);
sm.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);
sm.setBehindScrollScale(0.0f);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
toggle();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
Right now, I'm only concerned with ScheduleFragment:
package com.kicklighterdesignstudio.floridaday;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.actionbarsherlock.app.SherlockFragment;
public class ScheduleFragment extends SherlockFragment implements OnItemClickListener {
public static final String TAG = "ScheduleFragment";
private ArrayList<ScheduleItem> schedule;
private FloridaDayApplication app;
public ScheduleFragment() {
// setRetainInstance(true);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
app = (FloridaDayApplication) activity.getApplication();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.schedule_fragment, container, false);
}
@Override
public void onStart() {
super.onStart();
getSherlockActivity().getSupportActionBar().setTitle(R.string.schedule_fragment);
schedule = app.getSchedule();
ListView scheduleListView = (ListView) getActivity().findViewById(R.id.schedule_list);
ScheduleItemAdapter adapter = new ScheduleItemAdapter(getActivity(), schedule);
scheduleListView.setAdapter(adapter);
scheduleListView.setOnItemClickListener(this);
}
@Override
public void onItemClick(AdapterView<?> a, View v, int id, long position) {
Fragment newFragment = new ScheduleItemFragment(id);
FragmentTransaction transaction = getSherlockActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content_frame, newFragment).addToBackStack(null).commit();
}
}
ScheduleFragment displays a list of schedule items. When clicked, a new fragment is displayed (ScheduleItemFragment) to show details of the item and a map to its location:
package com.kicklighterdesignstudio.floridaday;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.model.MarkerOptions;
@SuppressLint("ValidFragment")
public class ScheduleItemFragment extends SherlockFragment {
public static final String TAG = "ScheduleItemFragment";
private int scheduleItemId;
private FloridaDayApplication app;
private ScheduleItem scheduleItem;
private MapView mapView;
private GoogleMap map;
public ScheduleItemFragment(int id) {
scheduleItemId = id;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
app = (FloridaDayApplication) activity.getApplication();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.schedule_item_fragment, container, false);
setHasOptionsMenu(true);
// Initialize MapView
mapView = (MapView) v.findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState);
return v;
}
@Override
public void onStart() {
super.onStart();
scheduleItem = app.getSchedule().get(scheduleItemId);
getSherlockActivity().getSupportActionBar().setTitle(scheduleItem.getTitle());
// Map Stuff
map = mapView.getMap();
if (map != null) {
map.getUiSettings();
map.setMyLocationEnabled(true);
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
// Add marker to the map
MarkerOptions options = new MarkerOptions().position(scheduleItem.getLocation().getPosition()).title(
scheduleItem.getLocation().getTitle());
map.addMarker(options);
// Adjust Camera Programmatically
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
scheduleItem.getLocation().getPosition(), 14);
map.animateCamera(cameraUpdate);
} else {
Log.i(TAG, "Map is null");
}
// Other Views
TextView title = (TextView) getSherlockActivity().findViewById(R.id.title);
TextView time = (TextView) getSherlockActivity().findViewById(R.id.time);
TextView description = (TextView) getSherlockActivity().findViewById(R.id.description);
title.setText(scheduleItem.getTitle());
time.setText(scheduleItem.getDateTimeString());
description.setText(scheduleItem.getDescription());
}
// TODO: Make this work
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
getFragmentManager().popBackStack();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public void onDestroy() {
mapView.onDestroy();
super.onDestroy();
}
@Override
public void onLowMemory() {
mapView.onLowMemory();
super.onLowMemory();
}
@Override
public void onPause() {
mapView.onPause();
super.onPause();
}
@Override
public void onResume() {
mapView.onResume();
super.onResume();
}
@Override
public void onSaveInstanceState(Bundle outState) {
mapView.onSaveInstanceState(outState);
super.onSaveInstanceState(outState);
}
}
Thanks to BaseActivity, the icon in my ActionBar is clickable. It toggles the Sliding Menu. When viewing a ScheduleItemFragment, I would like the icon to return to the previous item in the backstack (which you can see I'm trying to do.) No matter what I try, the icon always toggles the Sliding Menu. Any thoughts on how to guarantee my Fragment gains control of the ActionBar menu clicks?
you need to call setHasOptionsMenu(true);
in onCreate
, not onCreateView
also I'm interested what happens when you debug, does onOptionsItemSelected still get called?
edit: add the following to your fragment
@Override
public void onCreate(Bundle savedInstanceState) {
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
edit1:
there may be a better way to do this but I'm not exactly sure how your fragments are setup out, create a public field in baseActivity public bool isItemFragmentOnTop
now onOptionsItemSelected
in the case of the home button getting press do this
if (isItemFragmentOnTop){
getFragmentManager().popBackStack();
isItemFragmentOnTop = false;
} else {
toggle();
}
return true;
then in your fragment you can call ((BaseActivity)getActivity).isItemFragmentOnTop = true;
to make the home button pop the back stack, you would want to do this when you display your fragment onItemClick in your list view.