New address search in progress
This commit is contained in:
parent
82a682dd58
commit
a491e854ae
14 changed files with 532 additions and 150 deletions
|
@ -7,7 +7,6 @@ import net.osmand.ResultMatcher;
|
|||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.Amenity;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.osm.AbstractPoiType;
|
||||
import net.osmand.osm.MapPoiTypes;
|
||||
import net.osmand.search.core.CustomSearchPoiFilter;
|
||||
import net.osmand.search.core.ObjectType;
|
||||
|
@ -30,7 +29,6 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
@ -44,7 +42,7 @@ public class SearchUICore {
|
|||
private static final int TIMEOUT_BETWEEN_CHARS = 200;
|
||||
private static final Log LOG = PlatformUtil.getLog(SearchUICore.class);
|
||||
private SearchPhrase phrase;
|
||||
private SearchResultCollection currentSearchResult;
|
||||
private SearchResultCollection currentSearchResult;
|
||||
|
||||
private ThreadPoolExecutor singleThreadedExecutor;
|
||||
private LinkedBlockingQueue<Runnable> taskQueue;
|
||||
|
@ -56,8 +54,11 @@ public class SearchUICore {
|
|||
List<SearchCoreAPI> apis = new ArrayList<>();
|
||||
private SearchSettings searchSettings;
|
||||
private MapPoiTypes poiTypes;
|
||||
|
||||
|
||||
|
||||
private SearchCoreFactory.SearchCityByNameAPI searchCityByNameAPI;
|
||||
private SearchCoreFactory.SearchPostcodeAPI searchPostcodeAPI;
|
||||
private Class<? extends SearchCoreAPI> searchApiClass;
|
||||
|
||||
public SearchUICore(MapPoiTypes poiTypes, String locale, boolean transliterate) {
|
||||
this.poiTypes = poiTypes;
|
||||
taskQueue = new LinkedBlockingQueue<Runnable>();
|
||||
|
@ -67,7 +68,19 @@ public class SearchUICore {
|
|||
currentSearchResult = new SearchResultCollection(phrase);
|
||||
singleThreadedExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, taskQueue);
|
||||
}
|
||||
|
||||
|
||||
public Class<? extends SearchCoreAPI> getSearchApiClass() {
|
||||
return searchApiClass;
|
||||
}
|
||||
|
||||
public void setSearchApiClass(Class<? extends SearchCoreAPI> searchApiClass) {
|
||||
this.searchApiClass = searchApiClass;
|
||||
}
|
||||
|
||||
public boolean isInCustomSearch() {
|
||||
return searchApiClass != null;
|
||||
}
|
||||
|
||||
public static class SearchResultCollection {
|
||||
private List<SearchResult> searchResults;
|
||||
private SearchPhrase phrase;
|
||||
|
@ -242,11 +255,16 @@ public class SearchUICore {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getApiByClass(Class<T> cl) {
|
||||
for(SearchCoreAPI a : apis) {
|
||||
for (SearchCoreAPI a : apis) {
|
||||
if(cl.isInstance(a)) {
|
||||
return (T) a;
|
||||
}
|
||||
}
|
||||
if (cl.isInstance(searchCityByNameAPI)) {
|
||||
return (T) searchCityByNameAPI;
|
||||
} else if (cl.isInstance(searchPostcodeAPI)) {
|
||||
return (T) searchPostcodeAPI;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -279,7 +297,11 @@ public class SearchUICore {
|
|||
apis.add(streetsApi);
|
||||
SearchStreetByCityAPI cityApi = new SearchCoreFactory.SearchStreetByCityAPI(streetsApi);
|
||||
apis.add(cityApi);
|
||||
apis.add(new SearchCoreFactory.SearchAddressByNameAPI(streetsApi, cityApi));
|
||||
SearchCoreFactory.SearchAddressByNameAPI searchAddressByNameAPI
|
||||
= new SearchCoreFactory.SearchAddressByNameAPI(streetsApi, cityApi);
|
||||
apis.add(searchAddressByNameAPI);
|
||||
searchCityByNameAPI = new SearchCoreFactory.SearchCityByNameAPI(searchAddressByNameAPI);
|
||||
searchPostcodeAPI = new SearchCoreFactory.SearchPostcodeAPI();
|
||||
}
|
||||
|
||||
public void clearCustomSearchPoiFilters() {
|
||||
|
@ -414,7 +436,12 @@ public class SearchUICore {
|
|||
|
||||
private void searchInBackground(final SearchPhrase phrase, SearchResultMatcher matcher) {
|
||||
preparePhrase(phrase);
|
||||
ArrayList<SearchCoreAPI> lst = new ArrayList<>(apis);
|
||||
ArrayList<SearchCoreAPI> lst = new ArrayList<>();
|
||||
if (searchApiClass != null) {
|
||||
lst.add(getApiByClass(searchApiClass));
|
||||
} else {
|
||||
lst.addAll(apis);
|
||||
}
|
||||
Collections.sort(lst, new Comparator<SearchCoreAPI>() {
|
||||
|
||||
@Override
|
||||
|
@ -423,11 +450,11 @@ public class SearchUICore {
|
|||
o2.getSearchPriority(phrase));
|
||||
}
|
||||
});
|
||||
for(SearchCoreAPI api : lst) {
|
||||
if(matcher.isCancelled()) {
|
||||
for (SearchCoreAPI api : lst) {
|
||||
if (matcher.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
if(api.getSearchPriority(phrase) == -1) {
|
||||
if (api.getSearchPriority(phrase) == -1) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
|
|
|
@ -16,6 +16,7 @@ import net.osmand.data.City;
|
|||
import net.osmand.data.City.CityType;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.MapObject;
|
||||
import net.osmand.data.Postcode;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.data.QuadTree;
|
||||
import net.osmand.data.Street;
|
||||
|
@ -43,7 +44,6 @@ import java.util.LinkedHashSet;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
|
||||
|
@ -167,10 +167,116 @@ public class SearchCoreFactory {
|
|||
}
|
||||
return retName;
|
||||
}
|
||||
|
||||
|
||||
public static class SearchPostcodeAPI extends SearchBaseAPI {
|
||||
|
||||
@Override
|
||||
public boolean search(final SearchPhrase phrase, final SearchResultMatcher resultMatcher) throws IOException {
|
||||
if (!phrase.isUnknownSearchWordPresent()) {
|
||||
return false;
|
||||
}
|
||||
if (phrase.isNoSelectedType()) {
|
||||
final NameStringMatcher nm = phrase.getNameStringMatcher();
|
||||
final QuadRect bbox = phrase.getRadiusBBoxToSearch(SearchAddressByNameAPI.DEFAULT_ADDRESS_BBOX_RADIUS * 20);
|
||||
final QuadRect postcodeBbox = phrase.getRadiusBBoxToSearch(SearchAddressByNameAPI.DEFAULT_ADDRESS_BBOX_RADIUS * 5);
|
||||
Iterator<BinaryMapIndexReader> offlineIndexes = phrase.getOfflineIndexes(bbox, SearchPhraseDataType.ADDRESS);
|
||||
while (offlineIndexes.hasNext()) {
|
||||
BinaryMapIndexReader r = offlineIndexes.next();
|
||||
SearchRequest<City> req = BinaryMapIndexReader.buildAddressRequest(new ResultMatcher<City>() {
|
||||
@Override
|
||||
public boolean publish(City object) {
|
||||
return object.isPostcode() && nm.matches(object.getPostcode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return resultMatcher.isCancelled();
|
||||
}
|
||||
});
|
||||
List<City> l = r.getCities(req, BinaryMapAddressReaderAdapter.POSTCODES_TYPE);
|
||||
for (City c : l) {
|
||||
LatLon cl = c.getLocation();
|
||||
int y = MapUtils.get31TileNumberY(cl.getLatitude());
|
||||
int x = MapUtils.get31TileNumberX(cl.getLongitude());
|
||||
if (postcodeBbox.contains(x, y, x, y)) {
|
||||
SearchResult res = new SearchResult(phrase);
|
||||
res.object = c;
|
||||
res.file = (BinaryMapIndexReader) c.getReferenceFile();
|
||||
res.localeName = c.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
||||
res.otherNames = c.getAllNames(true);
|
||||
res.localeRelatedObjectName = res.file.getRegionName();
|
||||
res.relatedObject = res.file;
|
||||
res.location = c.getLocation();
|
||||
res.priority = SEARCH_ADDRESS_BY_NAME_PRIORITY;
|
||||
res.priorityDistance = 0.1;
|
||||
res.objectType = ObjectType.POSTCODE;
|
||||
resultMatcher.publish(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class SearchCityByNameAPI extends SearchBaseAPI {
|
||||
|
||||
private SearchAddressByNameAPI searchAddressByNameAPI;
|
||||
private static final int LIMIT = 10000;
|
||||
|
||||
public SearchCityByNameAPI(SearchAddressByNameAPI searchAddressByNameAPI) {
|
||||
this.searchAddressByNameAPI = searchAddressByNameAPI;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean search(final SearchPhrase phrase, final SearchResultMatcher resultMatcher) throws IOException {
|
||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(SearchAddressByNameAPI.DEFAULT_ADDRESS_BBOX_RADIUS * 20);
|
||||
QuadRect closestBBox = phrase.getRadiusBBoxToSearch(SearchAddressByNameAPI.DEFAULT_ADDRESS_BBOX_RADIUS * 3);
|
||||
if (phrase.isNoSelectedType()) {
|
||||
searchAddressByNameAPI.initCities(phrase, bbox);
|
||||
}
|
||||
NameStringMatcher nm = null;
|
||||
List<City> cities;
|
||||
if (phrase.isUnknownSearchWordPresent()) {
|
||||
nm = phrase.getNameStringMatcher();
|
||||
cities = searchAddressByNameAPI.townCitiesQR.queryInBox(bbox, new ArrayList<City>());
|
||||
} else {
|
||||
cities = searchAddressByNameAPI.townCitiesQR.queryInBox(closestBBox, new ArrayList<City>());
|
||||
}
|
||||
int limit = 0;
|
||||
for (City c : cities) {
|
||||
SearchResult res = new SearchResult(phrase);
|
||||
res.object = c;
|
||||
res.file = (BinaryMapIndexReader) c.getReferenceFile();
|
||||
res.localeName = c.getName(phrase.getSettings().getLang(), phrase.getSettings().isTransliterate());
|
||||
res.otherNames = c.getAllNames(true);
|
||||
res.localeRelatedObjectName = res.file.getRegionName();
|
||||
res.relatedObject = res.file;
|
||||
res.location = c.getLocation();
|
||||
res.priority = SEARCH_ADDRESS_BY_NAME_PRIORITY;
|
||||
res.priorityDistance = 0.1;
|
||||
res.objectType = ObjectType.CITY;
|
||||
if (nm == null) {
|
||||
resultMatcher.publish(res);
|
||||
} else if (nm.matches(res.localeName) || nm.matches(res.otherNames)) {
|
||||
resultMatcher.publish(res);
|
||||
}
|
||||
if (limit++ > LIMIT * phrase.getRadiusLevel()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSearchPriority(SearchPhrase p) {
|
||||
return searchAddressByNameAPI.getSearchPriority(p);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SearchAddressByNameAPI extends SearchBaseAPI {
|
||||
|
||||
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100*1000;
|
||||
private static final int DEFAULT_ADDRESS_BBOX_RADIUS = 100 * 1000;
|
||||
private static final int LIMIT = 10000;
|
||||
|
||||
|
||||
|
@ -222,17 +328,15 @@ public class SearchCoreFactory {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
private void initAndSearchCities(final SearchPhrase phrase, final SearchResultMatcher resultMatcher) throws IOException {
|
||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(DEFAULT_ADDRESS_BBOX_RADIUS * 20);
|
||||
protected void initCities(final SearchPhrase phrase, QuadRect bbox) throws IOException {
|
||||
Iterator<BinaryMapIndexReader> offlineIndexes = phrase.getOfflineIndexes(bbox, SearchPhraseDataType.ADDRESS);
|
||||
while(offlineIndexes.hasNext()) {
|
||||
while (offlineIndexes.hasNext()) {
|
||||
BinaryMapIndexReader r = offlineIndexes.next();
|
||||
if(!townCities.containsKey(r)) {
|
||||
if (!townCities.containsKey(r)) {
|
||||
BinaryMapIndexReader.buildAddressRequest(null);
|
||||
List<City> l = r.getCities(null, BinaryMapAddressReaderAdapter.CITY_TOWN_TYPE);
|
||||
townCities.put(r, l);
|
||||
for(City c : l) {
|
||||
for (City c : l) {
|
||||
LatLon cl = c.getLocation();
|
||||
c.setReferenceFile(r);
|
||||
int y = MapUtils.get31TileNumberY(cl.getLatitude());
|
||||
|
@ -242,6 +346,12 @@ public class SearchCoreFactory {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void initAndSearchCities(final SearchPhrase phrase, final SearchResultMatcher resultMatcher) throws IOException {
|
||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(DEFAULT_ADDRESS_BBOX_RADIUS * 20);
|
||||
initCities(phrase, bbox);
|
||||
|
||||
if (phrase.isNoSelectedType() && bbox != null && phrase.isUnknownSearchWordPresent()) {
|
||||
NameStringMatcher nm = phrase.getNameStringMatcher();
|
||||
resArray.clear();
|
||||
|
@ -259,20 +369,19 @@ public class SearchCoreFactory {
|
|||
res.priority = SEARCH_ADDRESS_BY_NAME_PRIORITY;
|
||||
res.priorityDistance = 0.1;
|
||||
res.objectType = ObjectType.CITY;
|
||||
if(nm.matches(res.localeName) || nm.matches(res.otherNames)) {
|
||||
if (nm.matches(res.localeName) || nm.matches(res.otherNames)) {
|
||||
subSearchApiOrPublish(phrase, resultMatcher, res, cityApi);
|
||||
}
|
||||
if(limit++ > LIMIT * phrase.getRadiusLevel()) {
|
||||
if (limit++ > LIMIT * phrase.getRadiusLevel()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void searchByName(final SearchPhrase phrase, final SearchResultMatcher resultMatcher)
|
||||
throws IOException {
|
||||
if(phrase.getRadiusLevel() > 1 || phrase.getUnknownSearchWordLength() > 3 || phrase.getUnknownSearchWords().size() > 0) {
|
||||
if (phrase.getRadiusLevel() > 1 || phrase.getUnknownSearchWordLength() > 3 || phrase.getUnknownSearchWords().size() > 0) {
|
||||
final boolean locSpecified = phrase.getLastTokenLocation() != null;
|
||||
LatLon loc = phrase.getLastTokenLocation();
|
||||
final List<SearchResult> immediateResults = new ArrayList<>();
|
||||
|
@ -287,7 +396,7 @@ public class SearchCoreFactory {
|
|||
int limit = 0;
|
||||
@Override
|
||||
public boolean publish(MapObject object) {
|
||||
if(isCancelled()) {
|
||||
if (isCancelled()) {
|
||||
return false;
|
||||
}
|
||||
SearchResult sr = new SearchResult(phrase);
|
||||
|
@ -339,7 +448,7 @@ public class SearchCoreFactory {
|
|||
return false;
|
||||
}
|
||||
City c = null;
|
||||
if(closestCities == null) {
|
||||
if (closestCities == null) {
|
||||
closestCities = townCitiesQR.queryInBox(villagesBbox, new ArrayList<City>());
|
||||
}
|
||||
double minDist = -1;
|
||||
|
@ -417,7 +526,7 @@ public class SearchCoreFactory {
|
|||
|
||||
@Override
|
||||
public boolean search(final SearchPhrase phrase, final SearchResultMatcher resultMatcher) throws IOException {
|
||||
if(!phrase.isUnknownSearchWordPresent()) {
|
||||
if (!phrase.isUnknownSearchWordPresent()) {
|
||||
return false;
|
||||
}
|
||||
final BinaryMapIndexReader[] currentFile = new BinaryMapIndexReader[1];
|
||||
|
@ -426,10 +535,10 @@ public class SearchCoreFactory {
|
|||
final NameStringMatcher nm = phrase.getNameStringMatcher();
|
||||
QuadRect bbox = phrase.getRadiusBBoxToSearch(BBOX_RADIUS_INSIDE);
|
||||
SearchRequest<Amenity> req = BinaryMapIndexReader.buildSearchPoiRequest(
|
||||
(int)bbox.centerX(), (int)bbox.centerY(),
|
||||
(int) bbox.centerX(), (int) bbox.centerY(),
|
||||
phrase.getUnknownSearchWord(),
|
||||
(int)bbox.left, (int)bbox.right,
|
||||
(int)bbox.top, (int)bbox.bottom,
|
||||
(int) bbox.left, (int) bbox.right,
|
||||
(int) bbox.top, (int) bbox.bottom,
|
||||
new ResultMatcher<Amenity>() {
|
||||
int limit = 0;
|
||||
@Override
|
||||
|
@ -759,9 +868,7 @@ public class SearchCoreFactory {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public static class SearchStreetByCityAPI extends SearchBaseAPI {
|
||||
|
||||
private SearchBaseAPI streetsAPI;
|
||||
|
@ -955,10 +1062,10 @@ public class SearchCoreFactory {
|
|||
|
||||
@Override
|
||||
public int getSearchPriority(SearchPhrase p) {
|
||||
if(isLastWordCityGroup(p)) {
|
||||
if (isLastWordCityGroup(p)) {
|
||||
return SEARCH_BUILDING_BY_CITY_PRIORITY;
|
||||
}
|
||||
if(!p.isLastWord(ObjectType.STREET)) {
|
||||
if (!p.isLastWord(ObjectType.STREET)) {
|
||||
return -1;
|
||||
}
|
||||
return SEARCH_BUILDING_BY_STREET_PRIORITY;
|
||||
|
|
|
@ -3,32 +3,45 @@
|
|||
xmlns:osmand="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="60dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp">
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.AppCompatImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="16dp"
|
||||
android:scaleType="centerInside"
|
||||
android:tint="?attr/color_dialog_buttons"
|
||||
android:src="@drawable/ic_action_search_dark"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?attr/color_dialog_buttons"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
osmand:textAllCapsCompat="true"
|
||||
osmand:typeface="@string/font_roboto_medium"
|
||||
android:text="@string/custom_search"/>
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingBottom="8dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:minHeight="60dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="24dp"
|
||||
android:layout_height="24dp"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginRight="16dp"
|
||||
android:scaleType="centerInside"
|
||||
android:src="@drawable/ic_action_search_dark"/>
|
||||
|
||||
<net.osmand.plus.widgets.TextViewEx
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?attr/color_dialog_buttons"
|
||||
android:textSize="@dimen/default_sub_text_size"
|
||||
osmand:textAllCapsCompat="true"
|
||||
osmand:typeface="@string/font_roboto_medium"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginLeft="56dp"
|
||||
android:background="?attr/dashboard_divider"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</LinearLayout>
|
50
OsmAnd/res/layout/search_header_list_item.xml
Normal file
50
OsmAnd/res/layout/search_header_list_item.xml
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/top_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/ctx_menu_info_view_bg"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<include layout="@layout/card_bottom_divider"/>
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"/>
|
||||
|
||||
<include layout="@layout/card_top_divider"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:minHeight="48dp"
|
||||
android:paddingLeft="56dp"
|
||||
android:paddingRight="16dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:textSize="@dimen/default_desc_text_size"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginLeft="56dp"
|
||||
android:background="?attr/dashboard_divider"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -9,6 +9,11 @@
|
|||
3. All your modified/created strings are in the top of the file (to make easier find what\'s translated).
|
||||
PLEASE: Have a look at http://code.google.com/p/osmand/wiki/UIConsistency, it may really improve your and our work :-) Thx - Hardy
|
||||
-->
|
||||
<string name="type_city_town">Type city or town</string>
|
||||
<string name="type_postcode">Type postcode</string>
|
||||
<string name="nearest_cities">Nearest cities</string>
|
||||
<string name="select_city">Select city</string>
|
||||
<string name="select_postcode">Select postcode</string>
|
||||
<string name="quick_action_auto_zoom">Auto zoom map on/off</string>
|
||||
<string name="quick_action_auto_zoom_desc">Tapping the action button will turn on/off auto zoom map according to your speed.</string>
|
||||
<string name="quick_action_auto_zoom_on">Auto zoom map on</string>
|
||||
|
|
|
@ -5,7 +5,6 @@ import android.app.Dialog;
|
|||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
|
@ -65,6 +64,10 @@ import net.osmand.plus.helpers.SearchHistoryHelper;
|
|||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.poi.PoiUIFilter;
|
||||
import net.osmand.plus.search.QuickSearchHelper.SearchHistoryAPI;
|
||||
import net.osmand.plus.search.listitems.QuickSearchButtonListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchHeaderListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchMoreListItem;
|
||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarController;
|
||||
import net.osmand.plus.views.mapwidgets.MapInfoWidgetsFactory.TopToolbarControllerType;
|
||||
import net.osmand.search.SearchUICore;
|
||||
|
@ -72,6 +75,8 @@ import net.osmand.search.SearchUICore.SearchResultCollection;
|
|||
import net.osmand.search.core.ObjectType;
|
||||
import net.osmand.search.core.SearchCoreAPI;
|
||||
import net.osmand.search.core.SearchCoreFactory.SearchAmenityTypesAPI;
|
||||
import net.osmand.search.core.SearchCoreFactory.SearchCityByNameAPI;
|
||||
import net.osmand.search.core.SearchCoreFactory.SearchPostcodeAPI;
|
||||
import net.osmand.search.core.SearchPhrase;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.search.core.SearchSettings;
|
||||
|
@ -118,6 +123,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
private QuickSearchMainListFragment mainSearchFragment;
|
||||
private QuickSearchHistoryListFragment historySearchFragment;
|
||||
private QuickSearchCategoriesListFragment categoriesSearchFragment;
|
||||
private QuickSearchAddressListFragment addrSearchFragment;
|
||||
private QuickSearchToolbarController toolbarController;
|
||||
|
||||
private Toolbar toolbarEdit;
|
||||
|
@ -406,6 +412,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
);
|
||||
|
||||
viewPager = (LockableViewPager) view.findViewById(R.id.pager);
|
||||
viewPager.setOffscreenPageLimit(2);
|
||||
pagerAdapter = new SearchFragmentPagerAdapter(getChildFragmentManager(), getResources());
|
||||
viewPager.setAdapter(pagerAdapter);
|
||||
if (centerLatLon != null || showCategories) {
|
||||
|
@ -484,6 +491,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
String newText = searchUICore.getPhrase().getTextWithoutLastWord();
|
||||
searchEditText.setText(newText);
|
||||
searchEditText.setSelection(newText.length());
|
||||
searchUICore.setSearchApiClass(null);
|
||||
} else if (useMapCenter && location != null) {
|
||||
useMapCenter = false;
|
||||
centerLatLon = null;
|
||||
|
@ -702,6 +710,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
boolean transliterate = app.getSettings().MAP_TRANSLITERATE_NAMES.get();
|
||||
searchHelper = app.getSearchUICore();
|
||||
searchUICore = searchHelper.getCore();
|
||||
searchUICore.setSearchApiClass(null);
|
||||
|
||||
location = app.getLocationProvider().getLastKnownLocation();
|
||||
|
||||
|
@ -873,7 +882,7 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
searchView.setVisibility(View.GONE);
|
||||
} else if (!show && tabsView.getVisibility() == View.VISIBLE) {
|
||||
tabToolbarView.setVisibility(View.GONE);
|
||||
buttonToolbarView.setVisibility(View.VISIBLE);
|
||||
buttonToolbarView.setVisibility(searchUICore.isInCustomSearch() ? View.GONE : View.VISIBLE);
|
||||
tabsView.setVisibility(View.GONE);
|
||||
searchView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
@ -899,6 +908,11 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
reloadCategories();
|
||||
break;
|
||||
|
||||
case ADDRESS:
|
||||
addrSearchFragment = (QuickSearchAddressListFragment) searchListFragment;
|
||||
reloadCities();
|
||||
break;
|
||||
|
||||
case MAIN:
|
||||
if (!Algorithms.isEmpty(searchQuery)) {
|
||||
searchEditText.setText(searchQuery);
|
||||
|
@ -951,7 +965,8 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
for (SearchResult sr : res.getCurrentSearchResults()) {
|
||||
rows.add(new QuickSearchListItem(app, sr));
|
||||
}
|
||||
rows.add(new CustomSearchButton(app, new OnClickListener() {
|
||||
rows.add(new QuickSearchButtonListItem(app, R.drawable.ic_action_search_dark,
|
||||
app.getString(R.string.custom_search), new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
PoiUIFilter filter = app.getPoiFilters().getCustomPOIFilter();
|
||||
|
@ -966,7 +981,74 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
e.printStackTrace();
|
||||
app.showToastMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadCities() {
|
||||
if (app.isApplicationInitializing()) {
|
||||
showProgressBar();
|
||||
app.getAppInitializer().addListener(new AppInitializeListener() {
|
||||
@Override
|
||||
public void onProgress(AppInitializer init, AppInitializer.InitEvents event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish(AppInitializer init) {
|
||||
if (!paused) {
|
||||
reloadCitiesInternal();
|
||||
if (!searching) {
|
||||
hideProgressBar();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reloadCitiesInternal();
|
||||
}
|
||||
}
|
||||
|
||||
private void reloadCitiesInternal() {
|
||||
try {
|
||||
SearchResultCollection res = searchUICore.shallowSearch(SearchCityByNameAPI.class,
|
||||
"", null);
|
||||
List<QuickSearchListItem> rows = new ArrayList<>();
|
||||
rows.add(new QuickSearchButtonListItem(app, R.drawable.ic_action_building_number,
|
||||
app.getString(R.string.select_city), new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
searchEditText.setHint(R.string.type_city_town);
|
||||
searchUICore.setSearchApiClass(SearchCityByNameAPI.class);
|
||||
updateTabbarVisibility(false);
|
||||
runSearch();
|
||||
}
|
||||
}));
|
||||
rows.add(new QuickSearchButtonListItem(app, R.drawable.ic_action_postcode,
|
||||
app.getString(R.string.select_postcode), new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
searchEditText.setHint(R.string.type_postcode);
|
||||
searchUICore.setSearchApiClass(SearchPostcodeAPI.class);
|
||||
mainSearchFragment.getAdapter().clear();
|
||||
updateTabbarVisibility(false);
|
||||
searchEditText.requestFocus();
|
||||
AndroidUtils.softKeyboardDelayed(searchEditText);
|
||||
}
|
||||
}));
|
||||
|
||||
if (res != null) {
|
||||
rows.add(new QuickSearchHeaderListItem(app, app.getString(R.string.nearest_cities), true));
|
||||
int limit = 15;
|
||||
for (SearchResult sr : res.getCurrentSearchResults()) {
|
||||
if (limit > 0) {
|
||||
rows.add(new QuickSearchListItem(app, sr));
|
||||
}
|
||||
limit--;
|
||||
}
|
||||
}
|
||||
addrSearchFragment.updateListAdapter(rows, false);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
app.showToastMessage(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void reloadHistory() {
|
||||
|
@ -1186,10 +1268,12 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
}
|
||||
}
|
||||
searchUICore.selectSearchResult(sr);
|
||||
searchUICore.setSearchApiClass(null);
|
||||
String txt = searchUICore.getPhrase().getText(true);
|
||||
searchQuery = txt;
|
||||
searchEditText.setText(txt);
|
||||
searchEditText.setSelection(txt.length());
|
||||
buttonToolbarView.setVisibility(View.VISIBLE);
|
||||
updateToolbarButton();
|
||||
SearchSettings settings = searchUICore.getPhrase().getSettings();
|
||||
if (settings.getRadiusLevel() != 1) {
|
||||
|
@ -1486,10 +1570,16 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
}
|
||||
|
||||
public class SearchFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||
private final String[] fragments = new String[]{QuickSearchHistoryListFragment.class.getName(),
|
||||
QuickSearchCategoriesListFragment.class.getName()};
|
||||
private final int[] titleIds = new int[]{QuickSearchHistoryListFragment.TITLE,
|
||||
QuickSearchCategoriesListFragment.TITLE};
|
||||
private final String[] fragments = new String[] {
|
||||
QuickSearchHistoryListFragment.class.getName(),
|
||||
QuickSearchCategoriesListFragment.class.getName(),
|
||||
QuickSearchAddressListFragment.class.getName()
|
||||
};
|
||||
private final int[] titleIds = new int[]{
|
||||
QuickSearchHistoryListFragment.TITLE,
|
||||
QuickSearchCategoriesListFragment.TITLE,
|
||||
QuickSearchAddressListFragment.TITLE
|
||||
};
|
||||
private final String[] titles;
|
||||
|
||||
public SearchFragmentPagerAdapter(FragmentManager fm, Resources res) {
|
||||
|
@ -1582,6 +1672,15 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
}
|
||||
}
|
||||
|
||||
public static class QuickSearchAddressListFragment extends QuickSearchListFragment {
|
||||
public static final int TITLE = R.string.address;
|
||||
|
||||
@Override
|
||||
public SearchListFragmentType getType() {
|
||||
return SearchListFragmentType.ADDRESS;
|
||||
}
|
||||
}
|
||||
|
||||
public static class QuickSearchMainListFragment extends QuickSearchListFragment {
|
||||
|
||||
@Override
|
||||
|
@ -1597,27 +1696,4 @@ public class QuickSearchDialogFragment extends DialogFragment implements OsmAndC
|
|||
}
|
||||
}
|
||||
|
||||
public static class CustomSearchButton extends QuickSearchListItem {
|
||||
|
||||
private OnClickListener onClickListener;
|
||||
|
||||
public CustomSearchButton(OsmandApplication app, OnClickListener onClickListener) {
|
||||
super(app, null);
|
||||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
return app.getIconsCache().getIcon(R.drawable.ic_action_search_dark);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return app.getString(R.string.custom_search);
|
||||
}
|
||||
|
||||
public OnClickListener getOnClickListener() {
|
||||
return onClickListener;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package net.osmand.plus.search;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
|
@ -21,7 +22,12 @@ import net.osmand.data.LatLon;
|
|||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.dashboard.DashLocationFragment;
|
||||
import net.osmand.plus.search.QuickSearchDialogFragment.CustomSearchButton;
|
||||
import net.osmand.plus.search.listitems.QuickSearchButtonListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchHeaderListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchListItemType;
|
||||
import net.osmand.plus.search.listitems.QuickSearchMoreListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchSelectAllListItem;
|
||||
import net.osmand.search.core.SearchPhrase;
|
||||
import net.osmand.util.Algorithms;
|
||||
import net.osmand.util.OpeningHoursParser;
|
||||
|
@ -40,24 +46,17 @@ public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
|||
private Float heading;
|
||||
private boolean useMapCenter;
|
||||
|
||||
private int searchMoreItemPosition;
|
||||
private int selectAllItemPosition;
|
||||
private int customSearchItemPosition;
|
||||
|
||||
private int screenOrientation;
|
||||
private int dp56;
|
||||
private int dp1;
|
||||
|
||||
private boolean hasSearchMoreItem;
|
||||
|
||||
private OnSelectionListener selectionListener;
|
||||
private boolean selectionMode;
|
||||
private boolean selectAll;
|
||||
private List<QuickSearchListItem> selectedItems = new ArrayList<>();
|
||||
|
||||
private static final int ITEM_TYPE_REGULAR = 0;
|
||||
private static final int ITEM_TYPE_SEARCH_MORE = 1;
|
||||
private static final int ITEM_TYPE_SELECT_ALL = 2;
|
||||
private static final int ITEM_TYPE_CUSTOM_SEARCH = 3;
|
||||
|
||||
public interface OnSelectionListener {
|
||||
|
||||
void onUpdateSelectionMode(List<QuickSearchListItem> selectedItems);
|
||||
|
@ -150,75 +149,62 @@ public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
|||
public void setListItems(List<QuickSearchListItem> items) {
|
||||
setNotifyOnChange(false);
|
||||
clear();
|
||||
hasSearchMoreItem = false;
|
||||
for (QuickSearchListItem item : items) {
|
||||
add(item);
|
||||
if (!hasSearchMoreItem && item.getType() == QuickSearchListItemType.SEARCH_MORE) {
|
||||
hasSearchMoreItem = true;
|
||||
}
|
||||
}
|
||||
acquireAdditionalItemsPositions();
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void addListItem(QuickSearchListItem item) {
|
||||
if (searchMoreItemPosition != -1 && item instanceof QuickSearchMoreListItem) {
|
||||
public void addListItem(@NonNull QuickSearchListItem item) {
|
||||
if (hasSearchMoreItem && item.getType() == QuickSearchListItemType.SEARCH_MORE) {
|
||||
return;
|
||||
}
|
||||
setNotifyOnChange(false);
|
||||
add(item);
|
||||
acquireAdditionalItemsPositions();
|
||||
if (item.getType() == QuickSearchListItemType.SEARCH_MORE) {
|
||||
hasSearchMoreItem = true;
|
||||
}
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void insertListItem(QuickSearchListItem item, int index) {
|
||||
public void insertListItem(@NonNull QuickSearchListItem item, int index) {
|
||||
setNotifyOnChange(false);
|
||||
insert(item, index);
|
||||
acquireAdditionalItemsPositions();
|
||||
if (item.getType() == QuickSearchListItemType.SEARCH_MORE) {
|
||||
hasSearchMoreItem = true;
|
||||
}
|
||||
setNotifyOnChange(true);
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void acquireAdditionalItemsPositions() {
|
||||
selectAllItemPosition = -1;
|
||||
searchMoreItemPosition = -1;
|
||||
customSearchItemPosition = -1;
|
||||
if (getCount() > 0) {
|
||||
QuickSearchListItem first = getItem(0);
|
||||
QuickSearchListItem last = getItem(getCount() - 1);
|
||||
selectAllItemPosition = first instanceof QuickSearchSelectAllListItem ? 0 : -1;
|
||||
searchMoreItemPosition = last instanceof QuickSearchMoreListItem ? getCount() - 1 : -1;
|
||||
customSearchItemPosition = last instanceof CustomSearchButton ? getCount() - 1 : -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuickSearchListItem getItem(int position) {
|
||||
return super.getItem(position);
|
||||
public boolean isEnabled(int position) {
|
||||
return getItem(position).getType() != QuickSearchListItemType.HEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemViewType(int position) {
|
||||
if (position == searchMoreItemPosition) {
|
||||
return ITEM_TYPE_SEARCH_MORE;
|
||||
} else if (position == customSearchItemPosition) {
|
||||
return ITEM_TYPE_CUSTOM_SEARCH;
|
||||
} else if (position == selectAllItemPosition) {
|
||||
return ITEM_TYPE_SELECT_ALL;
|
||||
} else {
|
||||
return ITEM_TYPE_REGULAR;
|
||||
}
|
||||
return getItem(position).getType().ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 4;
|
||||
return QuickSearchListItemType.values().length;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public View getView(final int position, View convertView, ViewGroup parent) {
|
||||
public View getView(final int position, View convertView, @NonNull ViewGroup parent) {
|
||||
final QuickSearchListItem listItem = getItem(position);
|
||||
int viewType = getItemViewType(position);
|
||||
QuickSearchListItemType type = listItem.getType();
|
||||
LinearLayout view;
|
||||
if (viewType == ITEM_TYPE_SEARCH_MORE) {
|
||||
if (type == QuickSearchListItemType.SEARCH_MORE) {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) app
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
@ -229,7 +215,7 @@ public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
|||
}
|
||||
|
||||
((TextView) view.findViewById(R.id.title)).setText(listItem.getName());
|
||||
} else if (viewType == ITEM_TYPE_CUSTOM_SEARCH) {
|
||||
} else if (type == QuickSearchListItemType.BUTTON) {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) app
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
@ -238,7 +224,9 @@ public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
|||
} else {
|
||||
view = (LinearLayout) convertView;
|
||||
}
|
||||
} else if (viewType == ITEM_TYPE_SELECT_ALL) {
|
||||
((ImageView) view.findViewById(R.id.imageView)).setImageDrawable(listItem.getIcon());
|
||||
((TextView) view.findViewById(R.id.title)).setText(listItem.getName());
|
||||
} else if (type == QuickSearchListItemType.SELECT_ALL) {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) app
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
@ -257,6 +245,18 @@ public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
|||
toggleCheckbox(position, ch);
|
||||
}
|
||||
});
|
||||
} else if (type == QuickSearchListItemType.HEADER) {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) app
|
||||
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
view = (LinearLayout) inflater.inflate(
|
||||
R.layout.search_header_list_item, null);
|
||||
} else {
|
||||
view = (LinearLayout) convertView;
|
||||
}
|
||||
view.findViewById(R.id.top_divider)
|
||||
.setVisibility(((QuickSearchHeaderListItem)listItem).isShowTopDivider() ? View.VISIBLE : View.GONE);
|
||||
((TextView) view.findViewById(R.id.title)).setText(listItem.getName());
|
||||
} else {
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = (LayoutInflater) app
|
||||
|
@ -344,11 +344,12 @@ public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
|||
app.getSettings().isLightContent() ? R.color.bg_color_light : R.color.bg_color_dark));
|
||||
View divider = view.findViewById(R.id.divider);
|
||||
if (divider != null) {
|
||||
if (position == getCount() - 1) {
|
||||
if (position == getCount() - 1 || getItem(position + 1).getType() == QuickSearchListItemType.HEADER) {
|
||||
divider.setVisibility(View.GONE);
|
||||
} else {
|
||||
divider.setVisibility(View.VISIBLE);
|
||||
if (position + 1 == searchMoreItemPosition || position == selectAllItemPosition) {
|
||||
if (getItem(position + 1).getType() == QuickSearchListItemType.SEARCH_MORE
|
||||
|| type == QuickSearchListItemType.SELECT_ALL) {
|
||||
LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp1);
|
||||
p.setMargins(0, 0, 0 ,0);
|
||||
divider.setLayoutParams(p);
|
||||
|
@ -364,13 +365,14 @@ public class QuickSearchListAdapter extends ArrayAdapter<QuickSearchListItem> {
|
|||
}
|
||||
|
||||
public void toggleCheckbox(int position, CheckBox ch) {
|
||||
int viewType = getItemViewType(position);
|
||||
if (viewType == ITEM_TYPE_SELECT_ALL) {
|
||||
QuickSearchListItemType type = getItem(position).getType();
|
||||
if (type == QuickSearchListItemType.SELECT_ALL) {
|
||||
selectAll = ch.isChecked();
|
||||
if (ch.isChecked()) {
|
||||
selectedItems.clear();
|
||||
for (int i = 0; i < getCount(); i++) {
|
||||
if (getItemViewType(i) == ITEM_TYPE_REGULAR) {
|
||||
QuickSearchListItemType t = getItem(i).getType();
|
||||
if (t == QuickSearchListItemType.SEARCH_RESULT) {
|
||||
selectedItems.add(getItem(i));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,10 @@ import net.osmand.plus.activities.MapActivity;
|
|||
import net.osmand.plus.base.OsmAndListFragment;
|
||||
import net.osmand.plus.dashboard.DashLocationFragment;
|
||||
import net.osmand.plus.helpers.SearchHistoryHelper.HistoryEntry;
|
||||
import net.osmand.plus.search.QuickSearchDialogFragment.CustomSearchButton;
|
||||
import net.osmand.plus.search.listitems.QuickSearchButtonListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchListItem;
|
||||
import net.osmand.plus.search.listitems.QuickSearchListItemType;
|
||||
import net.osmand.plus.search.listitems.QuickSearchMoreListItem;
|
||||
import net.osmand.search.core.ObjectType;
|
||||
import net.osmand.search.core.SearchResult;
|
||||
import net.osmand.util.Algorithms;
|
||||
|
@ -47,6 +50,7 @@ public abstract class QuickSearchListFragment extends OsmAndListFragment {
|
|||
enum SearchListFragmentType {
|
||||
HISTORY,
|
||||
CATEGORIES,
|
||||
ADDRESS,
|
||||
MAIN
|
||||
}
|
||||
|
||||
|
@ -86,11 +90,11 @@ public abstract class QuickSearchListFragment extends OsmAndListFragment {
|
|||
if (index < listAdapter.getCount()) {
|
||||
QuickSearchListItem item = listAdapter.getItem(index);
|
||||
if (item != null) {
|
||||
if (item instanceof QuickSearchMoreListItem) {
|
||||
if (item.getType() == QuickSearchListItemType.SEARCH_MORE) {
|
||||
((QuickSearchMoreListItem) item).getOnClickListener().onClick(view);
|
||||
} else if (item instanceof CustomSearchButton) {
|
||||
((CustomSearchButton) item).getOnClickListener().onClick(view);
|
||||
} else {
|
||||
} else if (item.getType() == QuickSearchListItemType.BUTTON) {
|
||||
((QuickSearchButtonListItem) item).getOnClickListener().onClick(view);
|
||||
} else if (item.getType() == QuickSearchListItemType.SEARCH_RESULT) {
|
||||
SearchResult sr = item.getSearchResult();
|
||||
|
||||
if (sr.objectType == ObjectType.POI
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package net.osmand.plus.search.listitems;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.View;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
|
||||
public class QuickSearchButtonListItem extends QuickSearchListItem {
|
||||
|
||||
private int iconId;
|
||||
private String title;
|
||||
private View.OnClickListener onClickListener;
|
||||
private int colorId;
|
||||
|
||||
public QuickSearchButtonListItem(OsmandApplication app, int iconId, String title, View.OnClickListener onClickListener) {
|
||||
super(app, null);
|
||||
this.iconId = iconId;
|
||||
this.title = title;
|
||||
this.onClickListener = onClickListener;
|
||||
this.colorId = app.getSettings().isLightContent() ? R.color.color_dialog_buttons_light : R.color.color_dialog_buttons_dark;
|
||||
}
|
||||
|
||||
public QuickSearchListItemType getType() {
|
||||
return QuickSearchListItemType.BUTTON;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIcon() {
|
||||
if (iconId != 0) {
|
||||
return app.getIconsCache().getIcon(iconId, colorId);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public View.OnClickListener getOnClickListener() {
|
||||
return onClickListener;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package net.osmand.plus.search.listitems;
|
||||
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
||||
public class QuickSearchHeaderListItem extends QuickSearchListItem {
|
||||
|
||||
private String title;
|
||||
private boolean showTopDivider;
|
||||
|
||||
public QuickSearchHeaderListItem(OsmandApplication app, String title, boolean showTopDivider) {
|
||||
super(app, null);
|
||||
this.title = title;
|
||||
this.showTopDivider = showTopDivider;
|
||||
}
|
||||
|
||||
public QuickSearchListItemType getType() {
|
||||
return QuickSearchListItemType.HEADER;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public boolean isShowTopDivider() {
|
||||
return showTopDivider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return title;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.plus.search;
|
||||
package net.osmand.plus.search.listitems;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
@ -41,6 +41,10 @@ public class QuickSearchListItem {
|
|||
this.searchResult = searchResult;
|
||||
}
|
||||
|
||||
public QuickSearchListItemType getType() {
|
||||
return QuickSearchListItemType.SEARCH_RESULT;
|
||||
}
|
||||
|
||||
public SearchResult getSearchResult() {
|
||||
return searchResult;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package net.osmand.plus.search.listitems;
|
||||
|
||||
public enum QuickSearchListItemType {
|
||||
SEARCH_RESULT,
|
||||
HEADER,
|
||||
BUTTON,
|
||||
SEARCH_MORE,
|
||||
SELECT_ALL
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.plus.search;
|
||||
package net.osmand.plus.search.listitems;
|
||||
|
||||
import android.view.View.OnClickListener;
|
||||
|
||||
|
@ -15,6 +15,10 @@ public class QuickSearchMoreListItem extends QuickSearchListItem {
|
|||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
public QuickSearchListItemType getType() {
|
||||
return QuickSearchListItemType.SEARCH_MORE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
|
@ -1,4 +1,4 @@
|
|||
package net.osmand.plus.search;
|
||||
package net.osmand.plus.search.listitems;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
|
@ -15,6 +15,10 @@ public class QuickSearchSelectAllListItem extends QuickSearchListItem {
|
|||
this.onClickListener = onClickListener;
|
||||
}
|
||||
|
||||
public QuickSearchListItemType getType() {
|
||||
return QuickSearchListItemType.SELECT_ALL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
Loading…
Reference in a new issue