[android] #2273 - Added InfoWindowView, Refactored InfoWindow to take in account margins/offset, exposed margin of InfoWindow as configurable

This commit is contained in:
Tobrun
2015-10-12 18:17:57 +02:00
parent c010c3aef8
commit 981ac4038d
16 changed files with 292 additions and 66 deletions

View File

@@ -1,12 +1,15 @@
package com.mapbox.mapboxsdk.annotations;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PointF;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.views.MapView;
@@ -28,10 +31,7 @@ public final class InfoWindow {
public InfoWindow(int layoutResId, MapView mapView) {
mMapView = mapView;
mIsVisible = false;
Context context = mapView.getContext();
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = inflater.inflate(layoutResId, (ViewGroup) mapView, false);
mView = LayoutInflater.from(mapView.getContext()).inflate(layoutResId, mapView, false);
if (mTitleId == 0) {
setResIds(mapView.getContext());
@@ -52,10 +52,6 @@ public final class InfoWindow {
public InfoWindow(View view, MapView mapView) {
mMapView = mapView;
mIsVisible = false;
ViewGroup parent = (ViewGroup) mapView.getParent();
Context context = mapView.getContext();
LayoutInflater inflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mView = view;
// default behavior: close it when clicking on the tooltip:
@@ -83,13 +79,67 @@ public final class InfoWindow {
MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT);
mView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
// Calculate default Android x,y coordinate
PointF coords = mMapView.toScreenLocation(position);
double y = mMapView.getTopOffsetPixelsForAnnotationSymbol(object.getSprite());
float x = coords.x - (mView.getMeasuredWidth() / 2);
float y = (float) mMapView.getTopOffsetPixelsForAnnotationSymbol(object.getSprite());
y = y * mMapView.getScreenDensity();
y += coords.y - mView.getMeasuredHeight();
lp.leftMargin = (int) coords.x - (mView.getMeasuredWidth() / 2);
// Add y because it's a negative value
lp.topMargin = (int) coords.y - mView.getMeasuredHeight() + (int) y;
// if getTopOffsetPixelsForAnnotationSymbol lands
// float x = coords.x - (mView.getMeasuredWidth() / 2) + offsetX;
// float y = coords.y - mView.getMeasuredHeight() + offsetY;
// get right/left popup window
float right = x + mView.getMeasuredWidth();
float left = x;
// get right/left map view
float mapRight = mMapView.getRight();
float mapLeft = mMapView.getLeft();
if (mView instanceof InfoWindowView) {
// only apply repositioning/margin for InfoWindowView
Resources resources = mMapView.getContext().getResources();
float margin = resources.getDimension(R.dimen.infowindow_margin);
float tipViewOffset = resources.getDimension(R.dimen.infowindow_tipview_width) / 2;
float tipViewMarginLeft = mView.getMeasuredWidth() / 2 - tipViewOffset;
// fit screen on right
if (right > mMapView.getRight()) {
x -= right - mapRight;
tipViewMarginLeft += right - mapRight + tipViewOffset;
right = x + mView.getMeasuredWidth();
}
// fit screen left
if (left < mMapView.getLeft()) {
x += mapLeft - left;
tipViewMarginLeft -= mapLeft - left + tipViewOffset;
left = x;
}
// Add margin right
if (mapRight - right < margin) {
x -= margin - (mapRight - right);
tipViewMarginLeft += margin - (mapRight - right) - tipViewOffset;
left = x;
}
// Add margin left
if (left - mapLeft < margin) {
x += margin - (left - mapLeft);
tipViewMarginLeft -= (margin - (left - mapLeft)) - tipViewOffset;
}
// Adjust tipView
InfoWindowView infoWindowView = (InfoWindowView) mView;
infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft);
}
// set anchor popupwindowview
mView.setX(x);
mView.setY(y);
close(); //if it was already opened
mMapView.addView(mView, lp);

View File

@@ -0,0 +1,36 @@
package com.mapbox.mapboxsdk.annotations;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.RelativeLayout;
import com.mapbox.mapboxsdk.R;
public class InfoWindowView extends RelativeLayout{
private InfoWindowTipView mTipView;
public InfoWindowView(Context context) {
this(context, null);
}
public InfoWindowView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initialize(context);
}
private void initialize(Context context){
LayoutInflater.from(context).inflate(R.layout.infowindow_content, this);
mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview);
}
public void setTipViewMarginLeft(int marginLeft){
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams();
layoutParams.leftMargin = marginLeft;
}
}

View File

@@ -202,7 +202,7 @@ public class Marker extends Annotation {
*/
private InfoWindow getInfoWindow() {
if (infoWindow == null) {
infoWindow = new InfoWindow(R.layout.infowindow, mapView);
infoWindow = new InfoWindow(R.layout.infowindow_view, mapView);
}
return infoWindow;
}

View File

@@ -2,4 +2,5 @@
<resources>
<!--Add references to exposed resources-->
<public name="AttributionAlertDialogStyle" type="style" />
<public name="infowindow_margin" type="dimen" />
</resources>

View File

@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/infowindow_content"
android:background="@color/white"
android:padding="5dp"
android:layout_width="wrap_content"
@@ -45,8 +45,10 @@
</LinearLayout>
<com.mapbox.mapboxsdk.annotations.InfoWindowTipView
android:layout_width="fill_parent"
android:layout_height="10dp"/>
android:id="@+id/infowindow_tipview"
android:layout_below="@+id/infowindow_content"
android:layout_width="@dimen/infowindow_tipview_width"
android:layout_height="8dp"/>
</LinearLayout>
</RelativeLayout>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mapbox.mapboxsdk.annotations.InfoWindowView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="infowindow_tipview_width">16dp</dimen>
<dimen name="infowindow_margin">8dp</dimen>
</resources>

View File

@@ -34,7 +34,7 @@ public class InfoWindowAdapterActivityTest extends BaseTest {
@Test
public void testSanity() {
onView(withId(R.id.secondMapView))
onView(withId(R.id.mapView))
.check(matches(isDisplayed()));
}

View File

@@ -29,12 +29,17 @@
android:name=".InfoWindowAdapterActivity"
android:label="@string/activity_infowindow_adapter" />
<activity
android:name=".InfoWindowActivity"
android:label="@string/activity_info_window" />
<activity
android:name=".MapFragmentActivity"
android:label="@string/activity_map_fragment" />
<activity android:name=".PressForMarkerActivity"
android:label="@string/activity_press_for_marker"/>
<activity
android:name=".PressForMarkerActivity"
android:label="@string/activity_press_for_marker" />
<meta-data
android:name="io.fabric.ApiKey"

View File

@@ -0,0 +1,108 @@
package com.mapbox.mapboxsdk.testapp;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import com.mapbox.mapboxsdk.views.MapView;
public class InfoWindowActivity extends AppCompatActivity {
private MapView mMapView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_infowindow);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
}
mMapView = (MapView) findViewById(R.id.mapView);
mMapView.setAccessToken(ApiAccess.getToken(this));
mMapView.onCreate(savedInstanceState);
mMapView.setStyle(Style.MAPBOX_STREETS);
mMapView.setCenterCoordinate(new LatLng(38.897705003219784, -77.03655168667463));
mMapView.setZoomLevel(15);
mMapView.addMarker(new MarkerOptions()
.title("Intersection")
.snippet("H St NW with 15th St NW")
.position(new LatLng(38.9002073, -77.03364419)));
mMapView.addMarker(new MarkerOptions()
.title("White House")
.snippet("The official residence and principal workplace of the President of the United States, located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every U.S. president since John Adams in 1800.")
.position(new LatLng(38.897705003219784, -77.03655168667463)));
mMapView.addMarker(new MarkerOptions().title("Intersection")
.snippet("E St NW with 17th St NW")
.position(new LatLng(38.8954236, -77.0394623)));
}
@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
@Override
protected void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}

View File

@@ -18,8 +18,6 @@ import com.mapbox.mapboxsdk.views.MapView;
public class InfoWindowAdapterActivity extends AppCompatActivity {
private static final String TAG = "InfoWindowAdapter";
private MapView mMapView;
@Override
@@ -27,7 +25,7 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_infowindow_adapter);
Toolbar toolbar = (Toolbar) findViewById(R.id.secondToolBar);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
@@ -36,7 +34,7 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
actionBar.setDisplayShowHomeEnabled(true);
}
mMapView = (MapView) findViewById(R.id.secondMapView);
mMapView = (MapView) findViewById(R.id.mapView);
mMapView.setAccessToken(ApiAccess.getToken(this));
mMapView.onCreate(savedInstanceState);
mMapView.setStyle(Style.MAPBOX_STREETS);
@@ -74,36 +72,34 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
return marker;
}
/**
* Dispatch onStart() to all fragments. Ensure any created loaders are
* now started.
*/
@Override
protected void onStart() {
super.onStart();
mMapView.onStart();
}
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
@Override
protected void onStop() {
super.onStop();
mMapView.onStop();
}
// Called when our app goes into the background
@Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
// Called when our app comes into the foreground
@Override
public void onResume() {
super.onResume();
mMapView.onResume();
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
@Override
@@ -112,11 +108,9 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
mMapView.onDestroy();
}
// Called when the system is running low on memory
@Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}

