Cannot get polygon to show on MapFragment in Android app - android

I am trying to draw a simply polygon on a MapFragment but cannot get it to render. I am using the code example from the developer docs but to no avail. I am new to this so I must be missing something very obvious but I cannot work out what it is. I am not getting any runtime errors.
Here is the relevant bit of my main activity.
public class UserLocation<MainActivity> extends Activity {
blah blah...
//Set up initial map fragment view
map = ((MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
LatLng startPoint = new LatLng(-30.89,24.26);
//See use of CameraPosition.Builder here which gives a cool perspective view on the map. See use of map.animateCamera using this method too;
CameraPosition cameraPosition = new CameraPosition.Builder().target(startPoint).tilt(60).zoom(6).bearing(0).
build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
//try add polgyon
List<LatLng> points = Arrays.asList(new LatLng(18.39416, -33.97885),
new LatLng(18.45116, -33.97885),
new LatLng(18.45116, -33.91077),
new LatLng(18.39416, -33.91077),
new LatLng(18.39416, -33.97885));
PolygonOptions options = new PolygonOptions();
options.addAll(points);
options.fillColor(Color.RED);
map.addPolygon(options);
The xml file
<TextView
android:id="#+id/header"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello_world" />
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageButton
android:id="#+id/mainNavigationButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginLeft="120dp"
android:onClick="OnClick_launch_mainNavigation"
android:alpha="0.8"
android:src="#drawable/copbutton"/>
<Spinner
android:id="#+id/spinner1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="17dp"
android:entries="#array/crime_arrays"
android:prompt="#string/crime_prompt" />
</FrameLayout>
The documents would suggest this is a simple process but I'm stumped. Thanks in advance for any advice.

your code should work. Could be, that you accidently switching your longitude/latitude, since you are drawing the polygons to (24.26,-30.89) but move your camera to (-30.89,24.26).
To ensure your at the right area, create a button which calls
private function onButtonClick(){
LatLng startPoint = new LatLng(24.26,-30.89);
CameraPosition cameraPosition = new CameraPosition.Builder().target(startPoint).tilt(60).zoom(6).bearing(0).
build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}

Related

How to have the soft keyboard cover a view, yet cause other views to take the available space?

Background
Suppose I have a view that works as the background (MapFragment in my case), and some other views that are the content of the activity.
The problem
Focusing an EditText, it shows the soft keyboard, causing all views to change their sizes, including the background view.
This means that showing the soft keyboard causes the background to "jump" and re-layout itself.
This is especially problematic in my case, as I use MapFragment as the background. That's because I can think of a workaround to detect the keyboard size, and show only the upper area of the background view, but there is little control of the MapFragment in how it looks and work.
Here's a demo of the problem:
Here's a sample xml, used inside the sample of the mapFragment:
basic_demo.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">
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<EditText
android:id="#android:id/edit"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginTop="20dp"
android:background="#66ffffff"
android:digits="0123456789()-+*"
android:focusable="true"
android:focusableInTouchMode="true"
android:gravity="center_vertical|left"
android:imeOptions="actionSearch|flagNoExtractUi"
android:inputType="phone"
android:singleLine="true"
android:textColorHint="#aaa"
android:textSize="18dp"
tools:hint="Search Phones ..."/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginBottom="30dp"
android:background="#66ffffff"
android:text="This should always be shown, at the bottom"/>
</FrameLayout>
What I've found
I know that we can set the "windowSoftInputMode" flag in the manifest, but this is an all-or-nothing solution. It affects all of the views, and not a single one.
The question
How can I let the soft keyboard change the layout of all views except specific ones?
Is it even possible?
EDIT: looking at "gio"'s solution, it works. Here's a more optimized way to do it:
View view=...
mContainerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
final Rect outGlobalRect = new Rect(), outWindowRect = new Rect();
#Override
public void onGlobalLayout() {
mContainerView.getGlobalVisibleRect(outGlobalRect);
mContainerView.getWindowVisibleDisplayFrame(outWindowRect);
int marginBottom = outGlobalRect.bottom - outWindowRect.bottom;
final FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();
if (layoutParams.bottomMargin == marginBottom)
return;
layoutParams.setMargins(0, 0, 0, marginBottom);
view.requestLayout();
}
});
It's possible according your initial requirements. Idea is to change bottom margin of needed view. Value will be calculated as difference between shown and real height of root view. I wrapped TextView into FrameLayout for case if you need to control more views there.
xml layout
<FrameLayout
android:id="#+id/ac_mp_container"
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">
<fragment
android:id="#+id/ac_mp_map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tivogi.so.MapsActivity" />
<EditText
android:layout_width="100dp"
android:layout_height="wrap_content" />
<FrameLayout
android:id="#+id/ac_mp_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This should always be shown, at the bottom" />
</FrameLayout>
activity class
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private View mContainerView;
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.ac_mp_map);
mapFragment.getMapAsync(this);
mContainerView = findViewById(R.id.ac_mp_container);
mContainerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
View view = findViewById(R.id.ac_mp_view);
int marginBottom;
Rect outGlobalRect = new Rect();
Rect outWindowRect = new Rect();
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mContainerView.getGlobalVisibleRect(outGlobalRect);
mContainerView.getWindowVisibleDisplayFrame(outWindowRect);
marginBottom = outGlobalRect.bottom - outWindowRect.bottom;
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.BOTTOM);
layoutParams.setMargins(0, 0, 0, marginBottom);
view.setLayoutParams(layoutParams);
}
});
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney 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));
}
}
Result:
This is a little bit off topic from what you guys have been discussing, but I had the same issue with the Google Map layout being re adjusted when user clicks on an EditText on that fragment layout. My problem was that the GoogleMap was a fragment of another view (ViewPager). In order to fix it, I had to programmatically add getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN) to the ViewPager Class.
Layout Hierarchy: Activity --> ViewPager --> GoogleMap Fragment. Code added to ViewPager on the onCreate method.

