3

I am trying to create a nutiteq ViewLabel with an custom view containing three Buttons. My code and the problem are very similar to this post nutiteq: Button resp. clickable Views not working in Custom ViewLabel.

With the provided answer of the referred post I noticed that the onTouchEvent-Method of the view is called and that the object which performs the click is posted by a handler to a runQueue which is triggered by the Choreographer.

After pressing a Button in the ViewLabel those internal calls I've described above happen, but the onClick-Method of the Button is not executed until I press somewhere outside the ViewLabel. Then the ViewLabel closes (like it should, when are pressing on the map behind it) and Toast I put in the onClick-Method is triggered.

I think the problem has something to do the UIThread. Seems like the performClick-Action is put into the wrong runQueue, which is active when the user doesn't have a Label opened.

It would be nice if someone has an idea, how to solve that problem.

Edited: Here is how i build the ViewLabel. This method is in a class which is called by the MapActivity:

    public void createViewMarker(View markerView, Bitmap icon, MapPos pos, Category cat, String tag) {
    MarkerStyle markerStyle = MarkerStyle.builder().setBitmap(icon).setSize(0.5f).setColor(
            Color.WHITE).build();
    ViewLabel label = new ViewLabel(markerView, new Handler(Looper.getMainLooper()));
    label.setTouchHandlingMode(true);
    markers.add(new MocaMarker(pos, label, markerStyle, cat,
            markerLayer, tag));
}
Community
  • 1
  • 1
pekayde
  • 118
  • 10
  • can you provide a bit of code? Especially how you are building the `ViewLabel`? – Valentino Ru Mar 16 '15 at 12:24
  • 1
    @ValentinoRu The MapActivity calls a Map-class which has this method `public void createViewMarker(View markerView, Bitmap icon, MapPos pos, Category cat, String tag) { MarkerStyle markerStyle = MarkerStyle.builder().setBitmap(icon).setSize(0.5f).setColor( Color.WHITE).build(); ViewLabel label = new ViewLabel(markerView, new Handler(Looper.getMainLooper())); label.setTouchHandlingMode(true); markers.add(new MocaMarker(pos, label, markerStyle, cat, markerLayer, tag)); }` – pekayde Mar 16 '15 at 22:44

3 Answers3

3

After the response of the nutiteq team in google groups who also didn't have a solution ( see here) i decided to get rid of the ViewLabel completely.

My solution now was to include the layout of the prepared poi view into the MapActivity layout file and load it together with my custom implementation of the MapListener. All initialization of the poi view elements i did in the constructor of the MapListener and just changed the visiblity when the method onVectorElementClicked was called. Here is a snippet how it basically looks:

 @Override
public void onMapClicked(double x, double y, boolean b) {
    Toast.makeText(activity, "onMapClicked " + (new EPSG3857()).toWgs84(x, y).x + " " + (new EPSG3857()).toWgs84(x, y).y, Toast.LENGTH_SHORT).show();
    Log.d(TAG, "onMapClicked " + x + " " + y);
    activity.runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mPoiGlanceView.setVisibility(View.INVISIBLE);
        }
    });
}

@Override
public void onVectorElementClicked(VectorElement vectorElement, double v, double v2, boolean b) {
    if (vectorElement != null && vectorElement instanceof Marker) {
        showPopupView(vectorElement);
        Toast.makeText(activity, "onLabelClicked Marker!", Toast.LENGTH_SHORT).show();
    }
}

private void showPopupView(VectorElement vectorElement) {
    mPoiGlanceView.setVisibility(View.VISIBLE);
    setUpUiElementsForView();
}

I was inspired by the ViewLabel alternative at the github documentation of nutiteq see here "Use Android standard Layout tools"

pekayde
  • 118
  • 10
1

ViewLabel constructor in Nutiteq SDK takes a Handler object as an argument. It uses this handler to post label redrawing and touch event messages. First I would check if your handler is properly connected to the UI thread. There is additional information about this here: https://developer.android.com/training/multiple-threads/communicate-ui.html

MarkT
  • 301
  • 2
  • 2
  • So we can't just pass a `new Handler()`in the constructor of ViewLabel? – Valentino Ru Mar 16 '15 at 12:18
  • Thanks for you suggestion @MarkT. I created a Handler like in the posted like described with `ViewLabel label = new ViewLabel(markerView, new Handler(Looper.getMainLooper()));` still the same result. I guess the problem is that the Handler i am feeding is in the mainLooper anyway and an opened ViewLabel is living in another thread so that the MainLooper continues after the Label is closed. At least it would be an explanation. – pekayde Mar 16 '15 at 22:42
1

For those who still want to use the custom view, here is a work around that I found. I found that the event triggered in the custom view will be executed after onMapMoved Event. Thus, I manually trigger it. Here is the code:

Replace YourViewID with your custom view layout ID and YourButtonID with the button ID. Add the code below to where you create the ViewLabel

View v = getLayoutInflater().inflate(R.layout.YourViewID, null);
((Button)v.findViewById(R.id.YourButtonID)).setOnTouchListener(new View.OnTouchListener(){
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        //Trigger only when users release the button
        if(motionEvent.getActionMasked()==MotionEvent.ACTION_UP){
            //Do your work
        }
        //Do not consume the OnTouch event
        return false;
    }
});

Replace YourBaseLayoutID with your root layout ID and yourMapView with your MapView object. Add the code below to OnCreate().

findViewById(R.id.YourBaseLayoutID).setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if(motionEvent.getActionMasked()==MotionEvent.ACTION_UP)
            yourMapView.getOptions().getMapListener().onMapMoved();
        return false;
    }
});
Joshua
  • 5,901
  • 2
  • 32
  • 52