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