Cannot fix Map Fragment in Fragment NullPointerException - java

I am trying to show a Map in a Fragment but I always get this NullPointerException:
java.lang.NullPointerException: Attempt to invoke virtual method
'com.google.android.gms.maps.GoogleMap
com.google.android.gms.maps.SupportMapFragment.getMap()' on a null
object reference
I knew there are many questions with this exception in this case but i can't find my mistake. I read any answer I have found.
Here is my Code:
public class DetailKarteFragment extends Fragment {
GoogleMap map;
static final LatLng brend = new LatLng(48.079, 8.157);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_detail_karte, null, false);
FragmentTransaction ft = getFragmentManager().beginTransaction();
map = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
SupportMapFragment fmap = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fmap == null) {
fmap = SupportMapFragment.newInstance();
ft.add(R.id.map, fmap);
}
ft.commit();
Marker brendMarker = map.addMarker(new MarkerOptions().position(brend).title("Brend"));
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(brend, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
return v;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
and the xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#color/background"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Route anzeigen"
android:id="#+id/button_route_planen"
android:layout_gravity="center_horizontal"
android:height="48dp"
android:background="#color/secondary_100"
android:layout_marginBottom="-48dp"/>
</LinearLayout>
</LinearLayout>

Just move the map = (...).getMap() line after ft.commit(). You are getting that exception because FragmentManager can't find a fragment which has not already been added or replaced into the container.
A better solution in my opinion would be:
SupportMapFragment fmap;
fmap = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fmap == null) {
fmap = SupportMapFragment.newInstance();
ft.add(R.id.map, fmap);
ft.commit();
}
map = fmap.getMap();

You are retrieving the GoogleMap object map before checking if the SupportMapFragment even exists. I assume that this fragment hasn't been added yet, and you're invoking the getMap() method on a null reference.

I know this question is very old... But I just had this problem and I would like to share what was happening to me and the solution.
I was trying to put a MapFragment inside a fragment just like you. But I forgot to put the key in my manifest:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_key" />
So, when this happens in a Activity, it throw an exception. That's great, because your app crashes and you can read the log and understand what you have to do! You get this message:
Caused by: java.lang.RuntimeException: API key not found.
Check that <meta-data android:name="com.google.android.geo.API_KEY" android:value="your API key"/>
is in the <application> element of AndroidManifest.xml
It's very easy to find what needs to be done this way, right?
But it doesn't happen when the MapFragment is inside another fragment!
It only return a null fragment... just like the problem you have right now.
So just put the key in the Manifest and you will be fine! I hope Google fix this, because it took me some hours to find out what was wrong.

Related

Mapbox supportMapFragment / mapView is black on Android versions lower than 8

