Написание MarkerInfoWindow для osmdroid
Статья предназначена для тех, у кого трудности с подключением infoWindow в osmdroid и работой с AsyncTask и просто для тех, кто раньше не делал ничего подобного :) Здесь я писал о том, как я создавал окошко для получения данных об автомобиле в сервисе мониторинга транспорта.Суть в том, что при нажатии на маркер, некоторые данные берутся из объекта, другие данные подгружаются из API, записываются в БД приложения, после чего отображаются в объекте InfoWindow.Начинаем с создания xml файла с описанием infoWindow, добавляем поля с заголовками критериев транспорта.MarkerInfoWindow позволяет записывать в Title, Description, Subdescription, я использовал только Descripton для всех нужных записей. Будем впоследствии передавать туда данные в виде строки с переносами.Разметка выглядит следующим образом:
public class CarInfoWindow extends MarkerInfoWindow {
Car mCar; Marker mMarker; CarInfoTask carInfoTask; Boolean stopped = false; Drawable icon; String active;
public CarInfoWindow (int layoutResId, MapView mapView) { super (layoutResId, mapView); } //при открытии запускаем asyncTask @Override public void onOpen (final Object item) { if (! stopped) { carInfoTask = new CarInfoTask (); carInfoTask.execute (item); } super.onOpen (item); } //при закрытии можем поменять иконку маркера @Override public void onClose () { stopped = false; super.onClose ();
if (!(mCar.getLastUpdate () == null)) { if (((System.currentTimeMillis () — Long.parseLong (mCar.getLastUpdate ())) / 3600000) > 1) { active = »0»; //car is not active } else { active = »1»; } } String fileName = Environment.getExternalStorageDirectory ()+»/automap/cars/icons/»+mCar.getIconIndex ()+»/»+active+»/icon.png»; icon = Utils.loadIcon (fileName, Float.parseFloat (mCar.getDirection ()), mCar.getIconType ()); mMarker.setIcon (icon); }
class CarInfoTask extends AsyncTask
@Override protected void onPreExecute () { super.onPreExecute (); }
@Override //операции по обработке данных производятся в этом методе protected Void doInBackground (Object… params) { try { //задаем нужный маркер, к которому привязан объект Car с нужными данными mMarker = (Marker)params[0]; mCar = (Car) mMarker.getRelatedObject (); //Данные, которые нужно передать в infoWindow String markName; String carModelName; String groupName; String carLastUpdate; Context context = getView ().getContext ();
//берем token, и данные из объекта Token token = Prefs.getToken (getView ().getContext ()); String markId = mCar.getMarkId (); String modelId = mCar.getModelId (); String orgId = mCar.getOrganizationId (); String groupId = mCar.getGroupId (); carLastUpdate = mCar.getLastUpdate ();
//что-нибудь делаем String formattedDate = »; if (!(carLastUpdate == null)) { long unixSeconds = Long.parseLong (carLastUpdate); Date date = new Date (unixSeconds); SimpleDateFormat sdf = new SimpleDateFormat («dd.MM.yyyy HH: mm: ss »); formattedDate = sdf.format (date); }
String organizationName = DbHelper.getInstance (context).getOrganizationStatById (orgId).getName ();
List marksList = null;
List groupsList = Api.getService (context).getGroups (token.getValue (), orgId);
size = groupsList.size ();
for (int i=0; i } catch (Exception e) {
e.printStackTrace ();
}
markName = DbHelper.getInstance (context).getMarkById (markId).getName ();
carModelName = DbHelper.getInstance (context).getCarModelById (modelId).getName ();
groupName = DbHelper.getInstance (context).getGroupById (groupId).getName ();
//записываем нужные данные сюда для передачи в UI.
publishProgress (organizationName, markName, carModelName, groupName, formattedDate);
//values[0] = organizationName, values[1] = markName и т.д. } catch (Exception e) {
e.printStackTrace ();
}
return null;
} @Override
protected void onProgressUpdate (String… values) {
super.onProgressUpdate (values);
//отображаем данные в textView, которые были переданые методом publishProgress ()
mMarker.hideInfoWindow ();
mMarker.setTitle (mCar.getCarNo () + » (» + values[1] + »)»);
mMarker.setSnippet (
values[2] + »\n» +
values[3] + »\n» +
values[0] + »\n» +
mCar.getSpeed () + »\n» +
values[4]
);
mMarker.setSubDescription (»); //можем поменять иконку маркера
String fileName = Environment.getExternalStorageDirectory ()+»/automap/cars/icons/»+mCar.getIconIndex ()+»/2/icon.png»;
icon = Utils.loadIcon (fileName, Float.parseFloat (mCar.getDirection ()), mCar.getIconType ());
mMarker.setIcon (icon);
}
//метод, в котором мы останавливаем asyncTask
@Override
protected void onPostExecute (Void result) {
stopped = true;
mMarker.showInfoWindow ();
super.onPostExecute (result);
}
}
}
Теперь при создании маркера остается всего лишь к маркеру привязать нужное окно
marker.setInfoWindow (infoWindow);
В результате проделанных манипуляций получаем нечто вроде: P.S. Несмотря на то, что маркер — иконка грузовика, а в описании это Alfa Romeo, всё работает верно :)