How to center text on android IconGenerator

I'm developing an app using lots of markers placed on the map, and I'm using a custom ClusterRenderer to show them.
Problem is that I can't draw the cluster's size in the center of the custom marker icon, please see attached screenshot.
I've tried adding contentPadding to the IconGenerator, but still no luck, because of the changing number of digits shown. Could you please help me center the text on the generated icon?
Code:
IconGenerator clusterIconGenerator = new IconGenerator(context);
clusterIcon = context.getResources().getDrawable(R.drawable.map_cluster);
clusterIconGenerator.setBackground(clusterIcon);
#Override
protected void onBeforeClusterRendered(Cluster<MyType> cluster, MarkerOptions markerOptions) {
Bitmap clusterIcon = clusterIconGenerator.makeIcon(String.valueOf(cluster.getSize()));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(clusterIcon));
}
UPDATE
starting Apr 1, 2016 a prefix has been added to the Resources of the library
so the id="text" has been changed to "amu_text".
As stated in the library documentation :
setContentView public void setContentView(View contentView) Sets the child view for the icon. If the view contains a
TextView with the id "amu_text", operations such as
setTextAppearance(Context, int) and makeIcon(String) will operate
upon that TextView .
#Override
protected void onBeforeClusterRendered(Cluster<Dashboard_Marker> cluster, MarkerOptions markerOptions) {
IconGenerator TextMarkerGen = new IconGenerator(context);
Drawable marker;
int ClusterSize = cluster.getSize();
marker = context.getResources().getDrawable(R.drawable.cluster_red);
TextMarkerGen.setBackground(marker);
LayoutInflater myInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View activityView = myInflater.inflate(R.layout.cluster_view, null, false);
TextMarkerGen.setContentView(activityView);
TextMarkerGen.makeIcon(String.valueOf(cluster.getSize()));
BitmapDescriptor icon = BitmapDescriptorFactory.fromBitmap(TextMarkerGen.makeIcon());
markerOptions.icon(icon);
}
with the layout cluster_view as :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:layout_centerVertical="true"
android:weightSum="1">
<TextView
android:layout_width="61dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:textColor="#000000"
android:id="#+id/amu_text"
android:layout_marginTop="13dp"
android:gravity="center" />
</LinearLayout>
note :: the layout must contain one text view with an id = "amu_text" in order for the icon generator to accept it , manipulate all the positioning you want in the layout .