I am using mapView and a SupportMapFragment to display the map in a fragment. On newer Android versions (I tested 8 and 9 on different devices) the map displays without any problem. However, on older Android versions (I tested 6 and 7) the map is showing a black screen (see black screen pic). The maps seems to work correctly though. I can click on it, routes are properly calculated an I can start navigation. So did I initialize the mapView / mapFragment wrong? How can I remove the black screen and get the mapView working on older Android versions?
I tried to initialize the mapView differently, but nothing seemed to do the trick. The map remains black. Since there is also no console output, regarding the black screen, I do not know how to proceed. Any help is greatly appreciated.
The MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, getString(R.string.access_token));
setContentView(R.layout.activity_main);
(...)
// Create supportMapFragment
if (savedInstanceState == null) {
// Create fragment
final FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Build mapboxMap
MapboxMapOptions options = new MapboxMapOptions();
options.camera(new CameraPosition.Builder()
.target(new LatLng(-52.6885, -70.1395))
.zoom(9)
.build());
// Create map fragment
mapFragment = SupportMapFragment.newInstance(options);
// Add map fragment to parent container
transaction.add(R.id.container2, mapFragment, "com.mapbox.map");
transaction.commit();
navigationView.setCheckedItem(R.id.nav_home);
} else {
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentByTag("com.mapbox.map");
}
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(#NonNull MapboxMap mapboxMap) {
MainActivity.this.mapboxMap = mapboxMap;
mapView = findViewById(R.id.mapView);
(...)
#Override
protected void onStart() {
super.onStart();
mapFragment.onStart();
}
// etc.
(...)
Part of the activity_main.xml containing the mapView and the container2 for the mapFragment:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<android.support.constraint.ConstraintLayout
xmlns:mapbox="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:id="#+id/container2"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.mapbox.mapboxsdk.maps.MapView
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
(...)
I expect the mapView/fragment to show properly not only in newer Android versions, but also in older Android versions.

Making a Snackbar Without a View?

I want to show a snackbar as soon as the user opens the Google Maps activity, but the thing is that there's no views in the activity to use as the first parameter of the activity (in the findViewById() of Snackbar.make()). What do I put there?
Here's the java class code:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// 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);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setBuildingsEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
float cameraZoom = 17;
LatLng location = new LatLng(43.404032, -80.478184);
mMap.addMarker(new MarkerOptions().position(location).title("49 McIntyre Place #18, Kitchener, ON N2R 1G3"));
CameraUpdateFactory.newLatLngZoom(location, cameraZoom);
Snackbar.make(findViewById(/*WHAT DO I PUT HERE?*/), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
}
}
Also, here is the activity xml code:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ca.davesautoservice.davesautoservice.MapsActivity" />
And lastly, here's the stacktrace error:
08-03 11:42:21.333 3901-3901/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: ca.davesautoservice.davesautoservice, PID: 3901
java.lang.NullPointerException
at android.support.design.widget.Snackbar.<init>(Snackbar.java:183)
at android.support.design.widget.Snackbar.make(Snackbar.java:215)
at ca.davesautoservice.davesautoservice.MapsActivity.onMapReady(MapsActivity.java:48)
at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzo$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:361)
at xz.a(:com.google.android.gms.DynamiteModulesB:82)
at maps.ad.u$5.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5333)
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:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
Thanks for the help! :)
I see some options... Not sure which one can fix your issue.
Simpliest
SupportMapFragment extends class android.support.v4.app.Fragment. This way, it has a method getView()
Snackbar.make(mapFragment.getView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Find Root View
From this answer, there's a way to get the root view via:
getWindow().getDecorView().getRootView()
So, maybe, you can do:
Snackbar.make(getWindow().getDecorView().getRootView(), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
NOTE: This approach has the side effect mentioned in the comments below:
The message will be shown behind the bottom navigation bar if the following method will be used to get view getWindow().getDecorView().getRootView()
Add a dummy LinearLayout to get the View
Honestly, I'm not sure if this solution is possible. I'm not sure if you can add a LinearLayout above the Maps fragment... I think it is OK but since I never work with Maps API before, I'm not sure.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dummy_layout_for_snackbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="ca.davesautoservice.davesautoservice.MapsActivity" />
</LinearLayout>
and then:
Snackbar.make(findViewById(R.id.dummy_layout_for_snackbar), "Click the pin for more options", Snackbar.LENGTH_LONG).show();
Try this in any activity:
snackbar(findViewById(android.R.id.content),"your text")
As Shahab Rauf points out, getting the view via getDecorView() may put the snackbar behind the navigation bar in the bottom. I use the following code: (Use and extend to your delight)
public class BaseActivity extends AppCompatActivity {
private View getRootView() {
final ViewGroup contentViewGroup = (ViewGroup) findViewById(android.R.id.content);
View rootView = null;
if(contentViewGroup != null)
rootView = contentViewGroup.getChildAt(0);
if(rootView == null)
rootView = getWindow().getDecorView().getRootView();
return rootView;
}
protected void showSnackBarWithOK(#StringRes int res) {
final View rootView = getRootView();
if(rootView != null) {
final Snackbar snackbar = Snackbar.make(getRootView(), res, Snackbar.LENGTH_INDEFINITE);
snackbar.setAction(R.string.ok, new View.OnClickListener() {
#Override
public void onClick(View v) {
snackbar.dismiss();
}
});
snackbar.show();
}
}
protected void showSnackBar(#StringRes int res) {
final View rootView = getRootView();
if(rootView != null)
Snackbar.make(rootView, res, Snackbar.LENGTH_LONG).show();
}
}
OK, So all above solutions are either too complex or irrelevant.
Simplest solution is to use this function ANYWHERE
fun showSnackBar(message: String?, activity: Activity?) {
if (null != activity && null != message) {
Snackbar.make(
activity.findViewById(android.R.id.content),
message, Snackbar.LENGTH_SHORT
).show()
}
}
Wanna call this function in Activity?
showSnackBar("Test Message in snackbar", this)
Wanna call this function in Fragment?
showSnackBar("Test Message in snackbar", requireActivity())
Happy Coding!
The simplest way of doing this is to get the advantage of Extention Function in Kotlin.
Step 1: Create a kotlin file i.e Extensions.kt and paste below code
For Activity:
fun Activity.showSnackBar(msg:String){
Snackbar.make(this.findViewById(android.R.id.content), msg, Snackbar.LENGTH_SHORT)
.setAction("Ok"){
}
.show()
}
For Fragment:
fun Fragment.showSnackBar(msg:String){
Snackbar.make(this.requireActivity().findViewById(android.R.id.content), msg, Snackbar.LENGTH_SHORT)
.setAction("Ok"){
}
.show()
}
Step 2: Call it like below:
showSnackBar("PASS HERE YOUR CUSTOM MESSAGE")
Don't do it.
Why ?
The entire idea of giving an anchor view to snackbar is probably because it gives us the ablity to put it on our favourite place on the screen,
As mentioned in other answers there are ways by which you can attach the root view to it automatically, Using getWindow().getDecorView().getRootView() is one of these, but it can cause this message to appear on bottom navigation view, which doesn't look good (at least to me).
If you want something for general message display go for toast, it is much less error prone and have a consistent appearence, if you need something with interaction I would suggest Alert Dialogue
I would say that findViewByIdis the best approach. As using getWindow().getDecorView().getRootView() will cause the message to be shown behind the bottom navigation bar.
In my case, I didn't need to create a dummy element in XML. I used the following code
Snackbar.make(findViewById(R.id.container),"This will start payment process.", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
and my XML file is as follows
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".HomePatientActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/sliding_tabs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
app:layout_anchorGravity="top"
app:tabMode="fixed" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v4.view.ViewPager>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
Add any layout and assign the layout an id example below:
<RelativeLayout
android:id="#+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment"
/>
</RelativeLayout>
In your activity find the layout using findViewById:
RelativeLayout relativeLayout = findViewById(R.id.relativeLayout);
Example for other layouts respectively as long as your assign the layouts their Id's:
LinearLayout relativeLayout = findViewById(R.id.linearLayout);
FrameLayout frameLayout = findViewById(R.id.frameLayout);
Displaying the Snackbar:
Snackbar.make(relativeLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
For other layouts just change the name of the layouts examples:
Snackbar.make(linearLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
Snackbar.make(frameLayout,"You are displaying a Snackbar",Snackbar.LENGTH_SHORT).show();
Use as extension function:
fun Activity?.showSnackBar(message: String) {
this ?: return
Snackbar.make(
this.findViewById(android.R.id.content),
message, Snackbar.LENGTH_LONG
).show()
}
With Jetpack Compose stable version released,now you no more need views in xml .
#Composable
fun Snackbar() {
Row {
if (viewModel.snackbarVisibleState.value) {
Snackbar(
action = {
Button(onClick = {
viewModel.snackbarText.value = ""
viewModel.snackbarVisibleState.value = false
}) {
Text("Ok")
}
},
modifier = Modifier
.padding(8.dp)
.align(Alignment.Bottom)
) {
Text(viewModel.snackbarText.value)
}
}
}
}
Here snackbarVisibleState is a MutableState inside viewmodel whose value you need to change in order to show and dismiss Snackbar.
For more code snippets for Jetpack Compose, refer this - https://androidlearnersite.wordpress.com/2021/08/03/jetpack-compose-1-0-0-sample-codes/

Working with Map Fragment Activity

I'm trying to create a basic activity with a google map fragment. Right now I have this:
public class MainScreen extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
// add the map fragment to the activity
if (findViewById(R.id.fragment_container) != null) {
if (savedInstanceState != null) { return; }
getSupportFragmentManager().beginTransaction()
.add(R.id.fragment_container, new FragmentGoogle()).commit();
}
}
}
public class FragmentGoogle extends android.support.v4.app.Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.map_google, container, false);
}
}
Which is producing this:
My question is: how can I interact with the fragment itself? Let's supposse I want to zoom in Sidney. Should I put the code in the MainScreen.class or in the Fragment.class? Which methods should I use? It's my first time working with fragments.
you don't need to create your own FragmentGoogle. You can use com.google.android.gms.maps.SupportMapFragment and controll it from you activity code.
in the layout:
<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=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment" />
and then in the Activity code:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney, Australia, and move the camera.
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
The code is taken from
this tutorial which is enough to start and use most of the features of the Google Maps Android API, just follow the steps :)
Lets say you have an empty activity in a new project.
do this :
creating premade android map activity
And then you ll get something like this :
your project structure
go to google maps api and do what they tell you to do in the (TODO)
Create an account and a project on google maps platform https://console.cloud.google.com/google/maps-apis/
Activate android development by clicking a button you ll have to look for it
and then go to key section to create new api key
go back to android studio and click the yellow xml file in the picture
past your key there
So by now the Map actvity should give you a real map and everything should work , you should see the map if you get to the map activity
but now what you want is to add that map inside your MainActivity .(i named it ActivityMain because MapActivity and MainActivity look the same )
Now all you need to do is copy past the fragment of the xml file activity_maps.xml without changing anything except for the id .
this is the activity_main.xml :
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map1"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
I tried adding a button here but i couldn't. So what i did is copy the fragment itself and put it inside the activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
tools:context=".ActivityMain">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start" />
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity" />
</LinearLayout>
I think these are all steps to create the picture you have in your question.
I hope this was useful not painful to read .

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" />

