calling getMap() inside nested mapfragment gives nullpointerexception - java

I have a mapfragment inside a custom fragment, by calling it like in the answer provided here
Unfortunatly there's a NullPointerException, if I call the getMap()-Method (see attached code). Has anybody an idea why? Thanks for your help!
private void initializeMap() {
initializeMapFragment();
try {
// show current location
map.setMyLocationEnabled(true);
map.getUiSettings().setRotateGesturesEnabled(true);
map.getUiSettings().setZoomGesturesEnabled(true);
// adding marker
addDestinationMarker();
// zoom to current location
Location myLocation = map.getMyLocation();
if (myLocation != null) {
LatLng currentPosition = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder().target(currentPosition).zoom(12).build();
map.moveCamera(CameraUpdateFactory.newLatLng(currentPosition));
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void initializeMapFragment() {
MapFragment mapFragment = MapFragment.newInstance();
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag("my_map_fragment") == null) {
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.map_container, mapFragment, "my_map_fragment").commit();
}
map = mapFragment.getMap();
}
EDIT //
The xml of the HomeFragment looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:weightSum="1">
<FrameLayout
android:id="#+id/map_container"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|bottom|left|right|center"
android:background="#drawable/bg_lines"
android:orientation="horizontal">
<Button
android:id="#+id/alarmButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/BlueButtonStyle"
android:text="#string/btn_alarm"/>
</LinearLayout>

Related

Could not find method "startSearch(View)" in a parent or ancestor Context

i try to locate a position, using the Google Maps Api. The Xml shows the Map and in the top a EditText-View + Button.
Thats the xml-file : google_maps_layout
<RelativeLayout xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:ems="13"
android:id="#+id/editText_locationSearch"
android:background="#ffffff"
android:layout_alignBottom="#+id/button_startSearchLocation"
android:layout_alignTop="#+id/button_startSearchLocation"
android:layout_alignParentStart="true"
android:hint="Ort einfügen"
android:textColorHint="#000000"
android:textColor="#000000"
/>
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="group14.event_log.MapsActivity"
android:layout_below="#+id/button_startSearchLocation"
android:layout_alignParentStart="true" />
<Button
android:text="Suche"
android:layout_height="wrap_content"
android:id="#+id/button_startSearchLocation"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
android:onClick="startSearch"
/>
</RelativeLayout>
You can see there is an onClick Method for Button_startSearchLocation.
I definied this method in Maps.Activity.java
private void startSearch(View view){
List<android.location.Address> addressList = null;
EditText location_editText = (EditText) findViewById(R.id.editText_locationSearch);
String location = location_editText.getText().toString();
if(location != null || !location.equals("")){
Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location , 1);
} catch (IOException e) {
e.printStackTrace();
}
android.location.Address address = addressList.get(0);
LatLng lating = new LatLng(address.getLatitude(), address.getLongitude());
mMap.addMarker(new MarkerOptions().position(lating).title("Marker"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(lating));
}
}
Its also the right xml file :
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.google_maps_layout);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
checkGPS(mMap);
}
When I run the application I get this error:
java.lang.IllegalStateException: Could not find method startSearch(View) in
a parent or ancestor Context for android:onClick attribute defined on
view class android.widget.Button with id 'button_startSearchLocation'
I want to know why the xml file cant find the method?
compileSdkVersion 24
buildToolsVersion "25.0.0"
minSdkVersion 19
targetSdkVersion 24
Ok sry Guys. Stupid mistake.
The method should be public.
**public** void startSearch(View view){
List<android.location.Address> addressList = null;
EditText location_editText = (EditText) findViewById(R.id.editText_locationSearch);
String location = location_editText.getText().toString();
if(location != null || !location.equals("")){
Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location , 1);
} catch (IOException e) {
e.printStackTrace();
}
android.location.Address address = addressList.get(0);
LatLng lating = new LatLng(address.getLatitude(), address.getLongitude());
mMap.addMarker(new MarkerOptions().position(lating).title("Marker"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(lating));
}
}

