I have an Activity
with a MapFragment
that I add to the Activity
programmatically using a FragmentTransaction
:
it only lag if you press the back button?
if thats the problem try to block the back button or make it exit the app try this code:
@Override
public void onBackPressed(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("You wanna leave the aplication?").setPositiveButton("Yes", dialogClickListener)
.setNegativeButton("No", dialogClickListener).show();
}
or try this code its a way to put a map fragment inside another fragment (nested Map Fragment) it worked for me a weeks ago:
Java Class:
public class Yourfragment extends Fragment {
private MapView mMapView;
private GoogleMap mMap;
private Bundle mBundle;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
// TODO handle this situation
}
mMapView = (MapView) inflatedView.findViewById(R.id.map);
mMapView.onCreate(mBundle);
setUpMapIfNeeded(inflatedView);
return inflatedView;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBundle = savedInstanceState;
}
private void setUpMapIfNeeded(View inflatedView) {
if (mMap == null) {
mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
}
XML:
<com.google.android.gms.maps.MapView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
put this code on post execute:
View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
// TODO handle this situation
}
mMapView = (MapView) inflatedView.findViewById(R.id.map);
mMapView.onCreate(mBundle);
setUpMapIfNeeded(inflatedView);
return inflatedView;
and call the assynctask on oncreateview
Try this:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Call assyncTask
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBundle = savedInstanceState;
}
private void setUpMapIfNeeded(View inflatedView) {
if (mMap == null) {
mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
private class GetFlightsTask extends AsyncTask<Double, Void, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// if I remove the next line, everything gets fixed
loadingFlightsSpinner.show();
}
@Override
protected String doInBackground(Double... params) {
// some pretty long remote API call
// (loading a JSON file from http://some.website.com/flights?...)
// works fine
String flightsJSON = loadJSON("flights?flyFrom=CZ&to=...");
}
@Override
protected void onPostExecute(String flightsJSON) {
super.onPostExecute(flightsJSON);
loadingFlightsSpinner.dismiss();
// here I do stuff with the JSON and then replace the fragment
dohardwork()
}
public view dohardwork(){
View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
// TODO handle this situation
}
mMapView = (MapView) inflatedView.findViewById(R.id.map);
mMapView.onCreate(mBundle);
setUpMapIfNeeded(inflatedView);
return inflatedView;
}
I have fixed it by dismissing the ProgressDialog
already at the end of the AsyncTask
's doInBackground()
method rather than at the beginning of the onPostExecute()
method.
Which is a bit weird because I actually thought I shouldn't touch things from the UI in the doInBackground()
method... If someone wants to elaborate on it a bit, I would be glad to learn why it works like this.
I have run a simple test:
public class MapFragmentOnBackStackExample extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_fragment_on_back_stack_example);
FragmentManager fm = getSupportFragmentManager();
Fragment f = fm.findFragmentById(R.id.fragment_container);
if (f == null) {
f = SupportMapFragment.newInstance();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(R.id.fragment_container, f);
transaction.commit();
}
}
public void onAddFragmentClick(View view) {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.replace(R.id.fragment_container, new MyFragment());
transaction.addToBackStack(null);
transaction.commit();
}
public static class MyFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
TextView textView = new TextView(getActivity());
textView.setText("MyFragment: " + hashCode());
return textView;
}
}
}
and can't see any problems.
I could see the problem when commented if (f == null) {
leaving it to always create new fragment on rotation, which is obviously wrong, but that brings some suspicions.
Can you see more than 1 MapFragment in memory at the same time? Try using Eclipse Memory Analyzer (MAT).