筛选JSON结果自动完成适配器 [英] Filter json results for Autocomplete adapter
问题描述
我有我的应用程序自动完成适配器,我从谷歌Places API所取回的JSON结果。我的问题是,试图得到的结果显示在屏幕上。我使用本指南:的http://examples.java$c$cgeeks.com/android/android-google-places-autocomplete-api-example/
在大多数情况下的code似乎是合理的,但不管是什么原因,我不能得到任何东西打印出来到我的显示器。我真的不明白过滤器是如何工作的,也许如何与自动完成适配器可以解释会有所帮助。
我的onCreate是:
@覆盖
保护无效的onCreate(捆绑savedInstanceState){
super.onCreate(savedInstanceState);
buildGoogleApiClient();
的setContentView(R.layout.activity_maps);
//获取SupportMapFragment并在地图就可以使用了得到通知。
SupportMapFragment mapFragment =(SupportMapFragment)getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(本); 如果(savedInstanceState!= NULL){
mIsResolving = savedInstanceState.getBoolean(KEY_IS_RESOLVING);
mShouldResolve = savedInstanceState.getBoolean(KEY_SHOULD_RESOLVE);
}//创建LocationRequest对象
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setInterval(10 * 1000)// 10秒,以毫秒为单位
.setFastestInterval(1 * 1000); // 1秒,以毫秒为单位 Log.d(TAGGoogleApiClient建); 如果(savedInstanceState!= NULL){
mSignInProgress = savedInstanceState
.getInt(SAVED_PROGRESS,STATE_DEFAULT);
} mShouldResolve =真;
mGoogleApiClient.connect();
Log.d(TAG开始登录); AutoCompleteTextView autoCompView =(AutoCompleteTextView)
findViewById(R.id.autoCompleteTextView);
autoCompView.setAdapter(新GooglePlacesAutocompleteAdapter(这一点,R.layout.activity_maps));
autoCompView.setOnItemClickListener(本); }
我对获得的Json结果的方法是:
公开的ArrayList<串GT;自动完成(字符串输入){
Log.d(TAGperformSearch()); ArrayList的resultList = NULL; AsyncTask的< ArrayList的<弦乐>中太虚,ArrayList的>
myTask =新的AsyncTask< ArrayList的<弦乐>中太虚,ArrayList的>(){ AutoCompleteTextView文字=(AutoCompleteTextView)
findViewById(R.id.autoCompleteTextView);
私人字符串输入= text.getText()的toString()。 @覆盖
保护的ArrayList doInBackground(ArrayList的<弦乐> ... PARAMS){
Log.d(TAG启动搜索); ArrayList的resultList = NULL; HttpURLConnection的康恩= NULL;
StringBuilder的jsonResults =新的StringBuilder();
尝试{
KEYWORD =输入; 终点=乌里
.parse(https://maps.googleapis.com/maps/api/place/nearbysearch/json)
。建立在()
.appendQueryParameter(位置,LOCATION)
.appendQueryParameter(半径,10000)
.appendQueryParameter(关键词,关键词)
.appendQueryParameter(钥匙,API_KEY)
。建立(); 网址URL =新的URL(ENDPOINT.toString()); Log.d(TAG,网址:+网址); 康恩=(HttpURLConnection类)url.openConnection();
InputStreamReader的在=新的InputStreamReader(conn.getInputStream()); //将成果转化为一个StringBuilder
INT读;
的char [] = BUFF新的char [1024];
而((读= in.read(BUFF))!= -1){
jsonResults.append(BUFF,0,读);
}
Log.d(TAG,jsonResults.toString());
}赶上(MalformedURLException的E){
Log.e(TAG,错误处理宿API URL,E);
返回resultList;
}赶上(IOException异常五){
Log.e(TAG,错误连接到Places API的E);
返回resultList;
} {最后
如果(参数conn!= NULL){
conn.disconnect();
}
}
尝试{
//创建一个从结果的JSON对象层次
JSONObject的jsonObj =新的JSONObject(jsonResults.toString());
JSONArray predsJsonArray = jsonObj.getJSONArray(结果); //从提取的结果将说明
resultList =新的ArrayList(predsJsonArray.length());
的for(int i = 0; I< predsJsonArray.length();我++){
的System.out.println(predsJsonArray.getJSONObject(I).getString(名字));
的System.out.println(predsJsonArray.getJSONObject(I).getString(附近));
的System.out.println(=========================================== ==========);
resultList.add(predsJsonArray.getJSONObject(I).getString(名字));
resultList.add(predsJsonArray.getJSONObject(I).getString(附近));
}
}赶上(JSONException E){
Log.e(TAG,无法处理JSON结果,E);
}
Log.d(TAG,resultList.toString());
返回resultList;
} }; myTask.execute(); Log.d(TAG,resultList.toString());
返回resultList;
}
我的过滤器类是:
类GooglePlacesAutocompleteAdapter扩展ArrayAdapter实现过滤的{
私人ArrayList的resultList; 公共GooglePlacesAutocompleteAdapter(上下文的背景下,诠释textViewResourceId){
超(背景下,textViewResourceId);
} @覆盖
公众诠释的getCount(){
返回resultList.size();
} @覆盖
公共字符串的getItem(INT指数){
返回(字符串)resultList.get(指数);
} @覆盖
公共过滤用getFilter(){
过滤器过滤器=新的过滤器(){
@覆盖
保护FilterResults performFiltering(CharSequence的约束){
FilterResults filterResults =新FilterResults();
如果(约束!= NULL){
//检索自动完成结果。
resultList =自动完成(constraint.toString()); //分配数据到FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
返回filterResults;
} @覆盖
保护无效publishResults(CharSequence的约束,Filter.FilterResults结果){
如果(结果= NULL&放大器;!&安培; results.count大于0){
notifyDataSetChanged();
}其他{
notifyDataSetInvalidated();
}
}
};
返回过滤器;
}
}
我知道我从谷歌得到一个完善的结果回来,我内置阵列看起来像这样(它包括名称及周边地区):
[城全球市场,920东湖街#G10,明尼阿波利斯,在
锚鱼和放大器;芯片,302第13大道东北,明尼阿波利斯,布拉斯卡
premium烤肉店,600东亨内大街,明尼阿波利斯,楔
社区合作社2105 Lyndale酒店大道南,明尼阿波利斯,陶自然
食品,2200亨内大街,明尼阿波利斯,鲜放大器;天然食品,1075
96号高速公路西,圣保罗,全食市场,222亨内大街,
明尼阿波利斯,森艾历森泰国,2422中央大街东北,
明尼阿波利斯,密西西比州市场天然食品合作社,622塞尔比大街,
圣保罗东区食品合作社,2551中央大街东北,
明尼阿波利斯,票据进口食品,721西湖街,明尼阿波利斯,
首尔食品公司,1071东穆尔湖驱动器,明尼阿波利斯,苏厄德社区
合作社 - 富兰克林商店,2823东大街富兰克林,明尼阿波利斯,狡猾
沙拉三明治,791雷蒙德大道,圣保罗,亚洲食品,1300 L'东方
街,圣保罗,波尔分发有限公司510 Kasota大道东南,
明尼阿波利斯,彩虹食品,1566大学路西,圣保罗,
蒲公英炊事车,800尼科莱特购物中心,明尼阿波利斯,世界街
厨房,2743 Lyndale酒店大道南#5,明尼阿波利斯,CES食品货架,
东大街19号,明尼阿波利斯]
块引用>任何帮助是AP preciated,谢谢!
这是我对XML activity_maps:<的RelativeLayout的xmlns:机器人=http://schemas.android.com/apk/res/android
的xmlns:工具=http://schemas.android.com/tools
机器人:layout_width =match_parent
机器人:layout_height =match_parent
工具:上下文=com.hudsoncorp.zahudson.roadtrip.MapsActivity> <片段的xmlns:机器人=http://schemas.android.com/apk/res/android
的xmlns:工具=http://schemas.android.com/tools
的xmlns:地图=http://schemas.android.com/apk/res-auto
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:ID =@ + ID /图
工具:上下文=com.hudsoncorp.zahudson.roadtrip.MapsActivity
机器人:名字=com.google.android.gms.maps.SupportMapFragment/> < RelativeLayout的
机器人:方向=垂直
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:填充=10dp> < AutoCompleteTextView
机器人:ID =@ + ID / autoCompleteTextView
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT
机器人:填充=10dp
机器人:提示=搜索位置
机器人:背景=#FFFFFF
机器人:文字颜色=#00000F
机器人:主题=@安卓风格/ Widget.Material.AutoCompleteTextView
机器人:EMS =10
安卓则shadowColor =@色/ background_floating_material_dark>
< requestFocus的/> < / AutoCompleteTextView> < / RelativeLayout的>< / RelativeLayout的>
解决方案我看到你有一个
的AsyncTask
从服务器访问数据,但你真的不需要的AsyncTask
,因为performFiltering()
已经在后台运行,所以你可以把你的)doInBackground()
逻辑performFiltering(
。@覆盖
保护FilterResults performFiltering(CharSequence的约束){ ArrayList的<串GT; resultList = NULL;
FilterResults filterResults =新FilterResults(); 如果(约束!= NULL){
//检索自动完成结果。
Log.d(TAG启动搜索); HttpURLConnection的康恩= NULL;
StringBuilder的jsonResults =新的StringBuilder();
尝试{
KEYWORD = constraint.toString(); 终点=乌里
.parse(https://maps.googleapis.com/maps/api/place/nearbysearch/json)
。建立在()
.appendQueryParameter(位置,LOCATION)
.appendQueryParameter(半径,10000)
.appendQueryParameter(关键词,关键词)
.appendQueryParameter(钥匙,API_KEY)
。建立(); 网址URL =新的URL(ENDPOINT.toString()); Log.d(TAG,网址:+网址); 康恩=(HttpURLConnection类)url.openConnection();
InputStreamReader的在=新的InputStreamReader(conn.getInputStream()); //将成果转化为一个StringBuilder
INT读;
的char [] = BUFF新的char [1024];
而((读= in.read(BUFF))!= -1){
jsonResults.append(BUFF,0,读);
}
Log.d(TAG,jsonResults.toString());
}赶上(MalformedURLException的E){
Log.e(TAG,错误处理宿API URL,E);
返回filterResults;
}赶上(IOException异常五){
Log.e(TAG,错误连接到Places API的E);
返回filterResults;
} {最后
如果(参数conn!= NULL){
conn.disconnect();
}
}
尝试{
//创建一个从结果的JSON对象层次
JSONObject的jsonObj =新的JSONObject(jsonResults.toString());
JSONArray predsJsonArray = jsonObj.getJSONArray(结果); //从提取的结果将说明
resultList =新的ArrayList(predsJsonArray.length());
的for(int i = 0; I< predsJsonArray.length();我++){
的System.out.println(predsJsonArray.getJSONObject(I).getString(名字));
的System.out.println(predsJsonArray.getJSONObject(I).getString(附近));
的System.out.println(=========================================== ==========);
resultList.add(predsJsonArray.getJSONObject(I).getString(名字));
resultList.add(predsJsonArray.getJSONObject(I).getString(附近));
}
}赶上(JSONException E){
Log.e(TAG,无法处理JSON结果,E);
}
Log.d(TAG,resultList.toString()); //分配数据到FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
返回filterResults;
}A
过滤器
就像是一个的AsyncTask
。performFiltering
像doInBackground
和publishResults()
像onPostExecute()
。顺便说一句,不更新在后台线程适配器列表。创建一个新的列表,并将其分配给
FilterResults.values
,然后分配在publishResults适配器列表()
。
publishResults()
应该是这样的:@覆盖
保护无效publishResults(CharSequence的约束,Filter.FilterResults结果){
如果(结果= NULL&放大器;!&安培; results.count大于0){
resultList =(ArrayList的)results.values;
notifyDataSetChanged();
}其他{
notifyDataSetInvalidated();
}
}I have an autocomplete adapter for my app and I am getting back json results from the Google Places API. My trouble is with trying to get the results to display on the screen. I am using this guide: http://examples.javacodegeeks.com/android/android-google-places-autocomplete-api-example/
For the most part the code seems sound, but for whatever reason I can't get anything to print out onto my display. I don't really understand how the filter works, and maybe an explanation for how that works with the autocomplete adapter would help.
My onCreate is:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); buildGoogleApiClient(); setContentView(R.layout.activity_maps); // Obtain the SupportMapFragment and get notified when the map is ready to be used. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); if (savedInstanceState != null) { mIsResolving = savedInstanceState.getBoolean(KEY_IS_RESOLVING); mShouldResolve = savedInstanceState.getBoolean(KEY_SHOULD_RESOLVE); } // Create the LocationRequest object mLocationRequest = LocationRequest.create() .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY) .setInterval(10 * 1000) //10 seconds, in milliseconds .setFastestInterval(1 * 1000); //1 second, in milliseconds Log.d(TAG, "GoogleApiClient built"); if (savedInstanceState != null) { mSignInProgress = savedInstanceState .getInt(SAVED_PROGRESS, STATE_DEFAULT); } mShouldResolve = true; mGoogleApiClient.connect(); Log.d(TAG, "Starting sign-in"); AutoCompleteTextView autoCompView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView); autoCompView.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.activity_maps)); autoCompView.setOnItemClickListener(this); }
My method for getting the Json results is:
public ArrayList<String> autocomplete(String input) { Log.d(TAG, "performSearch()"); ArrayList resultList = null; AsyncTask<ArrayList<String>, Void, ArrayList> myTask = new AsyncTask<ArrayList<String>, Void, ArrayList>() { AutoCompleteTextView text = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView); private String input = text.getText().toString(); @Override protected ArrayList doInBackground(ArrayList<String>... params) { Log.d(TAG, "Starting Search"); ArrayList resultList = null; HttpURLConnection conn = null; StringBuilder jsonResults = new StringBuilder(); try { KEYWORD = input; ENDPOINT = Uri .parse("https://maps.googleapis.com/maps/api/place/nearbysearch/json") .buildUpon() .appendQueryParameter("location", LOCATION) .appendQueryParameter("radius", "10000") .appendQueryParameter("keyword", KEYWORD) .appendQueryParameter("key", API_KEY) .build(); URL url = new URL(ENDPOINT.toString()); Log.d(TAG, "URL: " + url); conn = (HttpURLConnection) url.openConnection(); InputStreamReader in = new InputStreamReader(conn.getInputStream()); // Load the results into a StringBuilder int read; char[] buff = new char[1024]; while ((read = in.read(buff)) != -1) { jsonResults.append(buff, 0, read); } Log.d(TAG, jsonResults.toString()); } catch (MalformedURLException e) { Log.e(TAG, "Error processing Places API URL", e); return resultList; } catch (IOException e) { Log.e(TAG, "Error connecting to Places API", e); return resultList; } finally { if (conn != null) { conn.disconnect(); } } try { // Create a JSON object hierarchy from the results JSONObject jsonObj = new JSONObject(jsonResults.toString()); JSONArray predsJsonArray = jsonObj.getJSONArray("results"); // Extract the Place descriptions from the results resultList = new ArrayList(predsJsonArray.length()); for (int i = 0; i < predsJsonArray.length(); i++) { System.out.println(predsJsonArray.getJSONObject(i).getString("name")); System.out.println(predsJsonArray.getJSONObject(i).getString("vicinity")); System.out.println("====================================================="); resultList.add(predsJsonArray.getJSONObject(i).getString("name")); resultList.add(predsJsonArray.getJSONObject(i).getString("vicinity")); } } catch (JSONException e) { Log.e(TAG, "Cannot process JSON results", e); } Log.d(TAG, resultList.toString()); return resultList; } }; myTask.execute(); Log.d(TAG, resultList.toString()); return resultList; }
My filter class is:
class GooglePlacesAutocompleteAdapter extends ArrayAdapter implements Filterable { private ArrayList resultList; public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) { super(context, textViewResourceId); } @Override public int getCount() { return resultList.size(); } @Override public String getItem(int index) { return (String) resultList.get(index); } @Override public Filter getFilter() { Filter filter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); if (constraint != null) { // Retrieve the autocomplete results. resultList = autocomplete(constraint.toString()); // Assign the data to the FilterResults filterResults.values = resultList; filterResults.count = resultList.size(); } return filterResults; } @Override protected void publishResults(CharSequence constraint, Filter.FilterResults results) { if (results != null && results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }; return filter; } }
I know I'm getting a sound result back from google and my built array looks like this (it includes both name and vicinity):
[Midtown Global Market, 920 East Lake Street #G10, Minneapolis, The Anchor Fish & Chips, 302 13th Avenue Northeast, Minneapolis, Brasa Premium Rotisserie, 600 East Hennepin Avenue, Minneapolis, Wedge Community Co-Op, 2105 Lyndale Avenue South, Minneapolis, Tao Natural Foods, 2200 Hennepin Avenue, Minneapolis, Fresh & Natural Foods, 1075 Highway 96 West, Saint Paul, Whole Foods Market, 222 Hennepin Avenue, Minneapolis, Sen Yai Sen Lek Thai, 2422 Central Avenue Northeast, Minneapolis, Mississippi Market Natural Foods Co-op, 622 Selby Avenue, Saint Paul, Eastside Food Co-Op, 2551 Central Avenue Northeast, Minneapolis, Bills Imported Foods, 721 West Lake Street, Minneapolis, Seoul Foods, 1071 East Moore Lake Drive, Minneapolis, Seward Community Co-op - Franklin Store, 2823 East Franklin Avenue, Minneapolis, Foxy Falafel, 791 Raymond Avenue, Saint Paul, Asian Foods, 1300 L'Orient Street, Saint Paul, Pohl Distributing Co, 510 Kasota Avenue Southeast, Minneapolis, Rainbow Foods, 1566 University Avenue West, Saint Paul, Dandelion Kitchen Truck, 800 Nicollet Mall, Minneapolis, World Street Kitchen, 2743 Lyndale Avenue South #5, Minneapolis, CES Food Shelf, East 19th Street, Minneapolis]
Any help is appreciated, thanks!
[EDIT] Here is my XML for activity_maps:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.hudsoncorp.zahudson.roadtrip.MapsActivity"> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:map="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/map" tools:context="com.hudsoncorp.zahudson.roadtrip.MapsActivity" android:name="com.google.android.gms.maps.SupportMapFragment"/> <RelativeLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"> <AutoCompleteTextView android:id="@+id/autoCompleteTextView" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:hint="Search location" android:background="#FFFFFF" android:textColor="#00000F" android:theme="@android:style/Widget.Material.AutoCompleteTextView" android:ems="10" android:shadowColor="@color/background_floating_material_dark"> <requestFocus /> </AutoCompleteTextView> </RelativeLayout> </RelativeLayout>
解决方案I see you have an
AsyncTask
to access your data from the server, but you don't really need anAsyncTask
becauseperformFiltering()
already runs in the background, so you can put yourdoInBackground()
logic inperformFiltering()
.@Override protected FilterResults performFiltering(CharSequence constraint) { ArrayList<String> resultList = null; FilterResults filterResults = new FilterResults(); if (constraint != null) { // Retrieve the autocomplete results. Log.d(TAG, "Starting Search"); HttpURLConnection conn = null; StringBuilder jsonResults = new StringBuilder(); try { KEYWORD = constraint.toString(); ENDPOINT = Uri .parse("https://maps.googleapis.com/maps/api/place/nearbysearch/json") .buildUpon() .appendQueryParameter("location", LOCATION) .appendQueryParameter("radius", "10000") .appendQueryParameter("keyword", KEYWORD) .appendQueryParameter("key", API_KEY) .build(); URL url = new URL(ENDPOINT.toString()); Log.d(TAG, "URL: " + url); conn = (HttpURLConnection) url.openConnection(); InputStreamReader in = new InputStreamReader(conn.getInputStream()); // Load the results into a StringBuilder int read; char[] buff = new char[1024]; while ((read = in.read(buff)) != -1) { jsonResults.append(buff, 0, read); } Log.d(TAG, jsonResults.toString()); } catch (MalformedURLException e) { Log.e(TAG, "Error processing Places API URL", e); return filterResults ; } catch (IOException e) { Log.e(TAG, "Error connecting to Places API", e); return filterResults ; } finally { if (conn != null) { conn.disconnect(); } } try { // Create a JSON object hierarchy from the results JSONObject jsonObj = new JSONObject(jsonResults.toString()); JSONArray predsJsonArray = jsonObj.getJSONArray("results"); // Extract the Place descriptions from the results resultList = new ArrayList(predsJsonArray.length()); for (int i = 0; i < predsJsonArray.length(); i++) { System.out.println(predsJsonArray.getJSONObject(i).getString("name")); System.out.println(predsJsonArray.getJSONObject(i).getString("vicinity")); System.out.println("====================================================="); resultList.add(predsJsonArray.getJSONObject(i).getString("name")); resultList.add(predsJsonArray.getJSONObject(i).getString("vicinity")); } } catch (JSONException e) { Log.e(TAG, "Cannot process JSON results", e); } Log.d(TAG, resultList.toString()); // Assign the data to the FilterResults filterResults.values = resultList; filterResults.count = resultList.size(); } return filterResults; }
A
Filter
works like anAsyncTask
.performFiltering
is likedoInBackground
andpublishResults()
is likeonPostExecute()
.Incidentally, don't update the adapter list in a background thread. Create a new list and assign it to
FilterResults.values
, then assign the adapter list inpublishResults()
.
publishResults()
should look like this:@Override protected void publishResults(CharSequence constraint, Filter.FilterResults results) { if (results != null && results.count > 0) { resultList = (ArrayList) results.values; notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } }
这篇关于筛选JSON结果自动完成适配器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!