Switching from fragment with map fragment leaves a black screen

I have added a full-screen map fragment to one of my three tabbed fragments. Everything works great apart from an issue I'm experiencing with switching between the tabs.
Each time I switch from the fragment with the map, to one of the other fragments, I get a black screen for like 0.2 seconds. It seems to be a similar issue to the problems with scrolling in an activity with a map fragment.
I've tried adding a transparent view other the top of the map as others have suggested, but it didn't help.
This is my xml:
<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=".ParkMapFragment">
<fragment
android:id="#+id/fullParkMap"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
And this is my code:
public class ParkMapFragment extends Fragment {
public ParkMapFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_map, container, false);
}
#Override
public void onStart(){
super.onStart();
getActivity().setTitle("Map");
}
#Override
public void onDestroyView() {
super.onDestroyView();
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
getFragmentManager().beginTransaction().remove(mapFragment).commit();
}
}
}
Anyone have any suggestions?
Check if the view is null, and if not, remove it from its parent view. That way, you won't see the black screen.
Try the code below.
Fragment:
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
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 android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ExhibhitionMap2 extends Fragment implements OnMapClickListener,OnMarkerClickListener{
View v;
private GoogleMap mMap;
FragmentManager fragmentManager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// android = inflater.inflate(R.layout.activity_exhibhition_map, container, false);
if (v != null) {
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null)
parent.removeView(v);
}
try {
v = inflater.inflate(R.layout.activity_exhibhition_map, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
setUpMapIfNeeded();
return v;
}
/***** Sets up the map if it is possible to do so *****/
public void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
mMap = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map2)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null)
{
mMap.setOnMapClickListener(this);
mMap.setOnMarkerClickListener((OnMarkerClickListener) this);
MarkerOptions marker = new MarkerOptions().position(new LatLng(36.011513,-115.174853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-1");
MarkerOptions marker01 = new MarkerOptions().position(new LatLng(36.111513,-115.204853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-2");
MarkerOptions marker02 = new MarkerOptions().position(new LatLng(36.051513,-115.154853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-3");
MarkerOptions marker03 = new MarkerOptions().position(new LatLng(36.057513,-115.344853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-4");
MarkerOptions marker1 = new MarkerOptions().position(new LatLng(36.081513,-115.224853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-1");
MarkerOptions marker2 = new MarkerOptions().position(new LatLng(36.051513,-115.334853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-2");
MarkerOptions marker3 = new MarkerOptions().position(new LatLng(36.101513,-115.124853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-1");
MarkerOptions marker4 = new MarkerOptions().position(new LatLng(36.031513,-115.154853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-2");
MarkerOptions marker5 = new MarkerOptions().position(new LatLng(36.081513,-115.194853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-2");
mMap.addMarker(marker);
mMap.addMarker(marker01);
mMap.addMarker(marker02);
mMap.addMarker(marker03);
mMap.addMarker(marker1);
mMap.addMarker(marker2);
mMap.addMarker(marker3);
mMap.addMarker(marker4);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.051513,-115.174853), 10.0f));
}
}
}
#Override
public boolean onMarkerClick(Marker marker) {
/*Toast.makeText(getActivity(),
"" + marker.getTitle(), Toast.LENGTH_LONG)
.show();*/
marker.showInfoWindow();
return false;
}
#Override
public void onMapClick(LatLng arg0) {
// TODO Auto-generated method stub
}
public void onDestroy() {
super.onDestroy();
}
}
XML:
<RelativeLayout 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="com.istride.mmps.ContactActivity" >
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tableLayout1"
android:visibility="gone"
android:layout_margin="10dp" >
<TextView
android:id="#+id/tv_Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Bharati Vidyapeeth University's"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Large_Size" />
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_below="#+id/tv_Title"
android:text="Department of Information Technology and Management "
android:textColor="#color/black_text_color"
android:textSize="#dimen/small_size" />
<View
android:id="#+id/view2"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_below="#+id/tv"
android:layout_marginTop="10dp"
android:background="#color/blue_background" />
<RelativeLayout
android:id="#+id/relative"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/view2"
android:layout_marginTop="10dp"
android:background="#color/gray_home">
<TextView
android:id="#+id/textVi1"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/tv_add"
android:layout_alignParentTop="true"
android:background="#color/blue_background"
android:paddingBottom="2dp"
android:paddingLeft="8dp"
android:paddingRight="13dp"
android:paddingTop="2dp"
android:gravity="center_vertical"
android:text="ADDRESS "
android:textColor="#color/white_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#+id/textVi1"
android:paddingBottom="2dp"
android:paddingTop="2dp"
android:text="2nd Floor, Architecture Building, Bharati Vidyapeeth Campus, Dhankawadi, Pune-411043"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Medium_size" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/relativeLayout_call"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/relative"
android:layout_marginTop="10dp"
android:background="#color/gray_home">
<TextView
android:id="#+id/textView1"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/tv_school_office_num"
android:layout_alignParentTop="true"
android:background="#color/blue_background"
android:paddingBottom="2dp"
android:paddingLeft="8dp"
android:paddingRight="13dp"
android:paddingTop="2dp"
android:text="PHONE "
android:gravity="center_vertical"
android:textColor="#color/white_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_school_office_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_toRightOf="#+id/textView1"
android:layout_toLeftOf="#+id/imageView2"
android:textColor="#color/black_text_color"
android:paddingTop="2dp"
android:textSize="#dimen/Medium_size"
android:paddingBottom="2dp"
android:text="+91 989898989 asasa asas asasas ass sdsd asas asas ass assas asas ass " />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="3dp"
android:src="#drawable/ic_call" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/relativeLayout_Email"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/relativeLayout_call"
android:layout_marginTop="10dp"
android:background="#color/gray_home">
<TextView
android:id="#+id/tex1"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView1"
android:layout_alignParentTop="true"
android:background="#color/blue_background"
android:gravity="center_vertical"
android:paddingBottom="2dp"
android:paddingLeft="8dp"
android:paddingRight="13dp"
android:paddingTop="2dp"
android:text="EMAIL "
android:textColor="#color/white_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_school_office_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView1"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:layout_toRightOf="#+id/tex1"
android:textColor="#color/black_text_color"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:textSize="#dimen/Medium_size"
android:text="principal.mmei#eternalmewar.in" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="3dp"
android:src="#drawable/ic_email" />
</RelativeLayout>
</RelativeLayout>
<fragment
android:id="#+id/map2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_marginTop="10dp"
class="com.google.android.gms.maps.SupportMapFragment"
android:background="#color/gray_color"
android:paddingBottom="5dp"
android:layout_above="#+id/footer"
android:textSize="#dimen/small_size" />
<RelativeLayout
android:id="#+id/footer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" >
<TextView
android:id="#+id/blue"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#0000FF"
android:gravity="center"
android:layout_margin="10dp"
android:textColor="#color/black_text_color"
android:textSize="#dimen/small_size"
android:textStyle="bold" />
<TextView
android:id="#+id/parking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/blue"
android:layout_alignTop="#+id/blue"
android:layout_alignBottom="#+id/blue"
android:gravity="center_vertical"
android:text="Parking"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/cyc"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#00FFFF"
android:gravity="center"
android:layout_margin="10dp"
android:layout_toRightOf="#+id/parking"
android:textColor="#color/black_text_color"
android:textSize="#dimen/small_size"
android:textStyle="bold" />
<TextView
android:id="#+id/footer2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/cyc"
android:layout_alignTop="#+id/cyc"
android:layout_alignBottom="#+id/cyc"
android:gravity="center_vertical"
android:text="Food"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>
#Override
public void onDestroyView() {
super.onDestroyView();
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
getFragmentManager().beginTransaction().remove(mapFragment).commit();
}
}
right here you are removing the fragment without replacing it. I would use .replace instead with a new fragment.
Something like this:
getFragmentManager().beginTransaction().replace(R.id.your_placeholder, new CustomFragment(), "cstmFragID").commit();
i would recommend you to use MapView instead of SupportFragment to avoid nested fragment For details answer look at the following post
Should I use MapView or MapFragment
Now your ParkFragment be look like
MapFragment.java
public class MapFragment extends Fragment implements OnMapReadyCallback {
private MapView mMapView;
private GoogleMap mGoogleMap;
public MapFragment() {
// Required empty public constructor
}
public static MapFragment newInstance() {
MapFragment fragment = new MapFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
mMapView = (MapView) rootView.findViewById(R.id.map);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
return rootView;
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
mMapView.onPause();
super.onPause();
}
#Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
#Override
public void onMapReady(GoogleMap googleMap) {
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
}
fragment_map.xml
<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">
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
The problem is possibly because it is recreating Fragment which causes the Black screen. If you are using ViewPager then you can use
// Note that you must set adapter before this line otherwise it can cause NullPointerException
// Or add null check on getAdapter if required
mViewPager.setOffscreenPageLimit(mViewPager.getAdapter().getCount());
It will force ViewPager not to create Fragments second time. For sure, it takes more memory but I believe it is more efficient when using less tabs so I normally do this to avoid recreation of fragments.
Secondly I would suggest to remove these lines from onDestroy:
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
getFragmentManager().beginTransaction().remove(mapFragment).commit();
}
And overcome this issue by updating onCreateView as this:
private View mView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mView == null) {
mView = inflater.inflate(R.layout.fragment_map, container, false);
}
return mView;
}
It will not inflate layout every time so you will not face Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment issue.
But make sure you pass false in attachToRoot (last argument of inflater.inflate) otherwise you may get exceptions like The specified child already has a parent
Last thing, when using MapFragment inside Fragment, or in other words, when using Nested Fragments, I would recommend use getChildFragmentManager() instead of getFragmentManager() to avoid unexpected issues.
Because as the documentation says:
getFragmentManager: Return the FragmentManager for interacting with fragments associated with this fragment's activity. Note that this will be non-null slightly before getActivity(), during the time from when the fragment is placed in a FragmentTransaction until it is committed and attached to its activity. If this Fragment is a child of another Fragment, the FragmentManager returned here will be the parent's getChildFragmentManager().
getChildFragmentManager: Return a private FragmentManager for placing and managing Fragments inside of this Fragment.
This is a known issue. For the meantime, you may use work around by placing another view on top of the map that uses a background color that is the same as its container is. This makes the map smoothly come in once its ready.
SupportMapFragment mapFragment = SupportMapFragment.newInstance(new GoogleMapOptions().zOrderOnTop(true));
As you always replace fragment then map gets always created then workaround for this would be load your map fragment only once, rest of the time just show/hide your fragment (as if you are showing tabbed fragments).
Have you tried to hide and show fragment (instead of remove/adding it) ?
private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
fragmentA = FragmentA.newInstance("foo");
fragmentB = FragmentB.newInstance("bar");
fragmentC = FragmentC.newInstance("baz");
}
}
In your case you might change it to ParkMapFragment etc.
protected void displayFragmentA() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (fragmentA.isAdded()) { // if the fragment is already in container
ft.show(fragmentA);
} else { // fragment needs to be added to frame container
ft.add(R.id.flContainer, fragmentA, "A");
}
// Hide fragment B
if (fragmentB.isAdded()) { ft.hide(fragmentB); }
// Hide fragment C
if (fragmentC.isAdded()) { ft.hide(fragmentC); }
// Commit changes
ft.commit();
}
source: https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments
Try this inside createView:
if (v != null) {
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null)
parent.removeView(v);
}
You should make the transition of fragments by this way:
Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();
With TRANSIT_FRAGMENT_FADE Fragment should simply fade in or out; that is, no strong navigation associated with it except that it is appearing or disappearing for some reason.
Use it when you replace the fragment with map by another fragment, in other case I recomend the common use, without (.setTransition...):
Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).commit();

Error in inflating map fragment

I have a navigation bar and I am working with fragment, menu1fragment is a map, when I tried to use addtobackstack to save my data I have a problem in inflating any solution
MainActivity
private void displayView(int position) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (position) {
case 0:
fragment = new menu1_fragment();
title = getString(R.string.title_section1);
break;
case 1:
fragment = new menu2_fragment();
title = getString(R.string.title_section2);
break;
case 2:
fragment = new menu4_myfleet();
title = getString(R.string.title_section3);
break;
case 3:
fragment = new menufragment_contact();
title = getString(R.string.title_section4);
break;
case 4:
fragment = new menu5_Emergency();
title = getString(R.string.title_section5);
break;
case 5:
logoutUser();
break;
default:
break;
}
if (fragment != null) {
String backStateName = fragment.getClass().getName();
FragmentManager fragmentManager = getSupportFragmentManager();
boolean fragmentPopped = fragmentManager.popBackStackImmediate(backStateName, 0);
if (!fragmentPopped){ //fragment not in back stack, create it.
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(backStateName);
fragmentTransaction.commit();
}
/* FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.container_body, fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();*/
// set the toolbar title
getSupportActionBar().setTitle(title);
}
}
This is menu1_fragment that inflate the map:
rootview = inflater.inflate(R.layout.activity_map,container,false);
/*get map fragment and puts it in the container */
FragmentManager fm = getChildFragmentManager();
Fragment mapFragment = fm.findFragmentById(R.id.map);
if (mapFragment == null) {
mapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.container_body, mapFragment, "myMap")
.commitAllowingStateLoss();
}
//create the fragment that contain your vehicle
mFragment4Container = (FrameLayout) rootview.findViewById(R.id.fragment4Container);
mFragment4Container.setVisibility(View.GONE);
android.support.v4.app.FragmentTransaction trans = getActivity().getSupportFragmentManager().beginTransaction();
trans.add(mFragment4Container.getId(), new menu3_fragment());
trans.commit();
//create a fragmen for marker profile
mFragment4Containeruser = (FrameLayout) rootview.findViewById(R.id.fragment4Containeruser);
mFragment4Containeruser.setVisibility(View.GONE);
android.support.v4.app.FragmentTransaction transprofile = getActivity().getSupportFragmentManager().beginTransaction();
transprofile.add(mFragment4Containeruser.getId(), new user_info());
transprofile.commit();
This is the error that appears:
android.view.InflateException:Binary XML file line #7: Error inflating class fragment at
android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719) at
android.view.LayoutInflater.rInflate(LayoutInflater.java:761) at
android.view.LayoutInflater.inflate(LayoutInflater.java:498) at
android.view.LayoutInflater.inflate(LayoutInflater.java:398) at
com.example.fcb.insurance.menu1_fragment.onCreateView(menu1_fragment.java:120)
Menu1_fragment `
<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="match_parent"
android:id="#+id/map"
tools:context="com.example.fcb.insurance.map"
android:name="com.google.android.gms.maps.SupportMapFragment" />
<FrameLayout
android:id="#+id/fragment4Container"
android:layout_width="match_parent"
android:layout_height="400dp"
android:background="#E2E2E2"
android:layout_gravity="bottom"
/>
<FrameLayout
android:id="#+id/fragment4Containeruser"
android:layout_width="match_parent"
android:layout_height="180dp"
android:background="#E2E2E2"
android:layout_gravity="bottom"
/>
<com.rey.material.widget.Button
style="#style/Material.Drawable.Ripple.Wave.Light"
android:layout_width="256dp"
android:layout_height="wrap_content"
android:text="call expert"
android:id="#+id/buttonclose"
android:layout_marginBottom="100dp"
android:layout_gravity="center_horizontal|bottom"
app:rd_enable="true"/>
<com.rey.material.widget.Button
style="#style/Material.Drawable.Ripple.Wave.Light"
android:layout_width="256dp"
android:layout_height="wrap_content"
android:text="call Tow Truck"
android:id="#+id/button_towtruck"
android:layout_marginBottom="50dp"
android:layout_gravity="center_horizontal|bottom"
app:rd_enable="true"/>
</FrameLayout>
`
Main Activity.xml
<!-- 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.fcb.insurance.MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/container_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
</LinearLayout>
<FrameLayout
android:id="#+id/container_body"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
<!-- 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/fragment_navigation_drawer"
android:name="com.example.fcb.insurance.FragmentDrawer"
android:layout_width="#dimen/nav_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
app:layout="#layout/fragment_navigation_drawer"
tools:layout="#layout/fragment_navigation_drawer"
/>
</android.support.v4.widget.DrawerLayout>
Since you are adding the SupportMapFragment using XML in the Menu1_fragment.xml like that
android:name="com.google.android.gms.maps.SupportMapFragment"
then you should remove this code from Menu1_fragment.java
if (mapFragment == null) {
mapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.container_body, mapFragment, "myMap")
.commitAllowingStateLoss();
}
or vice versa.
Edit #1
I also noticed that you are inflating another layout for your menu1_fragment
rootview = inflater.inflate(R.layout.activity_map,container,false);
It should be R.layout.Menu1_fragment instead if R.layout.activity_map
remove android:name from xml declaration, and replace it with:
class="com.google.android.gms.maps.MapFragment"

