I have been reading every possible threads on stackoverflow for the past two days, and I can't figure out where my issue is... Experiencing a new error every time I bring a "fix"
Before the code, the end state: I'm trying to have a navigation drawer between multiple fragments. One of them is a restaurant search that display search results in a SupportMapFragment.
I don't get errors when I first load my fragment that contains the map, but I get error when I switch to another fragment thanks to NavigationDrawer, and I get an error when I'm pressing the back button, plus many other goodies.
Here is my code:
NavigationDrawer.java
public class NavigationDrawerActivity extends FragmentActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mListFragments;
public static FragmentManager fragmentManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fragmentManager = getSupportFragmentManager();
mTitle = mDrawerTitle = getTitle();
mListFragments = new String[] {"Search","Feed","About","Test"};
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mListFragments));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.navigation_drawer, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch(item.getItemId()) {
default:
return super.onOptionsItemSelected(item);
}
}
public void Logout(MenuItem item) {
SharedPreferences settings = getSharedPreferences(App.PREFS_NAME, 0);
settings.edit().remove("email").apply();
settings.edit().remove("password").apply();
settings.edit().remove("userID").apply();
settings.edit().putBoolean("hasLoggedIn",false).apply();
Intent intent = new Intent(this,LoginActivity.class);
startActivity(intent);
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
}
Fragment fragment;
private void selectItem(int position) {
// update the main content by replacing fragments
switch (position){
// Search engine
// case 0:
// if ( fragment!=null) fragment.onDestroy();
// fragment = new RestaurantSearchFragment();
// break;
// Rating feed
case 1:
// fragment = new RatingFeedTabHostFragment();
// break;
// About screen
case 2:
fragment = new AboutFragment();
break;
case 3:
fragment = new RestaurantSearchFragment2();
break;
default:
fragment = new AboutFragment();
break;
}
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
setTitle(mListFragments[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
fragment_restaurant_search.xml
<!-- Your layouts-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<!--The content you want to add-->
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_search_dark"
android:layout_gravity="center"
android:id="#+id/icon_search"/>
<AutoCompleteTextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:singleLine="true"
android:hint="Enter Restaurant Name"
android:id="#+id/restaurant_search"
android:completionThreshold="1"
android:imeOptions="actionSearch"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/button_search"
android:text="Go!"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_location_found"
android:id="#+id/location_search_image"
android:layout_gravity="center"
/>
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="Near Current Location"
android:singleLine="true"
android:imeOptions="actionSearch"
android:id="#+id/location_search"
android:inputType="none"/>
</LinearLayout>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
<fragment android:name="com.bestpick.bestpickapplication.Screens.NavigationDrawer.RestaurantSearch.RestaurantsListFragment"
android:id="#+id/restaurant_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:layout="#layout/fragment_restaurants"
/>
</LinearLayout>
RestaurantSearchFragment2.java
public class RestaurantSearchFragment2 extends Fragment
{
// Handles to UI widgets
private EditText locationSearchText;
private AutoCompleteTextView restaurantSearch;
private FragmentActivity context;
// sets context from calling Navigation Drawer Activity (FragmentActivity)
#Override
public void onAttach(Activity activity) {
context=(FragmentActivity) activity;
super.onAttach(activity);
}
public static FragmentManager fragmentManager;
private RestaurantMapFragment restaurantMapFragment;
private RestaurantsListFragment restaurantsListFragment;
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_restaurant_search, container, false);
fragmentManager = getChildFragmentManager();
// setting up the restaurant list fragment
restaurantsListFragment = (RestaurantsListFragment) fragmentManager.findFragmentById(R.id.restaurant_fragment);
if (restaurantsListFragment == null) {
restaurantsListFragment = new RestaurantsListFragment();
fragmentManager.beginTransaction().replace(R.id.restaurant_fragment, restaurantsListFragment).commit();
}
// setting up the restaurant map fragment
restaurantMapFragment = (RestaurantMapFragment) fragmentManager.findFragmentById(R.id.map);
if (restaurantMapFragment==null){
restaurantMapFragment = new RestaurantMapFragment();
fragmentManager.beginTransaction().replace(R.id.map,restaurantMapFragment).commit();
}
return view;
}
}
RestaurantFragmentMap.java
public class RestaurantMapFragment extends Fragment {
private static View view;
/**
* Note that this may be null if the Google Play services APK is not
* available.
*/
private static GoogleMap mMap;
private static Double latitude, longitude;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (container == null) {
return null;
}
view = (RelativeLayout) inflater.inflate(R.layout.location_fragment, container, false);
// Passing harcoded values for latitude & longitude. Please change as per your need. This is just used to drop a Marker on the Map
latitude = 26.78;
longitude = 72.56;
setUpMapIfNeeded(); // For setting up the MapFragment
return view;
}
/***** Sets up the map if it is possible to do so *****/
public static void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) NavigationDrawerActivity.fragmentManager
.findFragmentById(R.id.location_map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null)
setUpMap();
}
}
/**
* This is where we can add markers or lines, add listeners or move the
* camera.
* <p>
* This should only be called once and when we are sure that {#link #mMap}
* is not null.
*/
private static void setUpMap() {
// For showing a move to my loction button
mMap.setMyLocationEnabled(true);
// For dropping a marker at a point on the Map
mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title("My Home").snippet("Home Address"));
// For zooming automatically to the Dropped PIN Location
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,
longitude), 12.0f));
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
if (mMap != null)
setUpMap();
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) NavigationDrawerActivity.fragmentManager
.findFragmentById(R.id.location_map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null)
setUpMap();
}
}
#Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
/**** The mapfragment's id must be removed from the FragmentManager
**** or else if the same it is passed on the next time then
**** app will crash ****/
#Override
public void onDestroyView() {
super.onDestroyView();
if (mMap != null) {
RestaurantSearchFragment2.fragmentManager.beginTransaction()
.remove(RestaurantSearchFragment2.fragmentManager.findFragmentById(R.id.location_map)).commitAllowingStateLoss();
mMap = null;
}
}
}
location_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
android:id="#+id/location_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</RelativeLayout>
I have had all the errors in the world, the most fancy that I have right now is:
10-15 23:39:45.786 6568-6568/com.bestpick.bestpickapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bestpick.bestpickapplication, PID: 6568
java.lang.NullPointerException
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:651)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1937)
at android.support.v4.app.Fragment.performDestroy(Fragment.java:1721)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1071)
at android.support.v4.app.FragmentManagerImpl.removeFragment(FragmentManager.java:1218)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:639)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1484)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:450)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
and:
10-15 23:34:54.866 6251-6251/com.bestpick.bestpickapplication E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bestpick.bestpickapplication, PID: 6251
java.lang.RuntimeException: Unable to destroy activity {com.bestpick.bestpickapplication/com.bestpick.bestpickapplication.Screens.NavigationDrawer.NavigationDrawerActivity}: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3497)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3515)
at android.app.ActivityThread.access$1400(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1249)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
at android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1360)
at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1378)
at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)
at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)
at com.bestpick.bestpickapplication.Screens.NavigationDrawer.RestaurantSearch.RestaurantMapFragment.onDestroyView(RestaurantMapFragment.java:120)
at android.support.v4.app.Fragment.performDestroyView(Fragment.java:1709)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1011)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
at android.support.v4.app.FragmentManagerImpl.dispatchDestroyView(FragmentManager.java:1932)
at android.support.v4.app.Fragment.performDestroyView(Fragment.java:1706)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1011)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1121)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1103)
at android.support.v4.app.FragmentManagerImpl.dispatchDestroy(FragmentManager.java:1938)
at android.support.v4.app.FragmentActivity.onDestroy(FragmentActivity.java:336)
at android.app.Activity.performDestroy(Activity.java:5403)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1117)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3484)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3515)
at android.app.ActivityThread.access$1400(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1249)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
I googled them all, read blogs, stackoverflow... still can't figure out anything!
Thanks for your much appreciated help
Do this for backpress....
#Override
public void onBackPressed(){
android.support.v4.app.FragmentManager fm = this.getSupportFragmentManager();
if(fm.getBackStackEntryCount() > 0) {
fm.popBackStack();
}
else {
}
}
Related
I'm trying to show a google map fragment inside another fragment, however I can't manipulate the map, I already put all the steps that i saw on
the documentation, but i cant manipulate my map.
XML code:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentoPrincipalUsuario">
<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal|top">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="391dp"
class="com.google.android.gms.maps.MapFragment"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_marginTop="60dp" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="149dp"
android:layout_gravity="center_horizontal|bottom">
<Button
android:layout_width="117dp"
android:layout_height="wrap_content"
android:text="pedir taxi"
android:id="#+id/pedirTaxi"
android:layout_gravity="center_horizontal" />
</LinearLayout>
class fragment code:
public class FragmentoPrincipalUsuario extends Fragment implements OnMapReadyCallback {
private OnFragmentInteractionListener mListener;
private List<ParseUser> mChoferes;
private ParseUser mUsuarioActual;
private Button mPedido;
private GoogleMap map;
public FragmentoPrincipalUsuario() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//conseguir usuario actual
// mUsuarioActual = ParseUser.getCurrentUser();
View x = inflater.inflate(R.layout.fragmento_principal_usuario, container, false);
//evento boton pedir taxi
mPedido.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("tipoUsuario", "chofer");
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> choferes, com.parse.ParseException e) {
if (e == null) {
mChoferes = choferes;
String nombreChofer;
for (ParseUser chofer : mChoferes) {
nombreChofer = chofer.getUsername();
ParseObject gameScore = new ParseObject("Viaje");
gameScore.put("cliente", "hola");
gameScore.put("chofer", nombreChofer);
gameScore.put("tomado", false);
gameScore.saveInBackground();
}
} else {
// Something went wrong.
}
}
});
}
});
// Inflate the layout for this fragment
return x;
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
#Override
public void onMapReady(GoogleMap map) {
LatLng sydney = new LatLng(-27.7933121, -64.2574857);
map.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
map.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
Main activity class code:
public class DrawerPrincipal extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener,FragmentoPrincipalUsuario.OnFragmentInteractionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer_principal);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
//cargar fragment principal usuario
Fragment fragmento= null;
fragmento = new FragmentoPrincipalUsuario();
getSupportFragmentManager().beginTransaction()
.replace(R.id.content_main, fragmento)
.commit();
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.pantalla_principal_usuario, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.cuenta) {
// Handle the camera action
} else if (id == R.id.historial_viajes) {
} else if (id == R.id.contacto) {
} else if (id == R.id.compartir) {
} else if (id == R.id.version) {
} else if (id == R.id.salir) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onFragmentInteraction(Uri uri) {
}
}
Edit, after calling getMapAsync(), here is the stack trace:
nullpointer error:
12-18 19:51:50.056 11265-11265/ar.com.taxiexpress.taxiexpress
E/AndroidRuntime: FATAL EXCEPTION: main java.lang.RuntimeException:
Unable to start activity
ComponentInfo{ar.com.taxiexpress.taxiexpress/ar.com.taxiexpress.taxiexpress.DrawerPrincipal}:
java.lang.NullPointerException at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141) at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99) at
android.os.Looper.loop(Looper.java:137) at
android.app.ActivityThread.main(ActivityThread.java:5041) at
java.lang.reflect.Method.invokeNative(Native Method) at
java.lang.reflect.Method.invoke(Method.java:511) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at
dalvik.system.NativeStart.main(Native Method) Caused by:
java.lang.NullPointerException at
ar.com.taxiexpress.taxiexpress.FragmentoPrincipalUsuario.onCreateView(FragmentoPrincipalUsuario.java:61)
at
android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at
android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at
android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at
android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at
android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
at
android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
at
android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1164)
at android.app.Activity.performStart(Activity.java:5114) at
android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2153)
at
android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141) at
android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99) at
android.os.Looper.loop(Looper.java:137) at
android.app.ActivityThread.main(ActivityThread.java:5041) at
java.lang.reflect.Method.invokeNative(Native Method) at
java.lang.reflect.Method.invoke(Method.java:511) at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) at
dalvik.system.NativeStart.main(Native Method)
It looks like the main issue is that you're not calling getMapAsync().
Since you're using a nested SupportMapFragment inside of a Fragment, you will need to use getChildFragmentManager() to get the Map Fragment, and then call getMapAsync().
SupportMapFragment mapFragment = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.map));
mapFragment.getMapAsync(this);
However, while that would work, you would be better off having your Fragment extend SupportMapFragment, that way you wouldn't need to have nested Fragments:
public class MyMapFragment extends SupportMapFragment
implements OnMapReadyCallback {
private GoogleMap mMap;
private Marker marker;
public MyMapFragment () {
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
//remove previously placed Marker
if (marker != null) {
marker.remove();
}
//place marker where user just clicked
marker = mMap.addMarker(new MarkerOptions().position(point).title("Marker")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));
}
});
}
}
I'm having a few issues with my NavigationDrawerwhich I want to run from and Activitywhich contains 2 fragments. The idea is that the main fragment will be changed by selecting from the NavigationDrawer
I'm getting the following error when running:
Process: XXXX, PID: 31040
java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.support.v4.widget.DrawerLayout$LayoutParams
at android.support.v4.widget.DrawerLayout.isDrawerView(DrawerLayout.java:1129)
at android.support.v4.widget.DrawerLayout.isDrawerOpen(DrawerLayout.java:1379)
at XXXX.NavigationDrawerFragment.isDrawerOpen(NavigationDrawerFragment.java:117)
at XXXX.EditFactFind.onCreateOptionsMenu(EditFactFind.java:192)
at android.app.Activity.onCreatePanelMenu(Activity.java:2846)
at com.android.internal.policy.PhoneWindow.preparePanel(PhoneWindow.java:567)
at com.android.internal.policy.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:939)
at com.android.internal.policy.PhoneWindow$1.run(PhoneWindow.java:271)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
My activity that contains the fragments XML is:
<?xml version="1.0" encoding="utf-8"?>
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="XXXX.MainActivity">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/fragment_container"
android:layout_alignParentBottom="true">
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
If you're not building against API 17 or higher, use
android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
the container. -->
<fragment
android:id="#+id/navigation_drawer"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="XXXX.NavigationDrawerFragment"
tools:layout="#layout/fragment_navigation_drawer" />
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:id="#+id/editFactFindTop"
android:name="XXXX.editFactFind_top"
tools:layout="#layout/fragment_edit_fact_find_top"/>
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="3"
android:id="#+id/fragment_editFactFind"
android:name="XXXX.secA_pg1"
tools:layout="#layout/fragment_sec_a_pg1" />
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
My NavigationDrawer XML is:
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#cccc"
tools:context=".NavigationDrawerFragment" />
My Top fragment XML is:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="XXXX.editFactFind_top">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="#+id/fragment_container"
android:layout_alignParentBottom="true">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="#string/titleEditText"
android:id="#+id/titleViewText" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/titleViewText"
android:layout_alignBaseline="#id/titleViewText"
android:id="#+id/titleEditText"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/titleEditText"
android:layout_alignBaseline="#id/titleViewText"
android:layout_alignParentRight="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_marginLeft="20dp"
android:text="#string/dateTextView"
android:id="#id/dateTextView"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/saveButton"
android:id="#id/saveButton"
android:layout_below="#id/titleEditText"
android:layout_marginTop="50dp"
android:visibility="visible" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/cancelButton"
android:layout_marginLeft="10dp"
android:id="#id/cancelButton"
android:layout_toRightOf="#id/saveButton"
android:layout_alignBaseline="#id/saveButton"
android:visibility="visible" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Next"
android:id="#+id/nextButton"
android:layout_alignBaseline="#id/cancelButton"
android:layout_toRightOf="#id/cancelButton"/>
</RelativeLayout>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
My main fragment XML is:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="XXXX.secA_pg1">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:text="#string/Sec_A_pg1_fragment"
android:id="#+id/Sec_A_pg1_fragment"
android:layout_below="#id/nextButton"/>
</RelativeLayout>
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
My editFactFind java is:
public class EditFactFind extends Activity implements NavigationDrawerFragment.NavigationDrawerCallbacks {
public static final int RESULT_DELETE = -500;
private boolean isInEditMode = true;
private boolean isAddingFactFind = true;
private NavigationDrawerFragment mNavigationDrawerFragment;
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.edit_factfind);
final Button saveButton = (Button)findViewById(R.id.saveButton);
final Button cancelButton = (Button)findViewById(R.id.cancelButton);
final EditText titleEditText = (EditText)findViewById(R.id.titleEditText);
//final EditText factFindEditText = (EditText)findViewById(R.id.factFindEditText);
final TextView dateTextView = (TextView)findViewById(R.id.dateTextView);
final Button nextButton =(Button) findViewById(R.id.nextButton);
//Create fragment and give it an argument for the selected article
secA_pg1 iniSecFrag = new secA_pg1();
Bundle args = new Bundle();
args.putInt(secA_pg1.ARG_INDEX, 1);
iniSecFrag.setArguments(args);
FragmentTransaction initialTransaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
//initialTransaction.replace(R.id.fragment_container, iniSecFrag);
// initialTransaction.addToBackStack(null);
// Fragment iniSecFrag = new secA_pg1();
initialTransaction.add(R.id.fragment_container, iniSecFrag);
//Commit the transaction
initialTransaction.commit();
mNavigationDrawerFragment = (NavigationDrawerFragment)
getFragmentManager().findFragmentById(R.id.navigation_drawer); // Activity_nav_drawer.xml
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
Serializable extra = getIntent().getSerializableExtra("FactFind");
if(extra != null)
{
FactFind factFind = (FactFind) extra;
titleEditText.setText(factFind.getTitle());
// factFindEditText.setText(factFind.getFactFindTitle());
DateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
String date = dateFormat.format(factFind.getDate());
dateTextView.setText(date);
isInEditMode = false;
titleEditText.setEnabled(false);
// factFindEditText.setEnabled(false);
saveButton.setText("Edit");
isAddingFactFind = false;
}
cancelButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
setResult(RESULT_CANCELED, new Intent());
finish();
}
});
nextButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//secA_pg1 secFrag = (secA_pg1) getFragmentManager().findFragmentById(R.id.Sec_A_pg1_fragment);
//Create fragment and give it an argument for the selected article
secA_pg2 newSecFrag = new secA_pg2();
Bundle args = new Bundle();
args.putInt(secA_pg2.ARG_INDEX, 2);
newSecFrag.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack so the user can navigate back
transaction.replace(R.id.fragment_editFactFind, newSecFrag);
transaction.addToBackStack(null);
//Commit the transaction
transaction.commit();
}
});
saveButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if(isInEditMode)
{
Intent returnIntent = new Intent();
FactFind factFind = new FactFind(titleEditText.getText().toString(),Calendar.getInstance().getTime());
returnIntent.putExtra("FactFind", factFind);
setResult(RESULT_OK, returnIntent);
finish();
}
else
{
isInEditMode = true;
saveButton.setText("Save");
titleEditText.setEnabled(true);
// factFindEditText.setEnabled(true);
}
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.are_you_sure_you_want_to_delete_this_fact_find_it_can_t_be_undone_);
builder.setTitle("Confirm Delete");
builder.setPositiveButton("Delete", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent returnIntent = new Intent();
setResult(RESULT_DELETE, returnIntent);
finish();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
builder.create().show();
return false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.nav_drawer, menu);
restoreActionBar();
return true;
}
else {
//return super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.action_menu, menu);
return true;
}
}
//#Override
public void onSelectedFragChanged(int index) {
FragmentManager fragmentManager = getFragmentManager();
secA_pg1 secA_pg1 = (secA_pg1) fragmentManager.findFragmentById(R.id.Sec_A_pg1_fragment);
secA_pg1.setSectionTitle(index);
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
//actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public void onNavigationDrawerItemSelected(int position) {
}
}
and finally my NavigationDrawerFragment java is
/**
* Fragment used for managing interactions for and presentation of a navigation drawer.
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
* design guidelines</a> for a complete explanation of the behaviors implemented here.
*/
public class NavigationDrawerFragment extends Fragment {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
public NavigationDrawerFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Indicate that this fragment would like to influence the set of actions in the action bar.
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mDrawerListView = (ListView) inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
mDrawerListView.setAdapter(new ArrayAdapter<String>(
getActionBar().getThemedContext(),
android.R.layout.simple_list_item_activated_1,
android.R.id.text1,
new String[]{
getString(R.string.title_section1),
getString(R.string.title_section2),
getString(R.string.title_section3),
"Assets",
"ID",
}));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return mDrawerListView;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* #param fragmentId The android:id of this fragment in its activity's layout.
* #param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
// mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle = new ActionBarDrawerToggle(
getActivity(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
// R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) {
return;
}
// getActivity().InvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) {
return;
}
if (!mUserLearnedDrawer) {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
// getActivity().InvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If the drawer is open, show the global app actions in the action bar. See also
// showGlobalContextActionBar, which controls the top-left area of the action bar.
if (mDrawerLayout != null && isDrawerOpen()) {
inflater.inflate(R.menu.global, menu);
// showGlobalContextActionBar();
}
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
if (item.getItemId() == R.id.action_example) {
Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
*/
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
//actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(R.string.app_name);
}
private ActionBar getActionBar() {
return ((Activity) getActivity()).getActionBar();
}
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public static interface NavigationDrawerCallbacks {
/**
* Called when an item in the navigation drawer is selected.
*/
void onNavigationDrawerItemSelected(int position);
}
}
I've attempted several things and from research and the error I believe one of my XML files is incorrectly laid out and it sees it as a Frame Layout instead of a drawer but I can't figure out exactly where. I've tried amending the layouts in many ways but have had no luck.
Thanks :)
It looks like there's a few things wrong here, unless I'm missing something more complex that you're trying to achieve.
First, when you're using this DrawerLayout, it should have the content and the drawer in separate sections, whereas here everything is grouped under one FrameLayout. The basic structure of the XML would be something like:
<android.support.v4.widget.DrawerLayout>
<FrameLayout>
your main content stuff here
</FrameLayout>
<FrameLayout>
navigationdrawer stuff here
</FrameLayout>
</android.support.v4.widget.DrawerLayout>
They don't have to both be FrameLayouts, but the important thing is that there are two child views and they are in that order. Have a look at the guidance here.
The other main structural thing is that you don't need a DrawerLayout in all of your Fragments as well. The DrawerLayout belongs to the Activity, each fragment can just show its contents.
I believe that your problem is that the FrameLayout content's elements shouldn't contain any other views in your layouts.
For example, in your main fragment, your layout should look like this:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="XXXX.secA_pg1">
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView android:layout_width="match_parent" android:layout_height="match_parent"
android:text="#string/Sec_A_pg1_fragment"
android:id="#+id/Sec_A_pg1_fragment"
android:layout_below="#id/nextButton"/>
</RelativeLayout>
</android.support.v4.widget.DrawerLayout>
And keep in mind that when calling the isDrawerOpen(View drawer) method, you should pass as the parameter the RelativeLayout (in this example), that's actually the drawer view and also that this view must specify its horizontal gravity with the android:layout_gravity attribute.
I base my answer in the official documentation of DrawerLayout:
https://developer.android.com/training/implementing-navigation/nav-drawer.html
I Created a Navigation Drawer project from Android Studio. Now I want to add a linear layout to my navigation Drawer. So i Added it. But it shows a Error like this
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.arul.anatotion/com.arul.anatotion.Navigation}: android.view.InflateException: Binary XML file line #28: Error inflating class fragment
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #28: Error inflating class fragment
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290)
at android.app.Activity.setContentView(Activity.java:1929)
at com.arul.anatotion.Navigation.onCreate(Navigation.java:38)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.ListView
at com.arul.anatotion.NavigationDrawerFragment.onCreateView(NavigationDrawerFragment.java:92)
at android.app.Fragment.performCreateView(Fragment.java:1700)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:866)
at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1040)
at android.app.FragmentManagerImpl.addFragment(FragmentManager.java:1142)
at android.app.Activity.onCreateView(Activity.java:4786)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:290)
at android.app.Activity.setContentView(Activity.java:1929)
at com.arul.anatotion.Navigation.onCreate(Navigation.java:38)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$800(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
on NavigationDrawerFragment
I referred this answer but it is of no use Add EditText on Navigation Drawer Android
fragment_navigation Drawer
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView"
android:src="#drawable/ic_launcher"/>
<TextView
android:id="#+id/section_label"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:layout_marginTop="20dp"
android:layout_marginLeft="20dp"
android:textStyle="bold" />
</LinearLayout>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#FFFFFF"
android:dividerHeight="0dp"
tools:context=".NavigationDrawerFragment" />
</LinearLayout>
NavigationDrawerFragment
public class NavigationDrawerFragment extends Fragment {
/**
* Remember the position of the selected item.
*/
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
/**
* Per the design guidelines, you should show the drawer on launch until the user manually
* expands it. This shared preference tracks this.
*/
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
/**
* A pointer to the current callbacks instance (the Activity).
*/
private NavigationDrawerCallbacks mCallbacks;
/**
* Helper component that ties the action bar to the navigation drawer.
*/
private ActionBarDrawerToggle mDrawerToggle;
private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private View mFragmentContainerView;
private int mCurrentSelectedPosition = 0;
private boolean mFromSavedInstanceState;
private boolean mUserLearnedDrawer;
public NavigationDrawerFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Read in the flag indicating whether or not the user has demonstrated awareness of the
// drawer. See PREF_USER_LEARNED_DRAWER for details.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
if (savedInstanceState != null) {
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
mFromSavedInstanceState = true;
}
// Select either the default item (0) or the last selected item.
selectItem(mCurrentSelectedPosition);
}
#Override
public void onActivityCreated (Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Indicate that this fragment would like to influence the set of actions in the action bar.
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mDrawerListView = (ListView) inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
selectItem(position);
}
});
mDrawerListView.setAdapter(new ArrayAdapter<String>(
getActionBar().getThemedContext(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
new String[]{
getString(R.string.title_section1),
getString(R.string.title_section2),
getString(R.string.title_section3),
}));
mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
return mDrawerListView;
}
public boolean isDrawerOpen() {
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
}
/**
* Users of this fragment must call this method to set up the navigation drawer interactions.
*
* #param fragmentId The android:id of this fragment in its activity's layout.
* #param drawerLayout The DrawerLayout containing this fragment's UI.
*/
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
mFragmentContainerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the navigation drawer and the action bar app icon.
mDrawerToggle = new ActionBarDrawerToggle(
getActivity(), /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
) {
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
if (!isAdded()) {
return;
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (!isAdded()) {
return;
}
if (!mUserLearnedDrawer) {
// The user manually opened the drawer; store this flag to prevent auto-showing
// the navigation drawer automatically in the future.
mUserLearnedDrawer = true;
SharedPreferences sp = PreferenceManager
.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).apply();
}
getActivity().invalidateOptionsMenu(); // calls onPrepareOptionsMenu()
}
};
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
// per the navigation drawer design guidelines.
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
mDrawerLayout.openDrawer(mFragmentContainerView);
}
// Defer code dependent on restoration of previous instance state.
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
private void selectItem(int position) {
mCurrentSelectedPosition = position;
if (mDrawerListView != null) {
mDrawerListView.setItemChecked(position, true);
}
if (mDrawerLayout != null) {
mDrawerLayout.closeDrawer(mFragmentContainerView);
}
if (mCallbacks != null) {
mCallbacks.onNavigationDrawerItemSelected(position);
}
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallbacks = (NavigationDrawerCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
}
}
#Override
public void onDetach() {
super.onDetach();
mCallbacks = null;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Forward the new configuration the drawer toggle component.
mDrawerToggle.onConfigurationChanged(newConfig);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// If the drawer is open, show the global app actions in the action bar. See also
// showGlobalContextActionBar, which controls the top-left area of the action bar.
if (mDrawerLayout != null && isDrawerOpen()) {
inflater.inflate(R.menu.global, menu);
showGlobalContextActionBar();
}
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
if (item.getItemId() == R.id.action_example) {
Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Per the navigation drawer design guidelines, updates the action bar to show the global app
* 'context', rather than just what's in the current screen.
*/
private void showGlobalContextActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setTitle(R.string.app_name);
}
private ActionBar getActionBar() {
return getActivity().getActionBar();
}
/**
* Callbacks interface that all activities using this fragment must implement.
*/
public static interface NavigationDrawerCallbacks {
/**
* Called when an item in the navigation drawer is selected.
*/
void onNavigationDrawerItemSelected(int position);
}
}
Navigation .java
public class Navigation extends Activity
implements HomeFragment.OnFragmentInteractionListener, NavigationDrawerFragment.NavigationDrawerCallbacks, NewsFragment.OnFragmentInteractionListener{
#Override
public void onFragmentInteraction(Uri uri) {
}
/**
* Fragment managing the behaviors, interactions and presentation of the navigation drawer.
*/
private NavigationDrawerFragment mNavigationDrawerFragment;
/**
* Used to store the last screen title. For use in {#link #restoreActionBar()}.
*/
private CharSequence mTitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
mNavigationDrawerFragment = (NavigationDrawerFragment)getFragmentManager().findFragmentById(R.id.navigation_drawer);
mTitle = getTitle();
// Set up the drawer.
mNavigationDrawerFragment.setUp(
R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout));
}
#Override
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
FragmentManager fragmentManager = getFragmentManager();
switch(position){
case 0:
HomeFragment homeFragment = new HomeFragment();
fragmentManager.beginTransaction().replace(R.id.container, HomeFragment.newInstance("",""))
.commit();
// Toast.makeText(getApplicationContext(),"Entered",Toast.LENGTH_LONG).show();
break;
case 1:
NewsFragment newsFragment = new NewsFragment();
fragmentManager.beginTransaction()
.replace(R.id.container, NewsFragment.newInstance("",""))
.commit();
// Toast.makeText(getApplicationContext(),"Entered",Toast.LENGTH_LONG).show();
break;
case 2:
Intent intent= new Intent(this,PlayerActivity.class);
startActivity(intent);
}
// fragmentManager.beginTransaction()
// .replace(R.id.container, PlaceholderFragment.newInstance(position + 1))
// .commit();
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}
public void restoreActionBar() {
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(mTitle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
if (!mNavigationDrawerFragment.isDrawerOpen()) {
// Only show items in the action bar relevant to this screen
// if the drawer is not showing. Otherwise, let the drawer
// decide what to show in the action bar.
getMenuInflater().inflate(R.menu.navigation, menu);
restoreActionBar();
return true;
}
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_navigation, container, false);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((Navigation) activity).onSectionAttached(
getArguments().getInt(ARG_SECTION_NUMBER));
}
}
}
Caused by: java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.ListView
In the Fragment's onCreateView() method, you're inflating a layout with a LinearLayout as the root element, then trying to cast it to a ListView. Change the first line in that method to:
View rootView = inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
mDrawerListView = (ListView) rootView.findViewById(R.id.drawer_list);
Then change the return
statement to:
return rootView;
And add the following ID to the ListView in the layout xml:
android:id="#+id/drawer_list"
I have made an android application where in I first login and then show a main activity which has a navigation drawer. The navigation drawer has Home and Profile. The home shows a countdown timer while the profile retrieves the information from database and shows it.
The first time main.class comes it goes to Home and shows the countdown. Then I move to profile. The profile page shows correctly.
Now here it becomes difficult to understand for me. then i go to home (it shows correctly) then profile and then home (there is an error now)
I am not able to figure out why is there an error. Kindly help. I am new to android programming.
MenuFragment.java is the one that shows the countdown.
The error is in line
TextView mTextField = (TextView)getActivity().findViewbById(R.id.welcome);
of MenuFragment.java in third iteration.
Here is the main.class
public class Main extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private TextView mTextField;
private CharSequence mDrawerTitle;
private CharSequence mTitle;
private String[] mMenuTitles;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTitle = mDrawerTitle = getTitle();
mMenuTitles = getResources().getStringArray(R.array.menu_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer);
// set a custom shadow that overlays the main content when the drawer opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this,
R.layout.drawer_list_item, mMenuTitles));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// enable ActionBar app icon to behave as action to toggle nav drawer
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
// ActionBarDrawerToggle ties together the the proper interactions
// between the sliding drawer and the action bar app icon
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
R.string.drawer_open, /* "open drawer" description for accessibility */
R.string.drawer_close /* "close drawer" description for accessibility */
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
selectItem(0);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
/* Called whenever we call invalidateOptionsMenu() */
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// If the nav drawer is open, hide action items related to the content view
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_websearch).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// The action bar home/up action should open or close the drawer.
// ActionBarDrawerToggle will take care of this.
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action buttons
switch(item.getItemId()) {
case R.id.action_websearch:
// create intent to perform web search for this planet
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, getActionBar().getTitle());
// catch event that there's no activity to handle intent
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
} else {
Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* The click listner for ListView in the navigation drawer */
private class DrawerItemClickListener implements ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
selectItem(position);
}
}
private void selectItem(int position) {
// update the main content by replacing fragments
if (position == 1)
{
Fragment fragment = new FragmentProfile();
Bundle args = new Bundle();
args.putInt(FragmentProfile.ARG_MENU_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment, "current_fragment").commit();
}
else
{
Fragment fragment = new MenuFragment();
Bundle args = new Bundle();
args.putInt(MenuFragment.ARG_MENU_NUMBER, position);
fragment.setArguments(args);
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
//timer.cancel();
}
mDrawerList.setItemChecked(position, true);
setTitle(mMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
/**
* Fragment that appears in the "content_frame", shows a planet
*/
}
Here is MenuFragment.java
public class MenuFragment extends Fragment {
public static final String ARG_MENU_NUMBER = "menu_number";
public static boolean ifpause = false;
public static boolean flag = false;
public MenuFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
int i = getArguments().getInt(ARG_MENU_NUMBER);
View rootView;
rootView = inflater.inflate(R.layout.fragment_menu, container, false);
String menu = getResources().getStringArray(R.array.menu_array)[i];
TextView mTextField = (TextView)rootView.findViewById(R.id.welcome);
mTextField.setText("00:00:10");
final CounterClass timer = new CounterClass(10000,1000);
timer.start();
System.out.println(i);
getActivity().setTitle(menu);
return rootView;
}
public void onPause()
{
super.onPause();
ifpause = true;
}
public void onResume() {
super.onResume();
ifpause=false;
flag=true;
}
public class CounterClass extends CountDownTimer {
public CounterClass(long millisInFuture, long countDownInterval)
{
super(millisInFuture, countDownInterval);
}
public TextView mTextField = (TextView)getActivity().findViewById(R.id.welcome);
#Override
public void onFinish()
{
}
#Override
public void onTick(long millisUntilFinished)
{
long millis = millisUntilFinished;
String hms = String.format("%02d:%02d:%02d", TimeUnit.MILLISECONDS.toHours(millis),
TimeUnit.MILLISECONDS.toMinutes(millis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(millis)),
TimeUnit.MILLISECONDS.toSeconds(millis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(millis)));
if(!ifpause)
{
TextView mTextField = (TextView)getActivity().findViewById(R.id.welcome);
mTextField.setText(hms);
}
}
}
}
Logcat
E/AndroidRuntime(4456): FATAL EXCEPTION: main
E/AndroidRuntime(4456): Process: com.example.test, PID: 4456
E/AndroidRuntime(4456): java.lang.NullPointerException
E/AndroidRuntime(4456): at com.example.test.MenuFragment$CounterClass.onTick(MenuFragment.java:108)
E/AndroidRuntime(4456): at android.os.CountDownTimer$1.handleMessage(CountDownTimer.java:124)
E/AndroidRuntime(4456): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(4456): at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime(4456): at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime(4456): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(4456): at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime(4456): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime(4456): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime(4456): at dalvik.system.NativeStart.main(Native Method)
I believe you've got a race condition here.
The fragment has probably been detached from its parent Activity. You'll need to cancel the timer when you are done with it. Probably in onDestroyView.
Make a private member variable to hold onto your timer. Use that when you initialize it in your onCreateView method. Then, make use of it in your overridden onDestroyView method like so:
private CounterClass timer;
#Override
public void onDestroyView()
{
super.onDestroyView();
if (timer != null)
{
timer.cancel();
timer = null;
}
}
In addition, you might want to guard against your fragment not being attached to an Activity in your onTick method by checking for getActivity() == null and returning early in that case.
For more information on the Fragment lifecycle, please look here:
http://developer.android.com/reference/android/app/Fragment.html#Lifecycle
I'm trying to applicate drawernavigation (my first fragment is a map & the others are just some fragments with simple layouts).So it runs fine & I can navigate between my fragments but when I return to the first fragment which is a map I got a crash
logcat:
11-20 11:03:27.306: E/AndroidRuntime(13787): FATAL EXCEPTION: main
11-20 11:03:27.306: E/AndroidRuntime(13787): android.view.InflateException: Binary XML file line #6: Error inflating class fragment
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:697)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
11-20 11:03:27.306: E/AndroidRuntime(13787): at challenge.arabe.taxitaxi.HomeFragment.onCreateView(HomeFragment.java:48)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:828)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1032)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.app.BackStackRecord.run(BackStackRecord.java:622)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.app.FragmentManagerImpl$1.run(FragmentManager.java:426)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.os.Handler.handleCallback(Handler.java:605)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.os.Handler.dispatchMessage(Handler.java:92)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.os.Looper.loop(Looper.java:137)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.app.ActivityThread.main(ActivityThread.java:4511)
11-20 11:03:27.306: E/AndroidRuntime(13787): at java.lang.reflect.Method.invokeNative(Native Method)
11-20 11:03:27.306: E/AndroidRuntime(13787): at java.lang.reflect.Method.invoke(Method.java:511)
11-20 11:03:27.306: E/AndroidRuntime(13787): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
11-20 11:03:27.306: E/AndroidRuntime(13787): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
11-20 11:03:27.306: E/AndroidRuntime(13787): at dalvik.system.NativeStart.main(Native Method)
11-20 11:03:27.306: E/AndroidRuntime(13787): Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Duplicate id 0x7f05000c, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.app.Activity.onCreateView(Activity.java:4253)
11-20 11:03:27.306: E/AndroidRuntime(13787): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:673)
11-20 11:03:27.306: E/AndroidRuntime(13787): ... 18 more
I think this the most impportant:
Duplicate id 0x7f05000c, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
so this is my code:
LoginScreen:a fragmentActivity which make all call for the fragment
public class LoginScreen extends FragmentActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
// nav drawer title
private CharSequence mDrawerTitle;
// used to store app title
private CharSequence mTitle;
// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;
private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;
MapFragment mMap;
GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_screen);
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
if(status == ConnectionResult.SUCCESS) {
// what you want to do
Toast.makeText(getApplicationContext(), "good connection", Toast.LENGTH_SHORT).show();
}
// setUpMapIfNeeded();
// addTwitterMarq();
mTitle = mDrawerTitle = getTitle();
// load slide menu items
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
// nav drawer icons from resources
navMenuIcons = getResources()
.obtainTypedArray(R.array.nav_drawer_icons);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
navDrawerItems = new ArrayList<NavDrawerItem>();
// adding nav drawer items to array
// Home
navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons.getResourceId(0, -1)));
// Find People
navDrawerItems.add(new NavDrawerItem(navMenuTitles[1], navMenuIcons.getResourceId(1, -1)));
// Photos
navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons.getResourceId(2, -1)));
// Communities, Will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons.getResourceId(3, -1), true, "22"));
// Pages
navDrawerItems.add(new NavDrawerItem(navMenuTitles[4], navMenuIcons.getResourceId(4, -1)));
// What's hot, We will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[5], navMenuIcons.getResourceId(5, -1), true, "50+"));
// Recycle the typed array
navMenuIcons.recycle();
mDrawerList.setOnItemClickListener(new SlideMenuClickListener());
// setting the nav drawer list adapter
adapter = new NavDrawerListAdapter(getApplicationContext(),
navDrawerItems);
mDrawerList.setAdapter(adapter);
// enabling action bar app icon and behaving it as toggle button
getActionBar().setDisplayHomeAsUpEnabled(true);
//getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
R.drawable.ic_drawer, //nav menu toggle icon
R.string.app_name, // nav drawer open - description for accessibility
R.string.app_name // nav drawer close - description for accessibility
) {
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
// calling onPrepareOptionsMenu() to show action bar icons
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
// calling onPrepareOptionsMenu() to hide action bar icons
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
// on first time display view for first nav item
displayView(0);
}
}
/**
* Slide menu item click listener
* */
private class SlideMenuClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// display view for selected nav drawer item
displayView(position);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// toggle nav drawer on selecting action bar app icon/title
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
// Handle action bar actions click
switch (item.getItemId()) {
case R.id.action_settings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* *
* Called when invalidateOptionsMenu() is triggered
*/
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menu.findItem(R.id.action_settings).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new HomeFragment();
break;
case 1:
fragment = new FindPeopleFragment();
break;
case 2:
fragment = new PhotosFragment();
break;
case 3:
fragment = new CommunityFragment();
break;
case 4:
fragment = new PagesFragment();
break;
case 5:
fragment = new WhatsHotFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
#Override
public void setTitle(CharSequence title) {
mTitle = title;
getActionBar().setTitle(mTitle);
}
/**
* When using the ActionBarDrawerToggle, you must call it during
* onPostCreate() and onConfigurationChanged()...
*/
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
private void addTwitterMarq() {
// TODO Auto-generated method stub
LatLng pos = new LatLng(48.85078, 2.34440);
googleMap.addMarker(new MarkerOptions()
.title("Twitter")
.snippet("Twitter HQ")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.position(pos)
);
}
private void setUpMapIfNeeded() {
// TODO Auto-generated method stub
if (googleMap == null) {
// Try to obtain the map from the SupportMapFragment.
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
googleMap.setMyLocationEnabled(true);
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
if (googleMap != null) {
// setUpMap();
drawTestJunk();
}
}
}
private void drawTestJunk() {
// TODO Auto-generated method stub
UiSettings settings = googleMap.getUiSettings();
settings.setZoomControlsEnabled(true);
settings.setCompassEnabled(true);
settings.setTiltGesturesEnabled(false);
settings.setMyLocationButtonEnabled(true);
CameraUpdate camUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(45.53, -73.59), 14);
googleMap.moveCamera(camUpdate);
/**
* "Markers" lesson
*/
googleMap.addMarker(new MarkerOptions()
.position(new LatLng(45.538490,-73.598480))
.title("Hello world")
.snippet("what does a snippet look like?")
.draggable(true)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
);
/**
* skipping other "Marker" lessons, to move on to Lines, Polygons, and Circles.
* Topic list for later study:
* - Customized info windows
* - Marker click events
* - Marker drag events
* - Info window click events
*/
/**
* "Lines, Polygons, and Circles" lesson
*/
// LINE
PolylineOptions route = new PolylineOptions()
.add(new LatLng(45.538451240403596, -73.59851807077722) )
.add(new LatLng(45.5390432, -73.5997465) )
.add(new LatLng(45.5387234, -73.6000517) )
.add(new LatLng(45.5389376, -73.6005275) )
.color(Color.GREEN)
;
Polyline polyline = googleMap.addPolyline(route);
//you can also call PolylineOptions.addAll(Iterable<LatLng>) if the points are already in a list
// POLYGON
ArrayList<LatLng> hole= new ArrayList<LatLng>();
hole.add(new LatLng(45.5275, -73.5925));
hole.add(new LatLng(45.5225, -73.5925));
hole.add(new LatLng(45.5225, -73.5975));
hole.add(new LatLng(45.5275, -73.5975));
PolygonOptions rectOptions = new PolygonOptions()
.add(new LatLng(45.53, -73.59),
new LatLng(45.52, -73.59),
new LatLng(45.52, -73.60),
new LatLng(45.53, -73.60),
new LatLng(45.53, -73.59))
.addHole(hole)
.strokeColor(Color.RED)
.fillColor(Color.BLUE);
Polygon polygon = googleMap.addPolygon(rectOptions);
// And sure, why not, a CIRCLE
CircleOptions circleOptions = new CircleOptions()
.center(new LatLng(45.525, -73.595))
.radius(100);
Circle circle = googleMap.addCircle(circleOptions);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.login_screen, menu);
return true;
}
}
and this is my main layout for the fragmentActivity:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Framelayout to display Fragments -->
<FrameLayout
android:id="#+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<!--
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"/>
-->
<!-- Listview to display slider menu -->
<ListView
android:id="#+id/list_slidermenu"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#color/list_divider"
android:dividerHeight="1dp"
android:listSelector="#drawable/list_selector"
android:background="#color/list_background"/>
</android.support.v4.widget.DrawerLayout>
and this is the xml layout of the mapfragment:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment"/>
</RelativeLayout>
and this is the mapfragment code:
public class HomeFragment extends Fragment {
int mCurrentPosition = -1;
MapFragment mMap;
GoogleMap googleMap;
final static String ARG_POSITION = "position";
public HomeFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (savedInstanceState != null) {
mCurrentPosition = savedInstanceState.getInt(ARG_POSITION);
}
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
// int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext());
// if(status == ConnectionResult.SUCCESS) {
// // what you want to do
// //Toast.makeText(getApplicationContext(), "good connection", Toast.LENGTH_SHORT).show();
// }
setUpMapIfNeeded();
addTwitterMarq();
return rootView;
}
private void addTwitterMarq() {
// TODO Auto-generated method stub
LatLng pos = new LatLng(48.85078, 2.34440);
googleMap.addMarker(new MarkerOptions()
.title("Twitter")
.snippet("Twitter HQ")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.position(pos)
);
}
private void setUpMapIfNeeded() {
// TODO Auto-generated method stub
if (googleMap == null) {
// Try to obtain the map from the SupportMapFragment.
googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
googleMap.setMyLocationEnabled(true);
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
if (googleMap != null) {
// setUpMap();
drawTestJunk();
}
}
}
private void drawTestJunk() {
// TODO Auto-generated method stub
UiSettings settings = googleMap.getUiSettings();
settings.setZoomControlsEnabled(true);
settings.setCompassEnabled(true);
settings.setTiltGesturesEnabled(false);
settings.setMyLocationButtonEnabled(true);
CameraUpdate camUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(45.53, -73.59), 14);
googleMap.moveCamera(camUpdate);
/**
* "Markers" lesson
*/
googleMap.addMarker(new MarkerOptions()
.position(new LatLng(45.538490,-73.598480))
.title("Hello world")
.snippet("what does a snippet look like?")
.draggable(true)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
);
/**
* skipping other "Marker" lessons, to move on to Lines, Polygons, and Circles.
* Topic list for later study:
* - Customized info windows
* - Marker click events
* - Marker drag events
* - Info window click events
*/
/**
* "Lines, Polygons, and Circles" lesson
*/
// LINE
PolylineOptions route = new PolylineOptions()
.add(new LatLng(45.538451240403596, -73.59851807077722) )
.add(new LatLng(45.5390432, -73.5997465) )
.add(new LatLng(45.5387234, -73.6000517) )
.add(new LatLng(45.5389376, -73.6005275) )
.color(Color.GREEN)
;
Polyline polyline = googleMap.addPolyline(route);
//you can also call PolylineOptions.addAll(Iterable<LatLng>) if the points are already in a list
// POLYGON
ArrayList<LatLng> hole= new ArrayList<LatLng>();
hole.add(new LatLng(45.5275, -73.5925));
hole.add(new LatLng(45.5225, -73.5925));
hole.add(new LatLng(45.5225, -73.5975));
hole.add(new LatLng(45.5275, -73.5975));
PolygonOptions rectOptions = new PolygonOptions()
.add(new LatLng(45.53, -73.59),
new LatLng(45.52, -73.59),
new LatLng(45.52, -73.60),
new LatLng(45.53, -73.60),
new LatLng(45.53, -73.59))
.addHole(hole)
.strokeColor(Color.RED)
.fillColor(Color.BLUE);
Polygon polygon = googleMap.addPolygon(rectOptions);
// And sure, why not, a CIRCLE
CircleOptions circleOptions = new CircleOptions()
.center(new LatLng(45.525, -73.595))
.radius(100);
Circle circle = googleMap.addCircle(circleOptions);
}
#Override
public void onResume() {
// TODO Auto-generated method stub
super.onResume();
//setUpMapIfNeeded();
//addTwitterMarq();
}
#Override
public void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
outState.putInt(ARG_POSITION, mCurrentPosition);
}
public void updateArticleView(int position) {
mCurrentPosition = position;
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
Bundle args = getArguments();
if (args != null) {
// Set article based on argument passed in
updateArticleView(args.getInt(ARG_POSITION));
} else if (mCurrentPosition != -1) {
// Set article based on saved instance state defined during onCreateView
updateArticleView(mCurrentPosition);
}
}
}
I think that the problem is located in onResume & onCreateView methods!!
Hope that you'll help me
thanks.
use this
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:clickable="true"
/>
and override method onDestroyView() and Just put this code in onDestroyView()
public void onDestroyView()
{
super.onDestroyView();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
}
Try to reuse/recycle your layout.
I am running into "duplicate id" when using a map fragment.
So in onCreateView instead of
final View rootView = inflater.inflate(R.layout.fragment_profile, container, false);
i am using
public class YourFragment extends Fragment {
public YourFragment(){}
...
private static View rootView;
...
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//View rootView = inflater.inflate(R.layout.fragment_layout, container, false);
if (rootView != null) {
ViewGroup parent = (ViewGroup) rootView.getParent();
if (parent != null)
parent.removeView(rootView);
}
try {
rootView = inflater.inflate(R.layout.fragment_layout, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
I think you have to try to retrieve old Fragments instance instead of recreating it each time a drawer item is selected. In your displayView method of LoginScreen Activity, you have to do something like that in the switch:
Fragment fragment = null;
String title = getResources().getString(SOME_FRAGMENT_TITLE);
switch (position) {
case 1:
fragment = (YourFragment) fm.findFragmentByTag(title);
if (fragment == null) fragment = new YourFragment();
break;
}