地図の中心にマーカーがあるとします。指で地図を移動すると、エリアの境界から出たときにマーカーが表示されなくなることがわかります。それでは、マップをどこかに移動しても常にマップの中心に残るマーカーを作成するにはどうすればよいでしょうか? UBERという名前のアプリがあり、この機能を提供します。マーカーをドラッグアンドドロップするだけで、マップを移動するだけで、マーカーはその位置のままになります。
これがスクリーンショットです:
ご覧のとおり、マップを移動すると緑色のマーカーが画面の中央に表示されますが、マップはその場所のままですが、ユーザーがマップの移動を停止すると新しい位置が表示されます。どうすればこのようにできますか?
マーカーをドラッグ&ドロップしたときに住所を表示するコードがありますが、今度は地図をドラッグして移動するのではなく、住所をもう一度表示してみてはどうでしょうか。どんなアイデアでも素晴らしいと理解できることを願っています。
public class MainActivity extends AbstractMapActivity implements
OnNavigationListener, OnInfoWindowClickListener,
OnMarkerDragListener {
private static final String STATE_NAV="nav";
private static final int[] MAP_TYPE_NAMES= { R.string.normal,
R.string.hybrid, R.string.satellite, R.string.terrain };
private static final int[] MAP_TYPES= { GoogleMap.MAP_TYPE_NORMAL,
GoogleMap.MAP_TYPE_HYBRID, GoogleMap.MAP_TYPE_SATELLITE,
GoogleMap.MAP_TYPE_TERRAIN };
private GoogleMap map=null;
String filterAddress = "";
Marker marker;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (readyToGo()) {
setContentView(R.layout.activity_main);
SupportMapFragment mapFrag=
(SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.setRetainInstance(true);
initListNav();
map=mapFrag.getMap();
if (savedInstanceState == null) {
CameraUpdate center=
CameraUpdateFactory.newLatLng(new LatLng(
41.003739,
28.999572));
CameraUpdate zoom=CameraUpdateFactory.zoomTo(10);
map.moveCamera(center);
map.animateCamera(zoom);
addMarker(map, 41.003739, 28.999572, R.string.un, R.string.united_nations);
map.setInfoWindowAdapter(new PopupAdapter(getLayoutInflater()));
map.setOnInfoWindowClickListener(this);
map.setOnMarkerDragListener(this);
}
}
}
@Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
map.setMapType(MAP_TYPES[itemPosition]);
return(true);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt(STATE_NAV,
getSupportActionBar().getSelectedNavigationIndex());
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
getSupportActionBar().setSelectedNavigationItem(savedInstanceState.getInt(STATE_NAV));
}
@Override
public void onInfoWindowClick(Marker marker) {
Toast.makeText(this, marker.getTitle(), Toast.LENGTH_LONG).show();
}
@Override
public void onMarkerDragStart(Marker marker) {
LatLng position=marker.getPosition();
Log.d(getClass().getSimpleName(), String.format("Drag from %f:%f",
position.latitude,
position.longitude));
}
@Override
public void onMarkerDrag(Marker marker) {
LatLng position=marker.getPosition();
Log.d(getClass().getSimpleName(),
String.format("Dragging to %f:%f", position.latitude,
position.longitude));
}
@Override
public void onMarkerDragEnd(Marker marker) {
LatLng position=marker.getPosition();
String filterAddress = "";
Geocoder geoCoder = new Geocoder(
getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(
position.latitude,
position.longitude, 1);
if (addresses.size() > 0) {
for (int index = 0;
index < addresses.get(0).getMaxAddressLineIndex(); index++)
filterAddress += addresses.get(0).getAddressLine(index) + " ";
}
}catch (IOException ex) {
ex.printStackTrace();
}catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
}
Log.d(getClass().getSimpleName(),
String.format("Dragging to %f:%f", position.latitude,
position.longitude));
TextView myTextView = (TextView) findViewById(R.id.test);
myTextView.setText("Address is: " + filterAddress);
}
private void initListNav() {
ArrayList<String> items=new ArrayList<String>();
ArrayAdapter<String> nav=null;
ActionBar bar=getSupportActionBar();
for (int type : MAP_TYPE_NAMES) {
items.add(getString(type));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
nav=
new ArrayAdapter<String>(
bar.getThemedContext(),
Android.R.layout.simple_spinner_item,
items);
}
else {
nav=
new ArrayAdapter<String>(
this,
Android.R.layout.simple_spinner_item,
items);
}
nav.setDropDownViewResource(Android.R.layout.simple_spinner_dropdown_item);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
bar.setListNavigationCallbacks(nav, this);
}
private void addMarker(GoogleMap map, double lat, double lon,
int title, int snippet)
{
map.addMarker(new MarkerOptions().position(new LatLng(lat, lon))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.pin))
.draggable(true));
}
}
これがxmlです
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/layout1"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_below="@+id/img_header" >
<fragment
Android:id="@+id/map"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
class="com.google.Android.gms.maps.SupportMapFragment" />
<TextView
Android:id="@+id/test"
Android:layout_width="match_parent"
Android:layout_height="90dp"
Android:layout_alignParentRight="true"
Android:text="Address : "
Android:textColor="#FF0000"
Android:textSize="22sp" />
</RelativeLayout>
私はRelativeLayoutをフラグメントの親として使用し、マップとImageViewの中心に配置します(これは、uberまたは簡単なタクシーアプリのように中央のマップマーカーとして機能します):
_<!-- Map and ImageView in center for simulating the map marker -->
<RelativeLayout
Android:id="@+id/confirm_address_map_wrapper"
Android:layout_width="match_parent"
Android:layout_height="220dp">
<fragment
Android:id="@+id/confirm_address_map_fragment"
Android:name="com.google.Android.gms.maps.MapFragment"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:layout_centerInParent="true"
/>
<!-- Image View that acts as map marker notice centerInParent-->
<View
Android:id="@+id/view"
Android:layout_width="1dp"
Android:layout_height="1dp"
Android:layout_centerInParent="true"/>
<ImageView
Android:id="@+id/confirm_address_map_custom_marker"
Android:layout_width="@dimen/ICON_DEFAULT_SIZE"
Android:layout_height="@dimen/ICON_DEFAULT_SIZE"
Android:layout_above="@+id/view"
Android:layout_centerHorizontal="true"
Android:src="@mipmap/my_map_marker"/>
</RelativeLayout>
_
アクティビティでのonMapReady()メソッドgoogleMapインスタンスメソッドsetOnCameraChangeListener()
を使用します。これにより、マップの使用時にリッスンし、カメラ位置の中心に基づいて緯度と経度を取得できます。
_ @Override
public void onMapReady(GoogleMap googleMap) {
googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
Log.i("centerLat",cameraPosition.target.latitude);
Log.i("centerLong",cameraPosition.target.longitude);
}
});
}
_
UPDATE:OnCameraChangeListener
は非推奨です。 OnCameraIdleListener
を使用してください:
[出典: https://stackoverflow.com/a/38732283/421467]
私はUberアプリの効果を得ることができませんでしたが、似たようなことをすることができました。おそらく、 GoogleMap.OnCameraChangeListener を使用してソリューションにうまくいくでしょう。
アクティビティ:
public class MyActivity extends Activity implements OnCameraChangeListener {
...
@Override
public void onCameraChange(CameraPosition position) {
mMap.clear();
mMap.addMarker( new MarkerOptions()
.position( position.target )
.title( position.toString() )
);
}
...
}
問題は、カメラの移動中にマーカーが描画されないことです。ただし、マーカーのオーバーレイが既に作成されているようです。したがって、オーバーレイを使用すると、Uberアプリケーションのように機能するはずです。
質問が数か月前のものであっても、これが助けになることを願っています。おそらく、将来の開発者に役立つでしょう。
よろしくミキ
Fragment
を使用してGoogleマップを表示している場合、ImageView
をFragment
内に配置して、カスタマイズしたマーカーをオーバーレイして、マップを移動するときにマーカーが固定されるようにします。 xmlファイルのコードに従います。
_<fragment
Android:id="@+id/map"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
class="com.google.Android.gms.maps.MapFragment" >
<ImageView
Android:id="@+id/pin"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_gravity="center"
Android:contentDescription="@null"
Android:src="@drawable/pin" />
</fragment>
_
Activity.Javaファイルでこれを使用します。
_ImageView pinButton = (ImageView) findViewById(R.id.pin);
_
setOnCameraChangeListener()
を使用して、カメラの位置の中心に基づいて緯度と経度を取得するか、@ androidPlusPlusが提供する回答に従う
チェック this answer
最初:同じレイアウトと中央に等しい位置にイメージビューを追加します。 2番目:マップの中心の座標を取得するには、次のアプローチを使用します
1_ get viewgroup ( FrameLayout ) in my case where the map fragment is located.
- FrameLayout myContainer = (FrameLayout) findViewById(R.id.content_frame);
int mapHeight = myContainer.getHeight();
int mapWidth = myContainer.getWidth();
2_ use setOnCameraChangeListener and on camera change get the coordinates:
LatLng center = mMap.getCameraPosition().target;
また、 こちら は私の完全なソリューションです
mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
mCurrLocationMarker.remove();
LatLng midLatLng = mMap.getCameraPosition().target;
mCurrLocationMarker = mMap.addMarker(new MarkerOptions().title("I am here ").
position(midLatLng).icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_point));
}
});
mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
@Override
public void onCameraIdle() {
mCurrLocationMarker.remove();
LatLng position = mCurrLocationMarker.getPosition();
mCurrLocationMarker = mMap.addMarker(new MarkerOptions().title("I am here ").
position(position).icon(BitmapDescriptorFactory.fromResource(R.mipmap.ic_source)));
getAddress(position.latitude, position.longitude);
}
});