MapFragment, GoogleMap .getMap()

I am having a lot of trouble getting .getMap() to work when trying to create a GoogleMap object (it is returning null), I have looked around and seen people had similar issues but wasn't able to find any help from any of them. In it's current implementation how can I find the MapFragment & create a GoogleMap from it?
protected void setFragment(){
FragmentManager fm = getFragmentManager();
MapFragment mapFragment = MapFragment.newInstance();
fm.beginTransaction().replace(R.id.fragment_container, mapFragment).commit();
try{
GoogleMap gMap = ((MapFragment)fm.findFragmentById(R.id.fragment_container)).getMap();
gMap.setBuildingsEnabled(true);
}catch(Exception e){ }
}
The portion of XML containing fragment_container
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="#+id/selectionLayout">
<RelativeLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="85dp">
</RelativeLayout>
</RelativeLayout>
Allow the Map to load before you start using otherwise you'll get null. You have the onReady callback when the map is ready for use.
protected void setFragment(){
FragmentManager fm = getFragmentManager();
MapFragment mapFragment = MapFragment.newInstance();
fm.beginTransaction().replace(R.id.fragment_container, mapFragment).commit();
try{
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap map) {
//your map related actions.
}
});
}
catch(Exception e) {
e.printStackTrace();
}
}
You actually need to include a fragment (NOT the Relative Layout) to your layout like so:
<fragment
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />

How to add map fragment programmatically

I would like add this xml fragment programmatically to other fragments.
Is it possible?
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
In XML you can add a placeholder container:
<FrameLayout
android:id="#+id/mapContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
And then in code you can do:
FragmentManager fm = getChildFragmentManager();
SupportMapFragment supportMapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.mapContainer, supportMapFragment).commit();
Make a layout like:
<FrameLayout
android:id="#+id/layout_mapContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="0"
android:background="#android:color/transparent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent" />
</FrameLayout>
In Activity declare :
FrameLayout mapLayout = (FrameLayout)findViewById(R.id.layout_mapContainer);
initialise map like this:
private void initialiseMap() {
FragmentTransaction mTransaction = getSupportFragmentManager().beginTransaction();
SupportMapFragment mFRaFragment = new MapFragmentActivity();
mTransaction.add(mapLayout.getId(), mFRaFragment);
mTransaction.commit();
try {
MapsInitializer.initialize(context);
} catch (Exception e) {
e.printStackTrace();
}
}
Here MapFragmentActivity is class extends SupportMapFragment

Categories