OnClick doesn't work with LinearLayout

OnClick doesn't work. Nothing happens after clicking on layout. It seems like it is clickable, because layout changes its color, but new layout doesn't open.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/window"
android:layout_width="295dp"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#drawable/editborder"
android:clickable="true"
android:onClick="openBigImage">
Here is more code for Main Activity:
public class MyMapActivity extends FragmentActivity implements LocationListener
{
private Marker marker;
private Hashtable<String, String> markers;
private ImageLoader imageLoader;
private DisplayImageOptions options;
private GoogleMap map;
private ListView mainListView ;
private ArrayAdapter<String> listAdapter ;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_map);
// Look up the AdView as a resource and load a request.
//AdView adView = (AdView)this.findViewById(R.id.adView);
//adView.loadAd(new AdRequest());
// Getting Google Play availability status
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());
// Showing status
if(status!=ConnectionResult.SUCCESS)
{ // Google Play Services are not available
int requestCode = 10;
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
dialog.show();
}
else
{// Google Play Services are available
// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
if (savedInstanceState == null) {
// First incarnation of this activity.
mapFragment.setRetainInstance(true);
}
else
{
// Reincarnated activity. The obtained map is the same map instance in the previous
// activity life cycle. There is no need to reinitialize it.
map = mapFragment.getMap();
}
setUpMapIfNeeded();
}
}
#Override
protected void onResume()
{
super.onResume();
setUpMapIfNeeded();
}
public void openBigImage(View v)
{
setContentView(R.layout.bigpicture);
}
bigpicture.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bigpicture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000000"
android:orientation="vertical">
<fragment
android:id="#+id/minimap"
android:layout_width="200px"
android:layout_height="200px"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
class="com.google.android.gms.maps.SupportMapFragment" />
<ImageView
android:id="#+id/badge"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:adjustViewBounds="true" />
</RelativeLayout>
Calling setContentView() multiple times worked in other cases, like menu items "about", "settings" etc.
Tried to make without setContentView. I've put new Layout to the main.xml and made visibility GONE. OnClick method should change visibility to visible, but again nothing happens.
Logcat says "11-25 13:47:28.638: D/GestureDetector(3156): [Surface Touch Event] mSweepDown False, mLRSDCnt : -1 mTouchCnt : 2 mFalseSizeCnt:0" when i'm clicking on linear layout.
Paul,
One thing is close the linear layout with /> .I am assuming that you have followed the map tutorials link and passed all the manifest permissions and other requirements. You might have some reasons to use px. Check if map is being created. Also give some height and background color to your badge image and see if something happens.
I tested your code without map fragment and it worked fine.
Can you post the error log ?
Found. It is a click on InfoWindow, so we should implement onInfoWindowClick.
But first we must add map.setOnInfoWindowClickListener(this); in main activity. Main activity must implement OnInfoWindowClickListener.
I've added new LinearLayout to the main.xml, made it invisible.
Here's code for onInfoWindowClick:
#Override
public void onInfoWindowClick(Marker marker) {
LinearLayout secondLL = (LinearLayout) findViewById(R.id.bigpicture);
int visibility = secondLL.getVisibility();
if(visibility == View.GONE)
{
secondLL.setVisibility(View.VISIBLE);
}
}
I think you can't use onClick attribute.
You have to use setOnClickListener() like that :
LinearLayout layout = (LinearLayout )findViewById(R.id.window);
layout .setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
YourActivity.this.setContentView(R.layout.bigpicture);
}
});

Categories