Center fixed marker in android v2 mapview

I want to set fixed marker in the center point of mapview while dragging map.It has been done at android Map V1 google mapview. But now it's deprecated.Now my question is, is it possible in android Map V2 google mapview ?(I have tried.but map doesn't show)
So you want something like a cross-hairs on the center of map, right?
I have not used MapView. But I have used Map Fragment, and the way i implement a fix marker on the map is use a ImageView, So you will end up with something like below:
<?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/fragment1"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/cross_hairs" />
</RelativeLayout>
You could swap the MapFragment with MapView.
Placing the marker on the map will be inefficient, since you will need to keep updating the marker when the user pans the map.
Hope it helps!
I'm betting you used getMapCenter() which, as per Google Maps for Android v2, no longer available to use. But no worries, just use this:
GoogleMap.getCameraPosition().target
It will return a LatLng object which basically represents the center of the map. You can then use it to reposition the marker to the center every time there's a drag event by assigning an OnCameraChangedListener to your GoogleMap.
yourGMapInstance.setOnCameraChangeListener(new OnCameraChangedListener() {
#Override
public void onCameraChange (CameraPosition position) {
// Get the center of the Map.
LatLng centerOfMap = yourGMapInstance.getCameraPosition().target;
// Update your Marker's position to the center of the Map.
yourMarkerInstance.setPosition(centerOfMap);
}
});
There. I hope this helped!
Notice that setOnCameraChangeListener() has been deprecated, so you can use the new camera listeners (OnCameraIdleListener, OnCameraMoveListener, OnCameraMoveStartedListener, OnCameraMoveCanceledListener), for example:
map.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
#Override
public void onCameraMove() {
// Get the center of the map
LatLng center = map.getCameraPosition().target;
......
}
});
for more information, read this: https://developers.google.com/maps/documentation/android-api/events
Simply goto the XML File: Add Image View in map fragment and set the gravity to center. Then goto the Java File and add the following java code into your onMayReady Function:
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toTopOf="#+id/bottom_navigation"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="#+id/linearLayout2" />
<ImageView
android:id="#+id/imageView_map_marker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="17dp"
android:background="?attr/selectableItemBackgroundBorderless"
android:clickable="true"
android:layout_gravity="center"
android:tooltipText="Select Location"
app:srcCompat="#drawable/ic_baseline_location_red" />
mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
#Override
public void onCameraMove() {
mMap.clear();
binding.imageViewMapMarker.setVisibility(View.VISIBLE);
}
});
mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
#Override
public void onCameraIdle() {
binding.imageViewMapMarker.setVisibility(View.GONE);
selectedLatitude=mMap.getCameraPosition().target.latitude;
selectedLongitude=mMap.getCameraPosition().target.longitude;
MarkerOptions marker = new MarkerOptions().position(mMap.getCameraPosition().target).title("")
.icon(bitmapDescriptorFromVector(getApplicationContext(), R.drawable.ic_baseline_location_red));
mMap.addMarker(marker);
}
});

Monodroid add map preview

