ReZa ReZa - 4 months ago 15
Android Question

Choose a Location on mapview on view Touch

in my app , i want the user to choose a location on 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 work 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 event to the bottom of view , so i need this line .

how can i solve this problem?

Answer

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