- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我目前正在编写的应用程序处理地点。创建地点的主要方法是输入地址。为用户体验提供一种方便的方式非常重要。
在调查了一段时间后,我得出的结论是,最好的方法是基于当前位置和用户输入(如在 Google map 应用程序中)自动完成的文本区域。由于很遗憾 Google Map API 没有提供此功能,因此我必须自己实现它。
要获得地址建议,我使用 Geocoder .这些建议提供给 AutoCompleteTextView通过自定义 ArrayAdaptor通过自定义Filter .
ArrayAdapter(部分代码已被删除)
public class AddressAutoCompleteAdapter extends ArrayAdapter<Address> {
@Inject private LayoutInflater layoutInflater;
private ArrayList<Address> suggested;
private ArrayList<Address> lastSuggested;
private String lastInput = null;
private AddressLoader addrLoader;
public AddressAutoCompleteAdapter(Activity activity,
AddressLoaderFactory addrLoaderFact,
int maxSuggestionsCount) {
super(activity,R.layout.autocomplete_address_item);
suggested = new ArrayList<Address>();
lastSuggested = new ArrayList<Address>();
addrLoader = addrLoaderFact.create(10);
}
...
@Override
public Filter getFilter() {
Filter myFilter = new Filter() {
...
@SuppressWarnings("unchecked")
@Override
protected FilterResults performFiltering(CharSequence constraint) {
Log.d("MyPlaces","performFiltring call");
FilterResults filterResults = new FilterResults();
boolean debug = false;
if(constraint != null) {
// Load address
try {
suggested = addrLoader.load(constraint.toString());
}
catch(IOException e) {
e.printStackTrace();
Log.d("MyPlaces","No data conection avilable");
/* ToDo : put something useful here */
}
// If the address loader returns some results
if (suggested.size() > 0) {
filterResults.values = suggested;
filterResults.count = suggested.size();
// If there are no result with the given input we check last input and result.
// If the new input is more accurate than the previous, display result for the
// previous one.
} else if (constraint.toString().contains(lastInput)) {
debug = true;
Log.d("MyPlaces","Keep last suggestion : " + lastSuggested.get(0).toString());
filterResults.values = lastSuggested;
filterResults.count = lastSuggested.size();
} else {
filterResults.values = new ArrayList<Address>();
filterResults.count = 0;
}
if ( filterResults.count > 0) {
lastSuggested = (ArrayList<Address>) filterResults.values;
}
lastInput = constraint.toString();
}
if (debug) {
Log.d("MyPlaces","filter result count :" + filterResults.count);
}
return filterResults;
}
@Override
protected void publishResults(CharSequence contraint, FilterResults results) {
AddressAutoCompleteAdapter.this.notifyDataSetChanged();
}
};
return myFilter;
}
...
AddressLoader(部分代码已被删除)
public class GeocoderAddressLoader implements AddressLoader {
private Application app;
private int maxSuggestionsCount;
private LocationManager locationManager;
@Inject
public GeocoderAddressLoader(
Application app,
LocationManager locationManager,
@Assisted int maxSuggestionsCount){
this.maxSuggestionsCount = maxSuggestionsCount;
this.app = app;
this.locationManager = locationManager;
}
/**
* Take a string representing an address or a place and return a list of corresponding
* addresses
* @param addrString A String representing an address or place
* @return List of Address corresponding to the given address description
* @throws IOException If Geocoder API cannot be called
*/
public ArrayList<Address> load(String addrString) throws IOException {
//Try to filter with the current location
Location current = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
Geocoder geocoder = new Geocoder(app,Locale.getDefault());
ArrayList<Address> local = new ArrayList<Address>();
if (current != null) {
local = (ArrayList<Address>) geocoder.getFromLocationName(
addrString,
maxSuggestionsCount,
current.getLatitude()-0.1,
current.getLongitude()-0.1,
current.getLatitude()+0.1,
current.getLongitude()+0.1);
}
if (local.size() < maxSuggestionsCount) {
ArrayList<Address> global = (ArrayList<Address>) geocoder.getFromLocationName(
addrString, maxSuggestionsCount - local.size());
for (Address globalAddr : global) {
if (!containsAddress(local,globalAddr))
local.add(globalAddr);
}
}
return local;
}
...
这个实现确实有效,但并不完美。
AddressLoader 有一些输入时出现奇怪的行为。
例如如果用户想输入这个地址
10 rue Guy Ropartz 54600 Villers-les-Nancy
当他进入时:
10 rue Guy
有一些建议,但不是想要的地址。
如果达到此输入时他继续输入文本:
10 rue Guy Ro
建议消失。当输入为时,最终出现所需的地址
10 rue Guy Ropart
我认为这会让用户感到不安。奇怪的是没有建议 "10 rue Guy Ro" 而有建议 "10 rue Guy" 和 "10 rue Guy Ropart"嗯>...
我想出了解决此问题的可能方法并尝试实现它。这个想法是如果在输入更长的地址后没有 AdressLoader 建议的地址,则保留先前的建议。在我们的示例中,当输入为 “10 rue Guy Ro” 时,保留 “10 rue Guy” 建议。
很遗憾,我的代码不起作用。当我处于这种情况时,代码的大部分内容都达到了:
else if (constraint.toString().contains(lastInput)) {
debug = true;
Log.d("MyPlaces","Keep last suggestion : " + lastSuggested.get(0).toString());
filterResults.values = lastSuggested;
filterResults.count = lastSuggested.size();
}
performFiltering 返回的 FilterResult 中充满了好的建议,但它没有出现在 View 中。也许我错过了 publishResults 中的某些内容...
更新
出于兼容性考虑,我基于 Google Geocode Http API 实现了一个新的 AddressLoader。 (因为默认的 Android 地理编码器服务并非在所有设备上都可用)。它重现了完全相同的奇怪行为。
最佳答案
Geocoder api 的设计目的不是为“10 rue Guy Ro”等部分字符串提供建议。你可以在谷歌地图上试试这个,输入“10 rue Guy Ro”,留个空格。你不会得到任何建议(谷歌地图使用地理编码器),但是当你删除空间时,你会得到关于部分字符串的建议(谷歌地图使用私有(private) API)。您可以像使用 Google map 一样使用 Geocoder api,仅在用户在他输入的字符串中输入空格后获取建议。
关于Android AutocompleteTextView 使用 ArrayAdapter 和 Filter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10050108/
我应该在 Angular 应用程序中使用哪个,为什么? array.filter(o => o.name === myName); 或 $filter('filter')(array, {name:
以下两个调用是否解析为 Django 中的等效 SQL 查询? 链接多个调用 Model.objects \ .filter(arg1=foo) \ .filter(arg2=bar) \ ... 将
我正在尝试在 hbase-1.0.0 上运行 completebulkload。但是遇到错误, "java.lang.NoClassDefFoundError: org/apache/hadoop/h
我从这篇文章中学习了“树”和“索引”:Learning Git Internals by Example 但是当谈到“git filter-branch”命令时,我不知道“--tree-filter”
我正在尝试构建我的自定义过滤器以进行身份验证,但是当我尝试运行我的 WebAPI 解决方案时遇到了这个问题: The given filter instance must implement on
我想保留一个过滤器函数的列表,并通过返回true的过滤器来标记这些项。这是接近但不完全。。主要问题是std::stringify!总是返回“ADF”,可能是我声明为ADF的变量名。。第二个问题是,在定
我想保留一个筛选器函数列表,并通过返回True的筛选器来标记这些项目。这已经很接近了,但还不完全是。。主要问题是std::stringify!总是返回“ADF”,可能是我声明为ADF的变量名。。第二个
我尝试在 graphql 查询中使用 where: filter 但不幸的是我遇到了一些错误。我做错了什么? shoeposts { data { attributes(where: {s
几周以来,我一直在使用 Zend Framework 2,尽管在线文档非常不完整,但我还是设法建立了我的网站的初稿。 不幸的是,我在尝试实现 Zend\Filter\File\Rename 过滤器的自
我正在尝试在 APC 中使用 apc.filter 等功能。但是我所做的一切都不起作用 我应该完成 2 项任务。 1)需要包含1个目录用于缓存。我的代码在apc.ini apc.cache by de
我想使用一个可能返回 Err 的过滤器函数结果,并将其冒泡到包含函数: mycoll.into_iter() .filter(|el| { if el == "bad" { E
每个 Controller 都应该有方法filters(),在那里你可以指定一些类,我想知道,这些类是如何被框架包含的?这些类是如何配置的,以及何时配置,也许有人可以给我一个使用filters()并包
我想在一维信号上使用巴特沃斯滤波器。在 Matlab 中,脚本如下所示: f=100; f_cutoff = 20; fnorm =f_cutoff/(f/2); [b,a] = butter
我想比较两个列表,以便找到第一个列表中不在第二个列表中的值并返回它们。提前谢谢大家代码返回:不再支持过滤器有没有其他方法可以做到这一点 MATCH (cu:Customer{name: "myCust
在 Android 应用程序中,我有一个通用设置 -- 一个带有 ArrayAdapter 的 ListView。在某一时刻,我调用了适配器的 getFilter().filter() 方法,它很好地
所以我有如下数据: [ { "id": 0, "title": "happy dayys", "owner": {"id": "1", "username
阅读Mastering Web Development with AngularJS ,我正在尝试创建并使用一个使用 $filter 模块/关键字的新过滤器。 HTML
所以我的理解是 halt 命令应该停止当前过滤器中的请求,但它似乎继续。下面是一个非常简单的 Sinatra 应用程序,演示了这一点。 服务器.rb require 'sinatra' before
我正在尝试将散列传递给 URL 以设置 UIkit 过滤器。 All
我正在使用 django-filter应用程序。但是有一个问题我不知道如何解决。它几乎与 django 文档中描述的完全相同: https://docs.djangoproject.com/en/1.
我是一名优秀的程序员,十分优秀!