hello guys i'm having a problem regarding map fragment, i have integrated google maps into a fragment that get called by drawer Main activity
the problem is that when ever i re-click on you which display map fragment the app crashes, in the fallowing code u'll find Main activity Home fragment which is map fragment, xml
layout and logcat
any help is really appreciated thanks in advance MainActivity
:
package info.androidhive.slidingmenu;
import info.androidhive.slidingmenu.adapter.NavDrawerListAdapter;
import info.androidhive.slidingmenu.model.NavDrawerItem;
import java.util.ArrayList;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.PopupMenu;
import android.widget.Toast;
public class MainActivity extends Activity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
private static int lastClicked = 0;
public static int filterListFunc = 1;
// nav drawer title
private CharSequence mDrawerTitle;
// static var to change filter functionality
public static int filterFunc;
// used to store app title
private CharSequence mTitle;
// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;
private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;
@SuppressLint("NewApi")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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
if (lastClicked == position) {
lastClicked = position;
mDrawerLayout.closeDrawers();
}
displayView(position);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@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_normal:
HomeFragment.setMapType("normal");
return true;
case R.id.action_hyprid:
HomeFragment.setMapType("hyprid");
return true;
case R.id.action_satellite:
HomeFragment.setMapType("satellite");
return true;
case R.id.action_terrain:
HomeFragment.setMapType("terrain");
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_normal).setVisible(!drawerOpen);
return super.onPrepareOptionsMenu(menu);
}
/**
* Diplaying fragment view for selected nav drawer list item
* */
@SuppressLint("NewApi")
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
filterFunc = 1;
fragment = new HomeFragment();
mDrawerLayout.closeDrawers();
break;
case 1:
PopupMenu popup = new PopupMenu(getApplicationContext(),
mDrawerList.getChildAt(1), Gravity.RIGHT + Gravity.RIGHT);
// Inflating the Popup using xml file
popup.getMenuInflater()
.inflate(R.menu.poupup_menu, popup.getMenu());
// registering popup with OnMenuItemClickListener
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
if (filterFunc == 1) {
Toast.makeText(getApplicationContext(),
"You Clicked : " + item.getTitle(),
Toast.LENGTH_SHORT).show();
return true;
} else if (filterFunc == 2) {
if (item.getTitle().equals("Employees")) {
filterListFunc = 1;
Fragment fragment = new PhotosFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment)
.commit();
mDrawerLayout.closeDrawers();
return true;
} else if (item.getTitle().equals("Tickets")) {
filterListFunc = 2;
Fragment fragment = new PhotosFragment();
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment)
.commit();
mDrawerLayout.closeDrawers();
return true;
}
}
return false;
}
});
popup.show();// showing popup menu
mDrawerList.getChildAt(0).setClickable(false);
break;
case 2:
filterFunc = 2;
fragment = new PhotosFragment();
mDrawerLayout.closeDrawers();
break;
case 3:
filterFunc = 0;
fragment = new CommunityFragment();
mDrawerLayout.closeDrawers();
break;
case 4:
filterFunc = 0;
fragment = new PagesFragment();
mDrawerLayout.closeDrawers();
break;
case 5:
filterFunc = 0;
fragment = new WhatsHotFragment();
mDrawerLayout.closeDrawers();
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);
}
}
MapFragment:
package info.androidhive.slidingmenu;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.internal.f;
import android.app.Fragment;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
public class HomeFragment extends Fragment {
// latitude and longitude of an employee just demonstration
// static var get byte image changes into image adapter
public static byte[] iconEmp;
public static Bitmap bitmapfree;
public static Bitmap bitmapBusy;
public static byte[] bitMapData;
public static byte[] bitMapData2;
// Google Map
static GoogleMap googleMap;
public HomeFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container,
false);
// MainActivity e = new MainActivity();
try {
// Loading map
initilizeMap();
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
} catch (Exception ee) {
ee.printStackTrace();
}
return rootView;
}
@Override
public void onResume() {
super.onResume();
initilizeMap();
}
/**
* function to load map If map is not created it will create it for you
* */
void initilizeMap() {
googleMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getActivity(), "Sorry! unable to create maps",
Toast.LENGTH_SHORT).show();
}
// ///----------------------------------Zooming camera to position
// user-----------------
LocationManager locationManager = (LocationManager) getActivity()
.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = locationManager
.getLastKnownLocation(locationManager.getBestProvider(criteria,
false));
if (location != null) {
googleMap
.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(), location
.getLongitude()), 13));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(), location
.getLongitude())) // Sets the center of the map to
// location user
.zoom(14) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(40) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
// -------------------Zooming camera to position
// user-----------------
googleMap.setMyLocationEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
// def employee marker depending on a certain location
// def tickets marker in a certain location
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.free);
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
bitMapData = stream.toByteArray();
Drawable drawable2 = res.getDrawable(R.drawable.buzy);
Bitmap bitmap2 = ((BitmapDrawable) drawable2).getBitmap();
ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
bitmap2.compress(Bitmap.CompressFormat.JPEG, 100, stream2);
bitMapData2 = stream2.toByteArray();
// fill employee data
Employee emp = new Employee("1", "noor ahmad", "Routine", "0796548755",
"Free", 31.0000, 35.0000, "123");
Employee emp1 = new Employee("2", "ahmad mohammed", "Repair",
"0796556457", "NotFree", 31.9869, 35.8715, "123");
Employee emp2 = new Employee("3", "thaer abdullah",
"Preventive Maintenance", "0785461444", "NotFree", 31.9885,
35.8481, "123");
ArrayList<Employee> e = new ArrayList<Employee>();
e.add(emp);
e.add(emp1);
e.add(emp2);
// def ticket's images
Drawable drawableFixed = res.getDrawable(R.drawable.fixed);
Bitmap bitmapFixed = ((BitmapDrawable) drawableFixed).getBitmap();
Drawable drawableunFixed = res.getDrawable(R.drawable.unfixed);
Bitmap bitmapunFixed = ((BitmapDrawable) drawableunFixed).getBitmap();
Drawable drawableUnderM = res.getDrawable(R.drawable.underm);
Bitmap bitmapUnderM = ((BitmapDrawable) drawableUnderM).getBitmap();
// fill tickets data
Tickets tic = new Tickets(1, 1, 1, "Preventive_Maintenance", "",
31.9935, 35.8532, "5/2/2015", "fixed");
Tickets tic1 = new Tickets(2, 2, 2, "Repair", "not working", 31.9920,
35.8540, "5/2/2015", "unfixed");
Tickets tic2 = new Tickets(3, 3, 3, "Preventive_Maintenance", "",
31.9923, 35.8459, "5/2/2015", "under maintainance");
ArrayList<Tickets> t = new ArrayList<Tickets>();
t.add(tic);
t.add(tic1);
t.add(tic2);
// loop around employees and insert markers into the map
for (Employee e1 : e) {
MarkerOptions markerT = new MarkerOptions().position(
new LatLng(e1.getEmpLatitude(), e1.getEmpLongitude()))
.title(e1.getEmpName());
// Changing marker icon
bitmapfree = BitmapFactory.decodeByteArray(bitMapData, 0,
bitMapData.length);
bitmapBusy = BitmapFactory.decodeByteArray(bitMapData2, 0,
bitMapData2.length);
bitmapfree = eraseColor(bitmap, -16777216);
bitmapBusy = eraseColor(bitmap2, -16777216);
if (e1.getEmpWorkState().equals("NotFree")) {
iconEmp = bitMapData2;
markerT.icon(BitmapDescriptorFactory.fromBitmap(bitmapBusy));
} else if (e1.getEmpWorkState().equals("Free")) {
iconEmp = bitMapData;
markerT.icon(BitmapDescriptorFactory.fromBitmap(bitmapfree));
}
// adding employee marker to the map
googleMap.addMarker(markerT);
}
// loop around tickets and insert markers into the map
for (Tickets t1 : t) {
MarkerOptions markerT = new MarkerOptions()
.position(
new LatLng(t1.getTicketLatitude(), t1
.getTicketlongitude())).title(
t1.getTicketCategory());
// Changing marker icon
if (t1.getTicketState().equals("fixed")) {
markerT.icon(BitmapDescriptorFactory.fromBitmap(bitmapFixed));
} else if (t1.getTicketState().equals("unfixed")) {
markerT.icon(BitmapDescriptorFactory.fromBitmap(bitmapunFixed));
} else if (t1.getTicketState().equals("under maintainance")) {
markerT.icon(BitmapDescriptorFactory.fromBitmap(bitmapUnderM));
}
// adding employee marker to the map
googleMap.addMarker(markerT);
}
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
}
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
android.app.FragmentTransaction ft = getActivity().getFragmentManager()
.beginTransaction();
ft.remove(fragment);
ft.commit();
}
@Override
public void onDestroyView() {
super.onDestroyView();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
android.app.FragmentTransaction ft = getActivity().getFragmentManager()
.beginTransaction();
ft.remove(fragment);
ft.commit();
}
public static void setMapType(String n) {
if (n == "normal") {
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
} else if (n == "hyprid") {
googleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
} else if (n == "satellite") {
googleMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
} else if (n == "terrain") {
googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
}
}
// erase bitmap background black
public static Bitmap eraseColor(Bitmap src, int color) {
int width = src.getWidth();
int height = src.getHeight();
Bitmap b = src.copy(Config.ARGB_8888, true);
b.setHasAlpha(true);
int[] pixels = new int[width * height];
src.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 0; i < width * height; i++) {
if (pixels[i] == color) {
pixels[i] = 0;
}
}
b.setPixels(pixels, 0, width, 0, 0, width, height);
return b;
}
}
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/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
LogCat:
another error im getting : this occurs when i click on you twice
i have found the solution for those two problems so the first one: 1-null pointer exception unable to resume activity it occurs when ever i change the phone orientation from landscape to portrait and the solution is to: remove -
@Override
public void onPause() {
// TODO Auto-generated method stub
super.onPause();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
android.app.FragmentTransaction ft = getActivity().getFragmentManager()
.beginTransaction();
ft.remove(fragment);
ft.commit();
}
@Override
public void onDestroyView() {
super.onDestroyView();
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
android.app.FragmentTransaction ft = getActivity().getFragmentManager()
.beginTransaction();
ft.remove(fragment);
ft.commit();
}
from the Map Fragment 2-the second one was the error inflating class fragment which cause duplicates "calling the map fragment twice and loading it twice" and the solution that i've found is to create an if statement controls the loading process:
if(HomeFragment.googleMap != null){
LocationManager locationManager = (LocationManager)getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
Location location = locationManager
.getLastKnownLocation(locationManager.getBestProvider(criteria,
false));
if (location != null) {
HomeFragment.googleMap
.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(location.getLatitude(), location
.getLongitude()), 13));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(location.getLatitude(), location
.getLongitude())) // Sets the center of the map to
// location user
.zoom(14) // Sets the zoom
.bearing(0) // Sets the orientation of the camera to east
.tilt(40) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
HomeFragment.googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
}else{
fragment = new HomeFragment();}
mDrawerLayout.closeDrawers();
break;
and on other cases i added
HomeFragment.googleMap = null;
if the case lead to another fragment and if it doesn't i just let it be. hope this will help others. thank you
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.