androidosmdroidandroid-event

Choose a Location on mapview on view Touch


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?


Solution

  • 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;
        }
    });