I am trying to add google map v2 in a fragment in a preview style but I am not sure how to fit the map with the desired zoom inside the view. When I try to add the the map in a full fragment it works correctly. I am using a framelayout and loading the map like this
void InitMapFragment()
{
GoogleMapOptions mapOptions = new GoogleMapOptions()
.InvokeMapType(GoogleMap.MapTypeNormal)
.InvokeZoomControlsEnabled(true)
.InvokeCompassEnabled(true);
m_mapFragment = SupportMapFragment.NewInstance(mapOptions);
Activity.SupportFragmentManager.BeginTransaction().Replace(Resource.Id.mapLayout, m_mapFragment, "map").Commit();
}
Any ideas on how to add in a small prview format as in Sunrise app?
And here is the sample of how my layout file looks
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="#style/RegularMatchLayout"
android:orientation="vertical"
android:background="#e5e5e5">
<FrameLayout
android:id="#+id/mapLayout"
android:layout_width="300dp"
android:layout_height="300dp" />
</LinearLayout>
I have made similar thing like this:
For layout I used fragment and not frame layout but it's the same more or less.
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="208dp" />
Then I used this code to find the map and setup appropriate zoom level:
_map = ((SupportMapFragment)SupportFragmentManager.FindFragmentById(Resource.Id.map)).Map;
_map.UiSettings.ZoomControlsEnabled = false;
_map.UiSettings.ScrollGesturesEnabled = false;
_map.UiSettings.RotateGesturesEnabled = false;
_map.UiSettings.ZoomGesturesEnabled = false;
_map.UiSettings.TiltGesturesEnabled = false;
var location = new LatLng(_item.Latitude, _item.Longitude);
_map.MoveCamera(CameraUpdateFactory.NewLatLngZoom(location, 16));
var markerOptions = new MarkerOptions();
markerOptions.SetPosition(location);
markerOptions.InvokeIcon(BitmapDescriptorFactory.FromResource(Resource.Drawable.ic_map_marker));
_map.AddMarker(markerOptions);

MapView not working properly inside fragment android

Hi in my application i m displaying one fragment. Inside that fragment I am displaying map. So my code looks like :
<RelativeLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/innerrelativelay"
android:padding="10dp">
<TextView
android:id="#+id/storename"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Store Name:"
android:textSize="15sp"
/>
<TextView
android:id="#+id/storeaddress"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_below="#+id/storename"
android:text="Store Address:"
android:textSize="15sp"
/>
</RelativeLayout>
<com.google.android.gms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/mapView"
android:layout_below="#+id/innerrelativelay"
/>
</RelativeLayout>
and fragment looks like :
public class MyAccount extends SherlockFragment {
MapView map;
GoogleMap mMap;
TextView storeName,storeAddress;
SharedPreferences storeInfo,authenticationInfo;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.maplayout, container, false);
map = (MapView) v.findViewById(R.id.mapView);
map.onCreate(savedInstanceState);
mMap = map.getMap();
map.onCreate(savedInstanceState);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
mMap.setMyLocationEnabled(true);
try {
MapsInitializer.initialize(this.getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
// Updates the location and zoom of the MapView
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
mMap.animateCamera(cameraUpdate);
mMap.setMyLocationEnabled(true);
storeName = (TextView)v.findViewById(R.id.storename);
storeAddress = (TextView)v.findViewById(R.id.storeaddress);
storeInfo = getActivity().getSharedPreferences(CommonSharedPref.QCMERCHANT_STOREID, 0);
authenticationInfo = getActivity().getSharedPreferences(CommonSharedPref.QCMERCHANT_AUTHENTICATION_INFO, 0);
storeName.setText(storeName.getText().toString()+storeInfo.getString(CommonSharedPref.QCMERCHANT_STORENAME, ""));
storeAddress.setText(storeAddress.getText().toString()+storeInfo.getString(CommonSharedPref.QCMERCHANT_ADDRESS1, "")
+"\n"+storeInfo.getString(CommonSharedPref.QCMERCHANT_ADDRESS1, ""));
return v;
}
}
It shows me map properly but creating marker, showing current location or move camera at given location not working properly.
How to do this. Need help. Thank you.
UPDATE
Try changing the layout of fragment as
<fragment
android:id="#+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
Also it seems you havent initialised the markers yet. Thats why markers arent visible..
If you need pointers of how to do it.. There is a very good tutrial page...
http://www.vogella.com/articles/AndroidGoogleMaps/article.html
From here https://developers.google.com/maps/documentation/android/v1/hello-mapview, you can see that
Version 1 of the Google Maps Android API as been officially
deprecated as of December 3rd, 2012
So you shouldn't use MapView anymore. I suggest you use a MapFragment instead. See the excellent documentation for it here: https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/MapFragment

Categories

Resources