在 onTap 事件上打开弹出窗口后标记更改位置
我正在开发一个 Android 应用程序作为学校项目。 它基本上是一个天气应用程序,让用户发送当地的天气信息并与其他人分享。
基本实现需要使用 Google 地图显示一些标记,并在单击标记时显示弹出窗口。
现在问题来了,标记显示正确,但是当我点击其中一个来显示弹出窗口时,标记将从原始位置移动,所有使用相同资源的标记也会随之移动......
这里有两个屏幕截图代表什么发生:
初始情况 - 点击并关闭弹出窗口后 (屏幕截图有点太大,无法嵌入它们)
正如您可能从图 2 中注意到的,三个标记向南移动...... 我知道问题是由出现的弹出窗口引起的,但我真的不知道是什么导致了这种变化。
代码很简单,是我在查资料时写的,所以可能和其他例子类似。
ItemizedOverlay 类的扩展
public class ItemizedWeather extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
private MapView mapView;
private Drawable defaultMarker;
private MarkerPopup popup;
public ItemizedWeather(Drawable defaultMarker, MapView mapView) {
super(boundCenterBottom(defaultMarker));
this.defaultMarker = defaultMarker;
this.mapView = mapView;
// popup setup
this.popup = new MarkerPopup(mapView);
// parameter
MapView.LayoutParams params = new MapView.LayoutParams(
MapView.LayoutParams.WRAP_CONTENT, // width
MapView.LayoutParams.WRAP_CONTENT, // height
null,
MapView.LayoutParams.BOTTOM_CENTER
);
params.mode = MapView.LayoutParams.MODE_MAP;
// visibility
popup.setVisibility(View.GONE);
// add to view
mapView.addView(popup, params);
}
@Override
protected OverlayItem createItem(int i) {
return mapOverlays.get(i);
}
@Override
public int size() {
return mapOverlays.size();
}
@Override
protected boolean onTap(int index) {
// get the clicked element
OverlayItem item = mapOverlays.get(index);
// set new item
popup.setData(item);
// position
GeoPoint point = item.getPoint();
// parameter
MapView.LayoutParams params = new MapView.LayoutParams(
MapView.LayoutParams.WRAP_CONTENT, // width
MapView.LayoutParams.WRAP_CONTENT, // height
point,
MapView.LayoutParams.BOTTOM_CENTER
);
params.mode = MapView.LayoutParams.MODE_MAP;
// change parameter
popup.setLayoutParams(params);
// visibility
popup.setVisibility(View.VISIBLE);
// move to point
mapView.getController().animateTo(point);
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
// Tap event
if(super.onTouchEvent(event, mapView)) return true;
// de-select
if(event.getActionMasked() == MotionEvent.ACTION_UP && popup != null) popup.setVisibility(View.GONE);
return false;
}
public void addOverlay(OverlayItem overlay, Drawable marker) {
overlay.setMarker(boundCenterBottom(marker));
mapOverlays.add(overlay);
}
public void addOverlay(OverlayItem overlay, int drawable) {
addOverlay(overlay, mapView.getResources().getDrawable(drawable));
}
public void addOverlay(OverlayItem overlay) {
addOverlay(overlay, defaultMarker);
}
public void doPopulate() {
this.populate();
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, false);
}
}
MarkerPopup 类
public class MarkerPopup extends LinearLayout {
private TextView title;
private TextView snippet;
private ImageView image;
public MarkerPopup(MapView mapView) {
super(mapView.getContext());
setupPopup(mapView);
this.setPadding(20, 10, 20, 10);
this.setVisibility(GONE);
}
private void setupPopup(ViewGroup mapView) {
LayoutInflater inflater = (LayoutInflater) mapView.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.marker_popup, this);
title = (TextView) view.findViewById(R.id.tTitle);
snippet = (TextView) view.findViewById(R.id.tSnippet);
image = (ImageView) view.findViewById(R.id.iPopupImage);
}
public void setData(OverlayItem item) {
this.setVisibility(VISIBLE);
setObjects(item);
}
private void setObjects(OverlayItem item) {
// title
if (item.getTitle() != null) {
title.setVisibility(VISIBLE);
title.setText(item.getTitle());
title.setSelected(true);
} else {
title.setText("");
title.setVisibility(INVISIBLE);
}
// snippet
if (item.getSnippet() != null) {
snippet.setVisibility(VISIBLE);
snippet.setText(item.getSnippet());
} else {
snippet.setText("");
snippet.setVisibility(INVISIBLE);
}
// marker
if(item.getMarker(0) != null) {
image.setImageDrawable(item.getMarker(0));
}
}
}
If 与解决这里的问题相关,MarkerPopup 中膨胀的弹出布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="horizontal"
android:gravity="center_vertical"
android:padding="1.5dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/black_200"
android:orientation="horizontal"
android:gravity="center_vertical"
android:padding="2dp" >
<ImageView
android:id="@+id/iPopupImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/sun"
android:contentDescription="@string/icon" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp"
>
<TextView
android:id="@+id/tTitle"
android:textColor="@color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/placeholder"
android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true"
android:scrollHorizontally="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:focusable="false" />
<TextView
android:id="@+id/tSnippet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/placeholder"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/icon"
android:src="@drawable/marker_bottom" />
</LinearLayout>
希望问题能以正确的方式完成,因为这是我第一次在这里发帖,并且有一个解决方案。
I'm doing an Android app as a school project.
It's basically a weather app that let the user send the local weather information and share it with other people.
The basic implementation require the use Google Maps to show some marker and a popup when the marker is clicked.
Now here's the problem, the markers are show correctly but when I tap on one of them to show the popup, the marker will move from the original position and with it all the markers that use the same resource...
Here two screenshot representing what happen:
Initial situation -
After tap and closing popup
(The screenshot are a little too big to embed them)
As you may notice from image 2, three markers moved south-est...
I know the issue is caused by the popup that show up but I really can't figure out what is causing the change.
The code is really simple, I wrote it while looking for information, so it's probably similar to other example.
The extension of the ItemizedOverlay class
public class ItemizedWeather extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
private MapView mapView;
private Drawable defaultMarker;
private MarkerPopup popup;
public ItemizedWeather(Drawable defaultMarker, MapView mapView) {
super(boundCenterBottom(defaultMarker));
this.defaultMarker = defaultMarker;
this.mapView = mapView;
// popup setup
this.popup = new MarkerPopup(mapView);
// parameter
MapView.LayoutParams params = new MapView.LayoutParams(
MapView.LayoutParams.WRAP_CONTENT, // width
MapView.LayoutParams.WRAP_CONTENT, // height
null,
MapView.LayoutParams.BOTTOM_CENTER
);
params.mode = MapView.LayoutParams.MODE_MAP;
// visibility
popup.setVisibility(View.GONE);
// add to view
mapView.addView(popup, params);
}
@Override
protected OverlayItem createItem(int i) {
return mapOverlays.get(i);
}
@Override
public int size() {
return mapOverlays.size();
}
@Override
protected boolean onTap(int index) {
// get the clicked element
OverlayItem item = mapOverlays.get(index);
// set new item
popup.setData(item);
// position
GeoPoint point = item.getPoint();
// parameter
MapView.LayoutParams params = new MapView.LayoutParams(
MapView.LayoutParams.WRAP_CONTENT, // width
MapView.LayoutParams.WRAP_CONTENT, // height
point,
MapView.LayoutParams.BOTTOM_CENTER
);
params.mode = MapView.LayoutParams.MODE_MAP;
// change parameter
popup.setLayoutParams(params);
// visibility
popup.setVisibility(View.VISIBLE);
// move to point
mapView.getController().animateTo(point);
return true;
}
@Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
// Tap event
if(super.onTouchEvent(event, mapView)) return true;
// de-select
if(event.getActionMasked() == MotionEvent.ACTION_UP && popup != null) popup.setVisibility(View.GONE);
return false;
}
public void addOverlay(OverlayItem overlay, Drawable marker) {
overlay.setMarker(boundCenterBottom(marker));
mapOverlays.add(overlay);
}
public void addOverlay(OverlayItem overlay, int drawable) {
addOverlay(overlay, mapView.getResources().getDrawable(drawable));
}
public void addOverlay(OverlayItem overlay) {
addOverlay(overlay, defaultMarker);
}
public void doPopulate() {
this.populate();
}
@Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, false);
}
}
The MarkerPopup class
public class MarkerPopup extends LinearLayout {
private TextView title;
private TextView snippet;
private ImageView image;
public MarkerPopup(MapView mapView) {
super(mapView.getContext());
setupPopup(mapView);
this.setPadding(20, 10, 20, 10);
this.setVisibility(GONE);
}
private void setupPopup(ViewGroup mapView) {
LayoutInflater inflater = (LayoutInflater) mapView.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.marker_popup, this);
title = (TextView) view.findViewById(R.id.tTitle);
snippet = (TextView) view.findViewById(R.id.tSnippet);
image = (ImageView) view.findViewById(R.id.iPopupImage);
}
public void setData(OverlayItem item) {
this.setVisibility(VISIBLE);
setObjects(item);
}
private void setObjects(OverlayItem item) {
// title
if (item.getTitle() != null) {
title.setVisibility(VISIBLE);
title.setText(item.getTitle());
title.setSelected(true);
} else {
title.setText("");
title.setVisibility(INVISIBLE);
}
// snippet
if (item.getSnippet() != null) {
snippet.setVisibility(VISIBLE);
snippet.setText(item.getSnippet());
} else {
snippet.setText("");
snippet.setVisibility(INVISIBLE);
}
// marker
if(item.getMarker(0) != null) {
image.setImageDrawable(item.getMarker(0));
}
}
}
If is relevant to solve the problem here the popup layout that is inflated in MarkerPopup
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_horizontal">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/white"
android:orientation="horizontal"
android:gravity="center_vertical"
android:padding="1.5dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/black_200"
android:orientation="horizontal"
android:gravity="center_vertical"
android:padding="2dp" >
<ImageView
android:id="@+id/iPopupImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/sun"
android:contentDescription="@string/icon" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dp"
>
<TextView
android:id="@+id/tTitle"
android:textColor="@color/white"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/placeholder"
android:textAppearance="?android:attr/textAppearanceLarge"
android:singleLine="true"
android:scrollHorizontally="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:focusable="false" />
<TextView
android:id="@+id/tSnippet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/placeholder"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/icon"
android:src="@drawable/marker_bottom" />
</LinearLayout>
Hope the question is done the right way as it's my first time posting here, and that there's a solution.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论