View File

@@ -294,19 +294,10 @@ public class MainActivity extends AppCompatActivity {
startActivity(new Intent(getApplicationContext(), PressForMarkerActivity.class));
return true;
/*
case R.id.followNone:
mMapView.setUserLocationTrackingMode(MapView.UserLocationTrackingMode.NONE);
case R.id.action_info_window:
startActivity(new Intent(getApplicationContext(), InfoWindowActivity.class));
return true;
case R.id.followFollow:
mMapView.setUserLocationTrackingMode(MapView.UserLocationTrackingMode.FOLLOW);
return true;
case R.id.followBearing:
mMapView.setUserLocationTrackingMode(MapView.UserLocationTrackingMode.FOLLOW_BEARING);
return true;
*/
default:
return changeMapStyle(menuItem.getItemId());
}

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
android:minHeight="?attr/actionBarSize"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<com.mapbox.mapboxsdk.views.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@@ -5,7 +5,7 @@
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="@+id/secondToolBar"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
@@ -13,7 +13,7 @@
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<com.mapbox.mapboxsdk.views.MapView
android:id="@+id/secondMapView"
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent" />

View File

@@ -73,11 +73,6 @@
<item android:id="@+id/testsMenu"
android:title="@string/navdrawer_menu_title_individual_tests">
<menu>
<item
android:id="@+id/action_info_window_adapter"
android:checkable="false"
android:icon="@drawable/ic_filter_none_white_24dp"
android:title="@string/action_info_window_adapter" />
<item
android:id="@+id/action_map_fragment"
@@ -85,10 +80,23 @@
android:icon="@drawable/ic_widgets_white_24dp"
android:title="@string/action_map_fragment" />
<item android:id="@+id/action_press_for_marker"
android:checkable="false"
android:icon="@drawable/ic_pin_drop_white_24dp"
android:title="@string/action_press_for_marker"/>
<item
android:id="@+id/action_info_window"
android:checkable="false"
android:icon="@drawable/ic_filter_none_white_24dp"
android:title="@string/action_info_window" />
<item
android:id="@+id/action_info_window_adapter"
android:checkable="false"
android:icon="@drawable/ic_filter_none_white_24dp"
android:title="@string/action_info_window_adapter" />
<item
android:id="@+id/action_press_for_marker"
android:checkable="false"
android:icon="@drawable/ic_pin_drop_white_24dp"
android:title="@string/action_press_for_marker"/>
</menu>
</item>

View File

@@ -7,6 +7,7 @@
<string name="activity_infowindow_adapter">InfoWindow Adapter</string>
<string name="activity_map_fragment">Map Fragment Activity</string>
<string name="activity_press_for_marker">Press For Marker Activity</string>
<string name="activity_info_window">InfoWindow Activity</string>
<string name="navdrawer_menu_title_mainactivity_controls">Main Activity Controls</string>
<string name="navdrawer_menu_title_mainactivity_styles">Main Activity Styles</string>
@@ -21,6 +22,7 @@
<string name="action_info_window_adapter">InfoWindow Adapter</string>
<string name="action_map_fragment">MapFragment</string>
<string name="action_press_for_marker">Press For Marker</string>
<string name="action_info_window">InfoWindow</string>
<string name="label_fps">FPS:</string>