Nutiteq: ViewLabel: отложенное выполнение кнопки

Я пытаюсь создать Nutiteq ViewLabel с пользовательским представлением, содержащим три Button s. Мой код и проблема очень похожи на этот пост. Nutiteq: Button resp. интерактивные виды, не работающие в Custom ViewLabel.

С предоставленным ответом упомянутого поста я заметил, что onTouchEvent - Метод представления вызывается, и объект, который выполняет щелчок, публикуется обработчиком в runQueue, который запускается хореографом.

После нажатия Button в ViewLabel те внутренние звонки, которые я описал выше, случаются, но onClick -Метод из Button не выполняется, пока я не нажму где-то за пределами ViewLabel, Тогда ViewLabel закрывается (как следует, когда нажимаете на карту за ним) и Toast Я положил в onClick -Метод срабатывает.

Я думаю, что проблема имеет что-то делать UIThread, Похоже на performClick -Действие помещается в неправильный runQueue, который активен, когда у пользователя нет Label открыт.

Было бы хорошо, если у кого-то есть идея, как решить эту проблему.

Отредактировано: вот как я строю ViewLabel. Этот метод находится в классе, который вызывается 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));
}

3 ответа

Решение

После ответа команды nutiteq в группах Google, у которых также не было решения ( см. Здесь), я решил полностью избавиться от ViewLabel.

Мое решение теперь заключалось в том, чтобы включить макет подготовленного представления poi в файл макета MapActivity и загрузить его вместе с моей собственной реализацией MapListener. Все инициализации элементов представления poi я сделал в конструкторе MapListener и просто изменил видимость, когда метод onVectorElementClicked назывался. Вот фрагмент, как это выглядит в основном:

 @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();
}

Я был вдохновлен альтернативой ViewLabel в документации по GitHub от nutiteq, см. Здесь "Использование стандартных инструментов разметки Android"

Конструктор ViewLabel в Nutiteq SDK принимает объект Handler в качестве аргумента. Он использует этот обработчик для публикации перерисовки меток и касания сообщений о событиях. Сначала я бы проверил, правильно ли подключен ваш обработчик к потоку пользовательского интерфейса. Дополнительная информация об этом здесь: https://developer.android.com/training/multiple-threads/communicate-ui.html

Для тех, кто все еще хочет использовать пользовательский вид, вот обходной путь, который я нашел. Я обнаружил, что событие, вызванное в пользовательском представлении, будет выполнено после onMapMoved Событие. Таким образом, я вручную запускаю его. Вот код:

замещать YourViewID с вашим собственным идентификатором макета представления и YourButtonID с идентификатором кнопки. Добавьте код ниже, где вы создаете 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;
    }
});

замещать YourBaseLayoutID с вашим корневым идентификатором макета и yourMapView с вашим объектом MapView. Добавьте код ниже, чтобы 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;
    }
});
Другие вопросы по тегам