Написание MarkerInfoWindow для osmdroid

от автора

Статья предназначена для тех, у кого трудности с подключением infoWindow в osmdroid и работой с AsyncTask и просто для тех, кто раньше не делал ничего подобного 🙂 Здесь я писал о том, как я создавал окошко для получения данных об автомобиле в сервисе мониторинга транспорта.
Суть в том, что при нажатии на маркер, некоторые данные берутся из объекта, другие данные подгружаются из API, записываются в БД приложения, после чего отображаются в объекте InfoWindow.
Начинаем с создания xml файла с описанием infoWindow, добавляем поля с заголовками критериев транспорта.
image
MarkerInfoWindow позволяет записывать в Title, Description, Subdescription, я использовал только Descripton для всех нужных записей. Будем впоследствии передавать туда данные в виде строки с переносами.
Разметка выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="wrap_content"     android:layout_height="wrap_content"     android:orientation="horizontal"     android:background="@drawable/balloon_overlay_white" >     <ImageView android:id="@+id/bubble_image"         android:layout_width="65dp"         android:layout_height="65dp"         android:visibility="gone" />     <RelativeLayout         android:layout_width="wrap_content"         android:layout_height="wrap_content"         android:paddingLeft="5dp"         android:orientation="vertical" >             <TextView android:id="@+id/bubble_title"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:textColor="#000000"                 android:maxEms="17"                 android:layout_gravity="left"                 android:layout_weight="1"                 android:text="Title"                 android:textSize="18dp"                 android:textIsSelectable="false" />             <Button android:id="@+id/bubble_moreinfo"                 android:background="@drawable/btn_moreinfo"                 android:visibility="gone"                 android:layout_width="wrap_content"                 android:layout_height="wrap_content"                 android:layout_gravity="right"                 android:layout_weight="0" />         <TextView android:id="@+id/bubble_description"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textSize="14dp"             android:maxEms="17"             android:text="Description"             android:layout_toRightOf="@+id/model"             android:layout_below="@+id/bubble_title"             android:lineSpacingExtra="3dp"             android:layout_marginLeft="3dp" />         <TextView android:id="@+id/model"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textColor="#ff6c6c6c"             android:textSize="14dp"             android:maxEms="17"             android:text="@string/model"             android:layout_below="@+id/bubble_title"             android:layout_alignRight="@+id/organization" />         <TextView android:id="@+id/group"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textColor="#ff6c6c6c"             android:textSize="14dp"             android:maxEms="17"             android:text="@string/group"             android:layout_below="@+id/model"             android:layout_alignRight="@+id/organization" />         <TextView android:id="@+id/organization"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textColor="#ff6c6c6c"             android:textSize="14dp"             android:maxEms="17"             android:text="@string/organization"             android:layout_below="@+id/group" />         <TextView android:id="@+id/speed"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textColor="#ff6c6c6c"             android:textSize="14dp"             android:maxEms="17"             android:text="@string/speed"             android:layout_below="@+id/organization"             android:layout_alignRight="@+id/organization" />         <TextView android:id="@+id/update"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textColor="#ff6c6c6c"             android:textSize="14dp"             android:maxEms="17"             android:text="@string/update"             android:layout_below="@+id/speed"             android:layout_alignRight="@+id/organization" />         <TextView android:id="@+id/bubble_subdescription"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:textColor="#000000"             android:textSize="10dp"             android:maxEms="17"             android:text="Address"             android:layout_below="@+id/update" />     </RelativeLayout> </LinearLayout> 

Далее, для отображения нужных данных, пишем свой класс CarInfoWindow:

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<Object, String, Void> {          @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<Mark> marksList = null;                 List<CarModel> carModelsList = null;                 List<Group> groupsList = null; 				                 //делаем запрос в API, берем mark и model по id                 try {                     //используем retrofit                     carModelsList = Api.getService(context).getModels(token.getValue(), markId);                      int size = carModelsList.size();                     for (int i=0; i<size; i++) {                         //используем cupboard для сохранения данных в БД                         DbHelper.getInstance(context).insertCarModels(carModelsList.get(i));                      }                      groupsList = Api.getService(context).getGroups(token.getValue(), orgId);                     size = groupsList.size();                     for (int i=0; i<size; i++) {                         DbHelper.getInstance(context).insertGroups(groupsList.get(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); 


В результате проделанных манипуляций получаем нечто вроде:
image
P.S. Несмотря на то, что маркер — иконка грузовика, а в описании это Alfa Romeo, всё работает верно 🙂

ссылка на оригинал статьи http://habrahabr.ru/post/224289/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *