in my app, I want the user to choose a location on a map with tapping on a view that is on top of MapView.
this is my code:
map_fragment.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal|center_vertical"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.osmdroid.views.MapView
android:id="@+id/mapview"
tilesource="Mapnik"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<View
android:id="@+id/view_choose"
android:layout_width="50dp"
android:layout_height="70dp"
android:layout_gravity="center_horizontal|center_vertical"
android:background="@drawable/choose" />
</FrameLayout>
MapFragment.java
import butterknife.Bind;
import butterknife.ButterKnife;
import org.osmdroid.bonuspack.overlays.MapEventsReceiver;
import org.osmdroid.bonuspack.overlays.MapEventsOverlay;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
import android.view.MotionEvent;
import android.view.View;
import android.support.v4.app.Fragment;
public class MapFragment extends Fragment {
public static final String TAG = "MapFragment";
@Bind(R.id.mapview)
MapView mapView;
@Bind(R.id.view_choose)
View mChooseView;
boolean isChooseTouched = false;
public MapFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_map, container, false);
ButterKnife.bind(this, view);
init();
return view;
}
private void init() {
mapView.setTileSource(TileSourceFactory.MAPNIK);
mapView.getOverlays().add(0, new MapEventsOverlay(getActivity(), new MyMapEventsReceiver()));
mChooseView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
isChooseTouched = true;
int artificialX = (view.getWidth() / 2);
int artificialY = (view.getHeight());
event.setLocation(artificialX, artificialY);
return false;
}
});
}
class MyMapEventsReceiver implements MapEventsReceiver {
@Override
public boolean singleTapConfirmedHelper(GeoPoint geoPoint) {
if (isChooseTouched) {
Log.d(TAG,"location selected");
// some other calculation
isChooseTouched = false;
return true;
}
return false;
}
@Override
public boolean longPressHelper(GeoPoint geoPoint) {
return false;
}
}
}
I have tested this code on 4 devices .
in two of them, it works. and the Log prints
but in other two devices, it doesn't work. it just moves the mapview and the Log is not printed.
the point is when I remove this line :
event.setLocation(artificialX, artificialY);
from the code, it works on all of the devices .
again when I set the above line to something like this :
event.setLocation(artificialX, artificialY-30);
it works again.
but I need to change the location of the event to the bottom of the view , so I need this line.
how can i solve this problem?
ok i solved it with this :
mChooseView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
isChooseTouched = true;
int artificialX = (view.getWidth() / 2);
int artificialY = (view.getHeight()) - 5;
float x = view.getLeft() + artificialX;
float y = view.getTop() + artificialY;
event.setLocation(x, y);
mapView.dispatchTouchEvent(event);
return true;
}
});