Implement favorite points
This commit is contained in:
parent
3ac8381c2c
commit
4bfa61c8b3
10 changed files with 531 additions and 107 deletions
17
OsmAnd/res/layout/favourite_edit_dialog.xml
Normal file
17
OsmAnd/res/layout/favourite_edit_dialog.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="3dp"
|
||||
android:paddingRight="3dp" android:stretchColumns="1">
|
||||
<TableRow >
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="Name"/>
|
||||
<EditText android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="3dp"
|
||||
android:id="@+id/Name"/>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:text="Category"/>
|
||||
<AutoCompleteTextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="3dp"
|
||||
android:id="@+id/Category" android:completionThreshold="1"/>
|
||||
</TableRow>
|
||||
</TableLayout>
|
24
OsmAnd/res/layout/favourites_list.xml
Normal file
24
OsmAnd/res/layout/favourites_list.xml
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" android:orientation="vertical">
|
||||
|
||||
<LinearLayout android:id="@+id/LoadingPanel" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_marginTop="3dp"
|
||||
android:visibility="gone">
|
||||
<LinearLayout android:id="@+id/FillLayoutStart" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/>
|
||||
<Button android:id="@+id/ActionButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/default_buttons_delete"
|
||||
android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp" android:visibility="gone"/>
|
||||
<Button android:id="@+id/CancelButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/default_buttons_cancel"
|
||||
android:layout_marginLeft = "3dp" android:layout_marginTop ="3dp" android:layout_marginRight = "3dp" android:visibility="gone"/>
|
||||
|
||||
<LinearLayout android:id="@+id/FillLayoutEnd" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"/>
|
||||
<ProgressBar android:id="@+id/ProgressBar" android:layout_marginLeft="5dp" android:indeterminate="true" android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:layout_marginRight="5dp" android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
<ExpandableListView android:id="@android:id/list" android:layout_width="fill_parent" android:layout_weight="1" android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="3dp" android:layout_marginTop="3dp" android:layout_marginRight="3dp" ></ExpandableListView>
|
||||
|
||||
</LinearLayout>
|
12
OsmAnd/res/layout/favourites_list_category.xml
Normal file
12
OsmAnd/res/layout/favourites_list_category.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" android:paddingLeft="40dp">
|
||||
|
||||
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/check_item" android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical" android:focusable="false" android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
<TextView android:id="@+id/category_name" android:gravity="center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:textSize="21sp"></TextView>
|
||||
|
||||
</LinearLayout>
|
|
@ -1,11 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
android:orientation="horizontal" android:paddingLeft="10dp">
|
||||
|
||||
<LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||
<CheckBox android:id="@+id/check_item" android:layout_width="wrap_content" android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical" android:focusable="false" android:visibility="gone"/>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView android:id="@+id/favourite_icon" android:layout_width="25dp"
|
||||
android:paddingLeft="2dp" android:paddingRight="2dp"
|
||||
android:paddingTop="2dp" android:layout_height="fill_parent" />
|
||||
android:paddingRight="2dp" android:paddingTop="2dp" android:layout_height="fill_parent" />
|
||||
|
||||
<TextView android:id="@+id/favouritedistance_label"
|
||||
android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<resources>
|
||||
<string name="favourites_delete_multiple_succesful">Favorite points deleted successfully.</string>
|
||||
<string name="favorite_delete_multiple">You are going to delete %1$d favorites and %2$d groups. Are you sure?</string>
|
||||
<string name="favorite_home_category">Home</string>
|
||||
<string name="favorite_friends_category">Friends</string>
|
||||
<string name="favorite_places_category">Places</string>
|
||||
|
|
|
@ -11,9 +11,10 @@ public class FavouritePoint {
|
|||
public FavouritePoint(){
|
||||
}
|
||||
|
||||
public FavouritePoint(double latitude, double longitude, String name) {
|
||||
public FavouritePoint(double latitude, double longitude, String name, String category) {
|
||||
this.latitude = latitude;
|
||||
this.longitude = longitude;
|
||||
this.category = category;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,18 +40,24 @@ public class FavouritesDbHelper extends SQLiteOpenHelper {
|
|||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
db.execSQL(FAVOURITE_TABLE_CREATE);
|
||||
createCategories(db);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
|
||||
if(oldVersion == 1){
|
||||
db.execSQL("ALTER TABLE " + FAVOURITE_TABLE_NAME + " ADD COLUMN (" + FAVOURITE_COL_CATEGORY + " text)");
|
||||
db.execSQL("ALTER TABLE " + FAVOURITE_TABLE_NAME + " ADD " + FAVOURITE_COL_CATEGORY + " text");
|
||||
createCategories(db);
|
||||
db.execSQL("UPDATE " + FAVOURITE_TABLE_NAME + " SET category = ?", new Object[] { context.getString(R.string.favorite_default_category)}); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
addCategoryQuery(context.getString(R.string.favorite_home_category), db);
|
||||
addCategoryQuery(context.getString(R.string.favorite_friends_category), db);
|
||||
addCategoryQuery(context.getString(R.string.favorite_places_category), db);
|
||||
}
|
||||
}
|
||||
|
||||
private void createCategories(SQLiteDatabase db){
|
||||
addCategoryQuery(context.getString(R.string.favorite_home_category), db);
|
||||
addCategoryQuery(context.getString(R.string.favorite_friends_category), db);
|
||||
addCategoryQuery(context.getString(R.string.favorite_places_category), db);
|
||||
addCategoryQuery(context.getString(R.string.favorite_default_category), db);
|
||||
}
|
||||
|
||||
public List<FavouritePoint> getFavoritePointsFromGPXFile() {
|
||||
return favoritePointsFromGPXFile;
|
||||
|
@ -77,6 +83,11 @@ public class FavouritesDbHelper extends SQLiteOpenHelper {
|
|||
return cachedFavoritePoints;
|
||||
}
|
||||
|
||||
public Map<String, List<FavouritePoint>> getFavoriteGroups() {
|
||||
checkFavoritePoints();
|
||||
return favoriteGroups;
|
||||
}
|
||||
|
||||
|
||||
public boolean editFavouriteName(FavouritePoint p, String newName, String category) {
|
||||
checkFavoritePoints();
|
||||
|
@ -88,6 +99,10 @@ public class FavouritesDbHelper extends SQLiteOpenHelper {
|
|||
p.setCategory(category);
|
||||
if(!oldCategory.equals(category)){
|
||||
favoriteGroups.get(oldCategory).remove(p);
|
||||
if(!favoriteGroups.containsKey(category)){
|
||||
addCategoryQuery(category, db);
|
||||
favoriteGroups.put(category, new ArrayList<FavouritePoint>());
|
||||
}
|
||||
favoriteGroups.get(category).add(p);
|
||||
}
|
||||
return true;
|
||||
|
@ -133,9 +148,21 @@ public class FavouritesDbHelper extends SQLiteOpenHelper {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean deleteGroup(String group){
|
||||
checkFavoritePoints();
|
||||
FavouritePoint fp = new FavouritePoint(0, 0, "", group);
|
||||
if(deleteFavourite(fp)){
|
||||
favoriteGroups.remove(group);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean addFavourite(FavouritePoint p) {
|
||||
checkFavoritePoints();
|
||||
if(p.getName().equals("") && favoriteGroups.containsKey(p.getCategory())){
|
||||
return true;
|
||||
}
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
if (db != null) {
|
||||
// delete with same name before
|
||||
|
@ -144,10 +171,15 @@ public class FavouritesDbHelper extends SQLiteOpenHelper {
|
|||
" (" +FAVOURITE_COL_NAME +", " +FAVOURITE_COL_CATEGORY +", " +FAVOURITE_COL_LAT +", " +FAVOURITE_COL_LON + ")" +
|
||||
" VALUES (?, ?, ?, ?)", new Object[] { p.getName(), p.getCategory(), p.getLatitude(), p.getLongitude() }); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
if(!favoriteGroups.containsKey(p.getCategory())){
|
||||
if (!p.getName().equals("")) {
|
||||
addFavourite(new FavouritePoint(0, 0, "", p.getCategory()));
|
||||
}
|
||||
favoriteGroups.put(p.getCategory(), new ArrayList<FavouritePoint>());
|
||||
}
|
||||
favoriteGroups.get(p.getCategory()).add(p);
|
||||
cachedFavoritePoints.add(p);
|
||||
if(!p.getName().equals("")){
|
||||
favoriteGroups.get(p.getCategory()).add(p);
|
||||
cachedFavoritePoints.add(p);
|
||||
}
|
||||
p.setStored(true);
|
||||
return true;
|
||||
}
|
||||
|
@ -172,7 +204,7 @@ public class FavouritesDbHelper extends SQLiteOpenHelper {
|
|||
private void checkFavoritePoints(){
|
||||
if(favoriteGroups == null){
|
||||
favoriteGroups = new LinkedHashMap<String, List<FavouritePoint>>();
|
||||
SQLiteDatabase db = getReadableDatabase();
|
||||
SQLiteDatabase db = getWritableDatabase();
|
||||
if (db != null) {
|
||||
Cursor query = db.rawQuery("SELECT " + FAVOURITE_COL_NAME + ", " + FAVOURITE_COL_CATEGORY + ", " + FAVOURITE_COL_LAT + "," + FAVOURITE_COL_LON + " FROM " + //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
|
||||
FAVOURITE_TABLE_NAME, null);
|
||||
|
|
|
@ -6,9 +6,10 @@ package net.osmand.plus.activities;
|
|||
import java.io.File;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import net.osmand.FavouritePoint;
|
||||
|
@ -24,10 +25,11 @@ import net.osmand.plus.OsmandSettings;
|
|||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.ResourceManager;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ListActivity;
|
||||
import android.app.ExpandableListActivity;
|
||||
import android.app.AlertDialog.Builder;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -37,17 +39,20 @@ import android.view.View;
|
|||
import android.view.ViewGroup;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.BaseExpandableListAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ExpandableListView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class FavouritesActivity extends ListActivity {
|
||||
public class FavouritesActivity extends ExpandableListActivity {
|
||||
|
||||
public static final int SHOW_ON_MAP = 0;
|
||||
public static final int NAVIGATE_TO = 1;
|
||||
|
@ -56,6 +61,7 @@ public class FavouritesActivity extends ListActivity {
|
|||
|
||||
public static final int EXPORT_ID = 0;
|
||||
public static final int IMPORT_ID = 1;
|
||||
public static final int DELETE_ID = 2;
|
||||
|
||||
public static final String FILE_TO_SAVE = "favourites.gpx"; //$NON-NLS-1$
|
||||
|
||||
|
@ -63,25 +69,37 @@ public class FavouritesActivity extends ListActivity {
|
|||
private FavouritesAdapter favouritesAdapter;
|
||||
private FavouritesDbHelper helper;
|
||||
|
||||
private boolean selectionMode = false;
|
||||
private Set<FavouritePoint> favoritesToDelete = new LinkedHashSet<FavouritePoint>();
|
||||
private Set<String> groupsToDelete = new LinkedHashSet<String>();
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
ListView lv = new ListView(this);
|
||||
lv.setId(android.R.id.list);
|
||||
setContentView(lv);
|
||||
setContentView(R.layout.favourites_list);
|
||||
|
||||
|
||||
helper = ((OsmandApplication)getApplication()).getFavorites();
|
||||
favouritesAdapter = new FavouritesAdapter();
|
||||
favouritesAdapter.setFavoriteGroups(helper.getFavoriteGroups());
|
||||
getExpandableListView().setAdapter(favouritesAdapter);
|
||||
|
||||
/* Add Context-Menu listener to the ListView. */
|
||||
lv.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener(){
|
||||
getExpandableListView().setOnCreateContextMenuListener(new View.OnCreateContextMenuListener(){
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
|
||||
int child = ExpandableListView.getPackedPositionChild(((ExpandableListContextMenuInfo)menuInfo).packedPosition);
|
||||
int group = ExpandableListView.getPackedPositionGroup(((ExpandableListContextMenuInfo)menuInfo).packedPosition);
|
||||
if (child == -1) {
|
||||
return;
|
||||
}
|
||||
menu.setHeaderTitle(R.string.favourites_context_menu_title);
|
||||
|
||||
menu.add(0, SHOW_ON_MAP, 0, R.string.show_poi_on_map);
|
||||
menu.add(0, NAVIGATE_TO, 1, R.string.favourites_context_menu_navigate);
|
||||
final FavouritePoint point = (FavouritePoint) favouritesAdapter.getItem(((AdapterContextMenuInfo)menuInfo).position);
|
||||
|
||||
final FavouritePoint point = (FavouritePoint) favouritesAdapter.getChild(group, child);
|
||||
if(point.isStored()){
|
||||
menu.add(0, EDIT_ITEM, 2, R.string.favourites_context_menu_edit);
|
||||
menu.add(0, DELETE_ITEM, 3, R.string.favourites_context_menu_delete);
|
||||
|
@ -89,46 +107,140 @@ public class FavouritesActivity extends ListActivity {
|
|||
}
|
||||
|
||||
});
|
||||
|
||||
findViewById(R.id.CancelButton).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
cancelSelectingMode();
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
findViewById(R.id.ActionButton).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(groupsToDelete.size() + favoritesToDelete.size() > 0){
|
||||
|
||||
Builder b = new AlertDialog.Builder(FavouritesActivity.this);
|
||||
b.setMessage(getString(R.string.favorite_delete_multiple, favoritesToDelete.size(),
|
||||
groupsToDelete.size()));
|
||||
b.setPositiveButton(R.string.default_buttons_delete, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
cancelSelectingMode();
|
||||
deleteFavorites();
|
||||
}
|
||||
});
|
||||
b.setNegativeButton(R.string.default_buttons_cancel, null);
|
||||
b.show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void cancelSelectingMode() {
|
||||
selectionMode = false;
|
||||
findViewById(R.id.ActionButton).setVisibility(View.GONE);
|
||||
findViewById(R.id.CancelButton).setVisibility(View.GONE);
|
||||
findViewById(R.id.LoadingPanel).setVisibility(View.GONE);
|
||||
favouritesAdapter.notifyDataSetInvalidated();
|
||||
}
|
||||
|
||||
private void deleteFavorites() {
|
||||
new AsyncTask<Void, Object, String>(){
|
||||
|
||||
protected void onPreExecute() {
|
||||
showProgressBar();
|
||||
};
|
||||
protected void onPostExecute(String result) {
|
||||
hideProgressBar();
|
||||
favouritesAdapter.synchronizeGroups();
|
||||
};
|
||||
|
||||
protected void onProgressUpdate(Object... values) {
|
||||
for(Object o : values){
|
||||
if(o instanceof FavouritePoint){
|
||||
favouritesAdapter.deleteFavoritePoint((FavouritePoint) o);
|
||||
} else if(o instanceof String){
|
||||
favouritesAdapter.deleteCategory((String) o);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
for (FavouritePoint fp : favoritesToDelete) {
|
||||
helper.deleteFavourite(fp);
|
||||
publishProgress(fp);
|
||||
}
|
||||
favoritesToDelete.clear();
|
||||
for (String group : groupsToDelete) {
|
||||
helper.deleteGroup(group);
|
||||
publishProgress(group);
|
||||
}
|
||||
groupsToDelete.clear();
|
||||
return getString(R.string.favourites_delete_multiple_succesful);
|
||||
}
|
||||
|
||||
}.execute();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
helper = ((OsmandApplication)getApplication()).getFavorites();
|
||||
ArrayList<FavouritePoint> list = new ArrayList<FavouritePoint>(helper.getFavouritePoints());
|
||||
favouritesAdapter = new FavouritesAdapter(list);
|
||||
favouritesAdapter.synchronizeGroups();
|
||||
final LatLon mapLocation = OsmandSettings.getOsmandSettings(this).getLastKnownMapLocation();
|
||||
if(mapLocation != null){
|
||||
favouritesAdapter.sort(new Comparator<FavouritePoint>(){
|
||||
|
||||
@Override
|
||||
public int compare(FavouritePoint object1, FavouritePoint object2) {
|
||||
double d1 = MapUtils.getDistance(mapLocation, object1.getLatitude(), object1.getLongitude());
|
||||
double d2 = MapUtils.getDistance(mapLocation, object2.getLatitude(), object2.getLongitude());
|
||||
if(d1 == d2){
|
||||
return 0;
|
||||
} else if(d1 > d2){
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
});
|
||||
// TODO sort
|
||||
// favouritesAdapter.sort(new Comparator<FavouritePoint>(){
|
||||
//
|
||||
// @Override
|
||||
// public int compare(FavouritePoint object1, FavouritePoint object2) {
|
||||
// double d1 = MapUtils.getDistance(mapLocation, object1.getLatitude(), object1.getLongitude());
|
||||
// double d2 = MapUtils.getDistance(mapLocation, object2.getLatitude(), object2.getLongitude());
|
||||
// if(d1 == d2){
|
||||
// return 0;
|
||||
// } else if(d1 > d2){
|
||||
// return 1;
|
||||
// }
|
||||
// return -1;
|
||||
// }
|
||||
//
|
||||
// });
|
||||
}
|
||||
getListView().setAdapter(favouritesAdapter);
|
||||
|
||||
}
|
||||
|
||||
public void onListItemClick(ListView parent, View v, int position, long id) {
|
||||
FavouritePoint point = favouritesAdapter.getItem(position);
|
||||
OsmandSettings.getOsmandSettings(this).SHOW_FAVORITES.set( true);
|
||||
OsmandSettings.getOsmandSettings(this).setMapLocationToShow(point.getLatitude(), point.getLongitude(), getString(R.string.favorite)+" : " + point.getName()); //$NON-NLS-1$
|
||||
MapActivity.launchMapActivityMoveToTop(FavouritesActivity.this);
|
||||
@Override
|
||||
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
|
||||
if(selectionMode){
|
||||
CheckBox ch = (CheckBox) v.findViewById(R.id.check_item);
|
||||
FavouritePoint model = favouritesAdapter.getChild(groupPosition, childPosition);
|
||||
ch.setChecked(!ch.isChecked());
|
||||
if(ch.isChecked()){
|
||||
favoritesToDelete.add(model);
|
||||
} else {
|
||||
favoritesToDelete.remove(model);
|
||||
}
|
||||
} else {
|
||||
FavouritePoint point = (FavouritePoint) favouritesAdapter.getChild(groupPosition, childPosition);
|
||||
OsmandSettings.getOsmandSettings(this).SHOW_FAVORITES.set( true);
|
||||
OsmandSettings.getOsmandSettings(this).setMapLocationToShow(point.getLatitude(), point.getLongitude(), getString(R.string.favorite)+" : " + point.getName()); //$NON-NLS-1$
|
||||
MapActivity.launchMapActivityMoveToTop(FavouritesActivity.this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem aItem) {
|
||||
AdapterContextMenuInfo menuInfo = (AdapterContextMenuInfo) aItem.getMenuInfo();
|
||||
final FavouritePoint point = (FavouritePoint) favouritesAdapter.getItem(menuInfo.position);
|
||||
ContextMenuInfo menuInfo = aItem.getMenuInfo();
|
||||
int child = ExpandableListView.getPackedPositionChild(((ExpandableListContextMenuInfo)menuInfo).packedPosition);
|
||||
int group = ExpandableListView.getPackedPositionGroup(((ExpandableListContextMenuInfo)menuInfo).packedPosition);
|
||||
final FavouritePoint point = (FavouritePoint) favouritesAdapter.getChild(group, child);
|
||||
if (aItem.getItemId() == SHOW_ON_MAP) {
|
||||
OsmandSettings.getOsmandSettings(this).SHOW_FAVORITES.set( true);
|
||||
OsmandSettings.getOsmandSettings(this).setMapLocationToShow(point.getLatitude(), point.getLongitude(), getString(R.string.favorite)+" : " + point.getName());
|
||||
|
@ -139,16 +251,21 @@ public class FavouritesActivity extends ListActivity {
|
|||
} else if (aItem.getItemId() == EDIT_ITEM) {
|
||||
Builder builder = new AlertDialog.Builder(this);
|
||||
builder.setTitle(R.string.favourites_edit_dialog_title);
|
||||
final EditText editText = new EditText(this);
|
||||
builder.setView(editText);
|
||||
final View v = getLayoutInflater().inflate(R.layout.favourite_edit_dialog, getExpandableListView(), false);
|
||||
final AutoCompleteTextView cat = (AutoCompleteTextView) v.findViewById(R.id.Category);
|
||||
final EditText editText = (EditText) v.findViewById(R.id.Name);
|
||||
builder.setView(v);
|
||||
editText.setText(point.getName());
|
||||
cat.setText(point.getCategory());
|
||||
cat.setThreshold(1);
|
||||
cat.setAdapter(new ArrayAdapter(this, R.layout.list_textview, helper.getFavoriteGroups().keySet().toArray()));
|
||||
builder.setNegativeButton(R.string.default_buttons_cancel, null);
|
||||
builder.setPositiveButton(R.string.default_buttons_apply, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
boolean editied = helper.editFavouriteName(point, editText.getText().toString(), point.getCategory());
|
||||
boolean editied = helper.editFavouriteName(point, editText.getText().toString(), cat.getText().toString());
|
||||
if (editied) {
|
||||
favouritesAdapter.notifyDataSetChanged();
|
||||
favouritesAdapter.synchronizeGroups();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -169,7 +286,7 @@ public class FavouritesActivity extends ListActivity {
|
|||
Toast.makeText(FavouritesActivity.this,
|
||||
MessageFormat.format(resources.getString(R.string.favourites_remove_dialog_success), point.getName()),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
favouritesAdapter.remove(point);
|
||||
favouritesAdapter.synchronizeGroups();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -187,81 +304,260 @@ public class FavouritesActivity extends ListActivity {
|
|||
item.setIcon(android.R.drawable.ic_menu_save);
|
||||
item = menu.add(0, IMPORT_ID, 0, R.string.import_fav);
|
||||
item.setIcon(android.R.drawable.ic_menu_upload);
|
||||
item = menu.add(0, DELETE_ID, 0, R.string.default_buttons_delete);
|
||||
item.setIcon(android.R.drawable.ic_menu_delete);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void showProgressBar(){
|
||||
findViewById(R.id.LoadingPanel).setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.ProgressBar).setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void hideProgressBar(){
|
||||
findViewById(R.id.LoadingPanel).setVisibility(View.GONE);
|
||||
findViewById(R.id.ProgressBar).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if(item.getItemId() == EXPORT_ID){
|
||||
File appDir = OsmandSettings.getOsmandSettings(this).extendOsmandPath(ResourceManager.APP_DIR);
|
||||
final File appDir = OsmandSettings.getOsmandSettings(this).extendOsmandPath(ResourceManager.APP_DIR);
|
||||
if(favouritesAdapter.isEmpty()){
|
||||
Toast.makeText(this, R.string.no_fav_to_save, Toast.LENGTH_LONG).show();
|
||||
} else if(!appDir.exists()){
|
||||
Toast.makeText(this, R.string.sd_dir_not_accessible, Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
File f = new File(appDir, FILE_TO_SAVE);
|
||||
GPXFile gpx = new GPXFile();
|
||||
for (int i = 0; i < favouritesAdapter.getCount(); i++) {
|
||||
FavouritePoint p = favouritesAdapter.getItem(i);
|
||||
WptPt pt = new WptPt();
|
||||
pt.lat = p.getLatitude();
|
||||
pt.lon = p.getLongitude();
|
||||
pt.name = p.getName();
|
||||
gpx.points.add(pt);
|
||||
}
|
||||
String warning = GPXUtilities.writeGpxFile(f, gpx, this);
|
||||
if(warning == null){
|
||||
Toast.makeText(this, MessageFormat.format(getString(R.string.fav_saved_sucessfully), f.getAbsolutePath()),
|
||||
Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(this, warning, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
final File f = new File(appDir, FILE_TO_SAVE);
|
||||
new AsyncTask<Void, Void, String>(){
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
GPXFile gpx = new GPXFile();
|
||||
|
||||
for (FavouritePoint p : helper.getFavouritePoints()) {
|
||||
if (p.isStored()) {
|
||||
WptPt pt = new WptPt();
|
||||
pt.lat = p.getLatitude();
|
||||
pt.lon = p.getLongitude();
|
||||
pt.name = p.getName() + "_" + p.getCategory();
|
||||
gpx.points.add(pt);
|
||||
}
|
||||
}
|
||||
return GPXUtilities.writeGpxFile(f, gpx, FavouritesActivity.this);
|
||||
}
|
||||
|
||||
protected void onPreExecute() {
|
||||
showProgressBar();
|
||||
};
|
||||
|
||||
protected void onPostExecute(String warning) {
|
||||
hideProgressBar();
|
||||
if(warning == null){
|
||||
Toast.makeText(FavouritesActivity.this, MessageFormat.format(getString(R.string.fav_saved_sucessfully), f.getAbsolutePath()),
|
||||
Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Toast.makeText(FavouritesActivity.this, warning, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
};
|
||||
|
||||
}.execute();
|
||||
}
|
||||
} else if(item.getItemId() == IMPORT_ID){
|
||||
File appDir = OsmandSettings.getOsmandSettings(this).extendOsmandPath(ResourceManager.APP_DIR);
|
||||
File f = new File(appDir, FILE_TO_SAVE);
|
||||
final File f = new File(appDir, FILE_TO_SAVE);
|
||||
if(!f.exists()){
|
||||
Toast.makeText(this, MessageFormat.format(getString(R.string.fav_file_to_load_not_found), f.getAbsolutePath()), Toast.LENGTH_LONG).show();
|
||||
} else {
|
||||
Set<String> existedPoints = new LinkedHashSet<String>();
|
||||
if(!favouritesAdapter.isEmpty()){
|
||||
for (int i = 0; i < favouritesAdapter.getCount(); i++) {
|
||||
FavouritePoint fp = favouritesAdapter.getItem(i);
|
||||
existedPoints.add(fp.getName());
|
||||
}
|
||||
}
|
||||
GPXFileResult res = GPXUtilities.loadGPXFile(this, f);
|
||||
if (res.error == null) {
|
||||
for(WptPt p : res.wayPoints){
|
||||
if(!existedPoints.contains(p.name)){
|
||||
FavouritePoint fp = new FavouritePoint(p.lat, p.lon, p.name);
|
||||
if(helper.addFavourite(fp)){
|
||||
favouritesAdapter.add(fp);
|
||||
new AsyncTask<Void, FavouritePoint, String>(){
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
Set<String> existedPoints = new LinkedHashSet<String>();
|
||||
if (!favouritesAdapter.isEmpty()) {
|
||||
for (FavouritePoint fp : helper.getFavouritePoints()) {
|
||||
existedPoints.add(fp.getName() + "_" + fp.getCategory());
|
||||
}
|
||||
}
|
||||
GPXFileResult res = GPXUtilities.loadGPXFile(FavouritesActivity.this, f);
|
||||
if(res.error != null){
|
||||
return res.error;
|
||||
}
|
||||
for(WptPt p : res.wayPoints){
|
||||
if(!existedPoints.contains(p.name)){
|
||||
String categoryName = FavouritesActivity.this.getString(R.string.favorite_default_category);
|
||||
int c;
|
||||
String name = p.name;
|
||||
if((c = p.name.lastIndexOf('_')) != -1){
|
||||
categoryName = p.name.substring(c + 1);
|
||||
name = p.name.substring(0, c);
|
||||
}
|
||||
FavouritePoint fp = new FavouritePoint(p.lat, p.lon, name, categoryName);
|
||||
if (helper.addFavourite(fp)) {
|
||||
publishProgress(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Toast.makeText(this, R.string.fav_imported_sucessfully, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(this, res.error, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
protected void onProgressUpdate(FavouritePoint... values) {
|
||||
for(FavouritePoint p : values){
|
||||
favouritesAdapter.addFavoritePoint(p);
|
||||
}
|
||||
};
|
||||
|
||||
protected void onPreExecute() {
|
||||
showProgressBar();
|
||||
};
|
||||
|
||||
protected void onPostExecute(String warning) {
|
||||
hideProgressBar();
|
||||
if(warning == null){
|
||||
Toast.makeText(FavouritesActivity.this, R.string.fav_imported_sucessfully, Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Toast.makeText(FavouritesActivity.this, warning, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
favouritesAdapter.synchronizeGroups();
|
||||
};
|
||||
|
||||
}.execute();
|
||||
}
|
||||
} else if(item.getItemId() == DELETE_ID){
|
||||
selectionMode = true;
|
||||
findViewById(R.id.ActionButton).setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.CancelButton).setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.LoadingPanel).setVisibility(View.VISIBLE);
|
||||
favoritesToDelete.clear();
|
||||
groupsToDelete.clear();
|
||||
favouritesAdapter.notifyDataSetInvalidated();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class FavouritesAdapter extends BaseExpandableListAdapter {
|
||||
|
||||
class FavouritesAdapter extends ArrayAdapter<FavouritePoint> {
|
||||
FavouritesAdapter(List<FavouritePoint> list) {
|
||||
super(FavouritesActivity.this, R.layout.favourites_list_item, list);
|
||||
Map<String, List<FavouritePoint>> sourceFavoriteGroups;
|
||||
Map<String, List<FavouritePoint>> favoriteGroups = new LinkedHashMap<String, List<FavouritePoint>>();
|
||||
List<String> groups = new ArrayList<String>();
|
||||
|
||||
public void setFavoriteGroups(Map<String, List<FavouritePoint>> favoriteGroups) {
|
||||
this.sourceFavoriteGroups = favoriteGroups;
|
||||
synchronizeGroups();
|
||||
}
|
||||
|
||||
public void addFavoritePoint(FavouritePoint p) {
|
||||
if(!favoriteGroups.containsKey(p.getCategory())){
|
||||
favoriteGroups.put(p.getCategory(), new ArrayList<FavouritePoint>());
|
||||
groups.add(p.getCategory());
|
||||
}
|
||||
favoriteGroups.get(p.getCategory()).add(p);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void deleteFavoritePoint(FavouritePoint p) {
|
||||
if(favoriteGroups.containsKey(p.getCategory())){
|
||||
favoriteGroups.get(p.getCategory()).remove(p);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void deleteCategory(String p) {
|
||||
favoriteGroups.remove(p);
|
||||
groups.remove(p);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void synchronizeGroups(){
|
||||
favoriteGroups.clear();
|
||||
groups.clear();
|
||||
for(String key : sourceFavoriteGroups.keySet()){
|
||||
groups.add(key);
|
||||
favoriteGroups.put(key, new ArrayList<FavouritePoint>(sourceFavoriteGroups.get(key)));
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FavouritePoint getChild(int groupPosition, int childPosition) {
|
||||
return favoriteGroups.get(groups.get(groupPosition)).get(childPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getChildId(int groupPosition, int childPosition) {
|
||||
return groupPosition * 10000 + childPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChildrenCount(int groupPosition) {
|
||||
return favoriteGroups.get(groups.get(groupPosition)).size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGroup(int groupPosition) {
|
||||
return groups.get(groupPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getGroupCount() {
|
||||
return groups.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getGroupId(int groupPosition) {
|
||||
return groupPosition;
|
||||
}
|
||||
|
||||
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
@Override
|
||||
public boolean hasStableIds() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChildSelectable(int groupPosition, int childPosition) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
|
||||
View row = convertView;
|
||||
if (row == null) {
|
||||
LayoutInflater inflater = getLayoutInflater();
|
||||
row = inflater.inflate(R.layout.favourites_list_category, parent, false);
|
||||
}
|
||||
TextView label = (TextView) row.findViewById(R.id.category_name);
|
||||
final String model = getGroup(groupPosition);
|
||||
List<FavouritePoint> ms = helper.getFavoriteGroups().get(model);
|
||||
int sz = ms != null ? ms.size() : 0;
|
||||
label.setText(model + " [" + sz +"]");
|
||||
final CheckBox ch = (CheckBox) row.findViewById(R.id.check_item);
|
||||
|
||||
if(selectionMode){
|
||||
ch.setVisibility(View.VISIBLE);
|
||||
ch.setChecked(groupsToDelete.contains(model));
|
||||
|
||||
ch.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(ch.isChecked()){
|
||||
groupsToDelete.add(model);
|
||||
favoritesToDelete.addAll(helper.getFavoriteGroups().get(model));
|
||||
favouritesAdapter.notifyDataSetInvalidated();
|
||||
} else {
|
||||
groupsToDelete.remove(model);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ch.setVisibility(View.GONE);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
|
||||
View row = convertView;
|
||||
if (row == null) {
|
||||
LayoutInflater inflater = getLayoutInflater();
|
||||
|
@ -271,7 +567,7 @@ public class FavouritesActivity extends ListActivity {
|
|||
TextView label = (TextView) row.findViewById(R.id.favourite_label);
|
||||
TextView distanceLabel = (TextView) row.findViewById(R.id.favouritedistance_label);
|
||||
ImageView icon = (ImageView) row.findViewById(R.id.favourite_icon);
|
||||
FavouritePoint model = (FavouritePoint) getItem(position);
|
||||
final FavouritePoint model = (FavouritePoint) getChild(groupPosition, childPosition);
|
||||
row.setTag(model);
|
||||
if(model.isStored()){
|
||||
icon.setImageResource(R.drawable.favorites);
|
||||
|
@ -283,6 +579,30 @@ public class FavouritesActivity extends ListActivity {
|
|||
lastKnownMapLocation.getLatitude(), lastKnownMapLocation.getLongitude()));
|
||||
distanceLabel.setText(OsmAndFormatter.getFormattedDistance(dist, FavouritesActivity.this));
|
||||
label.setText(model.getName());
|
||||
final CheckBox ch = (CheckBox) row.findViewById(R.id.check_item);
|
||||
if(selectionMode && model.isStored()){
|
||||
ch.setVisibility(View.VISIBLE);
|
||||
ch.setChecked(favoritesToDelete.contains(model));
|
||||
row.findViewById(R.id.favourite_icon).setVisibility(View.GONE);
|
||||
ch.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(ch.isChecked()){
|
||||
favoritesToDelete.add(model);
|
||||
} else {
|
||||
favoritesToDelete.remove(model);
|
||||
if(groupsToDelete.contains(model.getCategory())){
|
||||
groupsToDelete.remove(model.getCategory());
|
||||
favouritesAdapter.notifyDataSetInvalidated();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
row.findViewById(R.id.favourite_icon).setVisibility(View.VISIBLE);
|
||||
ch.setVisibility(View.GONE);
|
||||
}
|
||||
return row;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -327,7 +327,7 @@ public class MainMenuActivity extends Activity {
|
|||
builder.setNeutralButton(R.string.vector_map_not_needed, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
getPreferences(MODE_WORLD_WRITEABLE).edit().putBoolean(VECTOR_INDEXES_CHECK, false);
|
||||
getPreferences(MODE_WORLD_WRITEABLE).edit().putBoolean(VECTOR_INDEXES_CHECK, false).commit();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(R.string.first_time_continue, null);
|
||||
|
|
|
@ -32,6 +32,9 @@ import android.text.ClipboardManager;
|
|||
import android.text.Html;
|
||||
import android.util.FloatMath;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
|
@ -43,21 +46,29 @@ public class MapActivityActions {
|
|||
this.mapActivity = mapActivity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void addFavouritePoint(final double latitude, final double longitude){
|
||||
final Resources resources = mapActivity.getResources();
|
||||
final FavouritePoint p = new FavouritePoint(latitude, longitude, resources.getString(R.string.add_favorite_dialog_default_favourite_name));
|
||||
|
||||
final FavouritePoint point = new FavouritePoint(latitude, longitude, resources.getString(R.string.add_favorite_dialog_default_favourite_name),
|
||||
resources.getString(R.string.favorite_default_category));
|
||||
Builder builder = new AlertDialog.Builder(mapActivity);
|
||||
builder.setTitle(R.string.add_favorite_dialog_top_text);
|
||||
final EditText editText = new EditText(mapActivity);
|
||||
builder.setView(editText);
|
||||
builder.setTitle(R.string.favourites_edit_dialog_title);
|
||||
final View v = mapActivity.getLayoutInflater().inflate(R.layout.favourite_edit_dialog, null, false);
|
||||
final FavouritesDbHelper helper = ((OsmandApplication)mapActivity.getApplication()).getFavorites();
|
||||
builder.setView(v);
|
||||
final EditText editText = (EditText) v.findViewById(R.id.Name);
|
||||
editText.setText(point.getName());
|
||||
final AutoCompleteTextView cat = (AutoCompleteTextView) v.findViewById(R.id.Category);
|
||||
cat.setText(point.getCategory());
|
||||
cat.setAdapter(new ArrayAdapter(mapActivity, R.layout.list_textview, helper.getFavoriteGroups().keySet().toArray()));
|
||||
|
||||
builder.setNegativeButton(R.string.default_buttons_cancel, null);
|
||||
builder.setNeutralButton(R.string.update_existing, new DialogInterface.OnClickListener(){
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Builder b = new AlertDialog.Builder(mapActivity);
|
||||
final FavouritesDbHelper helper = ((OsmandApplication)mapActivity.getApplication()).getFavorites();
|
||||
|
||||
final Collection<FavouritePoint> points = helper.getFavouritePoints();
|
||||
final String[] names = new String[points.size()];
|
||||
final FavouritePoint[] favs = new FavouritePoint[points.size()];
|
||||
|
@ -95,10 +106,11 @@ public class MapActivityActions {
|
|||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
final FavouritesDbHelper helper = ((OsmandApplication)mapActivity.getApplication()).getFavorites();
|
||||
p.setName(editText.getText().toString());
|
||||
boolean added = helper.addFavourite(p);
|
||||
point.setName(editText.getText().toString());
|
||||
point.setCategory(cat.getText().toString());
|
||||
boolean added = helper.addFavourite(point);
|
||||
if (added) {
|
||||
Toast.makeText(mapActivity, MessageFormat.format(getString(R.string.add_favorite_dialog_favourite_added_template), p.getName()), Toast.LENGTH_SHORT)
|
||||
Toast.makeText(mapActivity, MessageFormat.format(getString(R.string.add_favorite_dialog_favourite_added_template), point.getName()), Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
mapActivity.getMapView().refreshMap();
|
||||
|
|
Loading…
Reference in a new issue