android:根据服务器响应实现应用searchbuild议

我需要在我的android应用程序中build立一个searchfunction,它依靠从服务器的JSON响应。 用户将在位于操作栏的search视图中inputsearch查询。 根据用户键入查询的内容,服务器返回的响应应该显示为下拉提示。 我应该如何去做。 基于我已阅读的文档,我需要实现一个内容提供商。 什么是实现应用程序search最好的方式?

Solutions Collecting From Web of "android:根据服务器响应实现应用searchbuild议"

看下面的代码我已经实现了EditText.You也可以做这样的事情:

private ArrayList<JSONObject> mRightListOverlapData, mRightTempData; mEdit_Search.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { // TODO Auto-generated method stub } @Override public void afterTextChanged(Editable s) { // TODO Auto-generated method stub mRightListOverlapData.clear(); String searchTag = mEdit_Search.getText().toString(); if (searchTag == null || searchTag.equals("")) { mRightTempData.clear(); mOverlapAdapter.notifyDataSetChanged(); } else if (searchTag.length() == 1) { mRightListOverlapData.addAll(mRightTempData); mOverlapAdapter.notifyDataSetChanged(); } else { **startServiceForSearchSuggestion(searchTag);** } } else { try { if (mRightTempData.size() > 0) { for (int i = 0; i < mRightTempData.size(); i++) { if (mRightTempData.get(i) .getString("search_text").toLowerCase() .startsWith(searchTag.toLowerCase())) { mRightListOverlapData.add(mRightTempData .get(i)); } } if (mRightListOverlapData.size() == 0) { JSONObject noData = new JSONObject(); noData.put("search_text", "No Data"); mRightListOverlapData.add(noData); } } mOverlapAdapter.notifyDataSetChanged(); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }); 

当用户在EditText中input第一个字符时,它将调用webService。然后将所有响应保存到tempArray中,当用户input另一个字符时,将从tempArray中search该元素。 startServiceForSearchSuggestion()方法是:

 private void startServiceForSearchSuggestion(String search_tag) { if (!Utils.isNetworkAvailable(getBaseContext())) { Toast.makeText(getBaseContext(), "No Network Available", Toast.LENGTH_SHORT).show(); } else { Intent intent1 = new Intent(this, WebService.class); intent1.putExtra(METHOD, GET_SEARCH_SUGGESTION); intent1.putExtra("search_tag", search_tag); startService(intent1); } } 

它将启动web服务来获得服务器的响应。 服务类是:

  public class WebService extends Service implements WebServiceConstants { private AppPreferences mPrefs; private static String TAG_WEB_SERVICE = "WebService"; private static String DEVICE_TYPE = "android"; private static String MESSAGE_CENTER = "gcm"; private static String URL_JSON = "YOUR_URL"; private Context mContext; private int METHOD_NAME = 1; private String mSearch_Tag = ""; private DBQuery mDBQuery; public static boolean is_Service_Running = false; @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); mContext = this; mPrefs = new AppPreferences(mContext); mDBQuery = new DBQuery(mContext); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub try { METHOD_NAME = intent.getIntExtra(METHOD, 1); mSearch_Tag = intent.getStringExtra("search_tag"); LoadDataFromServer data = new LoadDataFromServer(); data.execute(); } catch (NullPointerException e) { // TODO: handle exception } super.onStart(intent, startId); } public class LoadDataFromServer extends AsyncTask<Void, Void, Void> { JSONObject response; @Override protected Void doInBackground(Void... params) { // TODO Auto-generated method stub JSONObject root = getJsonHeader(); switch (METHOD_NAME) { case GET_SEARCH_SUGGESTION: response = getResponse(yourJsonRequestObject); break; } return null; } @Override protected void onPostExecute(Void result) { // TODO Auto-generated method stub try { switch (METHOD_NAME) { case GET_SEARCH_SUGGESTION: Log.v(TAG_WEB_SERVICE, "Response = GET_SEARCH_SUGGESTION : " + response.toString()); sendBroadcast(new Intent(METHOD_GET_SEARCH_SUGGESTION) .putExtra("Response", response.toString())); break; default: break; } } catch (NullPointerException e) { // TODO: handle exception } } } } 

onPostExecute方法你必须发送广播到你的活动和onCreive这个广播你可以保存你的Json数据到arrayList.Like这样:

 private BroadcastReceiver mReceiverSearchSuggestion = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub JSONObject root; try { root = new JSONObject(intent.getStringExtra("Response")); setSearchSuggestions(root); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; 

方法:

1。

 private JSONObject getResponse(JSONObject obj) { // Create a new HttpClient and Post Header HttpClient httpclient = new DefaultHttpClient(); HttpParams myParams = new BasicHttpParams(); HttpConnectionParams.setConnectionTimeout(myParams, 10000); HttpConnectionParams.setSoTimeout(myParams, 10000); String temp = ""; try { HttpPost httppost = new HttpPost(URL_JSON); httppost.setHeader("Content-type", "application/json"); StringEntity se = new StringEntity(obj.toString()); se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); httppost.setEntity(se); HttpResponse response = httpclient.execute(httppost); temp = EntityUtils.toString(response.getEntity()); Log.v(TAG_WEB_SERVICE, "Temp = " + temp); if (temp == null || temp.trim().equals("")) { } else { return new JSONObject(temp); } } catch (ClientProtocolException e) { } catch (IOException e) { } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } 

2。

 private void setSearchSuggestions(JSONObject root) { // TODO Auto-generated method stub try { JSONObject search_suggestion = root .getJSONObject(METHOD_GET_SEARCH_SUGGESTION); if (search_suggestion.getString("response_type").equalsIgnoreCase( "success")) { if (search_suggestion.has("data")) { mRightTempData.clear(); mRightListOverlapData.clear(); JSONArray data = search_suggestion.getJSONArray("data"); for (int i = 0; i < data.length(); i++) { JSONObject value = data.getJSONObject(i); mRightTempData.add(value); } } else { Toast.makeText(getBaseContext(), "No data related to search", Toast.LENGTH_SHORT) .show(); } } else { Toast.makeText(getBaseContext(), "Search Suggestion : Type Failure", Toast.LENGTH_SHORT) .show(); } } 

我已经设置适配器与Json对象的arrayList是这样的:

  mOverlapAdapter = new RightOverlapAdapter(getBaseContext(), mRightListOverlapData); mDListRightOverLap.setAdapter(mOverlapAdapter); 

您可以直接从指定标记的JSONObject的ArrayList中读取数据到适配器的getView方法中。

你需要像这样在Manifest中定义这个服务:

  <service android:name="com.your.package.WebService" /> 

希望它会帮助你。

您可以为AutoCompleteTextView自定义适配器。

 ... getInput = (AutoCompleteTextView) rootView .findViewById(R.id.translate_word); getInput.setAdapter(new AutoCompleteAdapter(mContext)); ... 

AutoCompleteAdapter类

 public class AutoCompleteAdapter extends ArrayAdapter<AutoCompleteItem> { protected static final String TAG = "AutoCompleteAdapter"; private Context mContext; private LayoutInflater vi; private List<AutoCompleteItem> suggestions; public AutoCompleteAdapter(Context context) { super(context, R.layout.autocomplete_item); this.mContext = context; vi = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); suggestions = new ArrayList<AutoCompleteItem>(); } @Override public int getCount() { return suggestions.size(); } @Override public AutoCompleteItem getItem(int index) { return suggestions.get(index); } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; final AutoCompleteItem i = suggestions.get(position); if (i != null) { AutoCompleteItem aci = (AutoCompleteItem)i; v = vi.inflate(R.layout.autocomplete_item, null); final TextView txtWord = (TextView)v.findViewById(R.id.word); if (txtWord != null) { txtWord.setText(aci.getWord()); } final TextView txtLang = (TextView)v.findViewById(R.id.lang); if (txtLang != null) { if (aci.getLang() != null && !aci.getLang().equals("")) txtLang.setText("[" + aci.getLang().toUpperCase() + "]"); } final TextView txtConj = (TextView)v.findViewById(R.id.conj); if (txtConj != null) { txtConj.setText(aci.getConj()); txtConj.setTag(i); txtConj.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { AutoCompleteItem autoCompleteItem = (AutoCompleteItem)v.getTag(); String lang = autoCompleteItem.getLang(); // v.getParent(). String word = autoCompleteItem.getWord(); } }); } } return v; } @Override public Filter getFilter() { Filter myFilter = new Filter() { @Override protected FilterResults performFiltering(CharSequence constraint) { FilterResults filterResults = new FilterResults(); if (constraint != null && !constraint.toString().equalsIgnoreCase(sWord) && constraint.toString().length() >= 2) { AutoCompleteParse acp = new AutoCompleteParse(); // A class that queries a web API, parses the data and // returns an ArrayList<AutoCompleteItem> List<AutoCompleteItem> new_suggestions =acp.getAutoComplete(mContext, constraint.toString()); suggestions.clear(); for (int i=0;i<new_suggestions.size();i++) { suggestions.add(new_suggestions.get(i)); } if (suggestions.size() > 0) sWord = constraint.toString(); // Now assign the values and count to the FilterResults // object filterResults.values = suggestions; filterResults.count = suggestions.size(); } return filterResults; } @Override protected void publishResults(CharSequence contraint, FilterResults results) { if (contraint != null && !contraint.toString().equalsIgnoreCase(sWord) && contraint.toString().length() >= 2 && results != null && results.count > 0) { notifyDataSetChanged(); } else { notifyDataSetInvalidated(); } } }; return myFilter; } } 

AutoCompleteParse类

 public class AutoCompleteParse { Context mContext; public AutoCompleteParse() { } public List<AutoCompleteItem> getAutoComplete(Context context, String sWord) { this.mContext = context; ... List<AutoCompleteItem> ListData = new ArrayList<AutoCompleteItem>(); try { URL acUrl = new URL(autoCompleteUrl); URLConnection acConn = acUrl.openConnection(); BufferedReader reader = new BufferedReader(new InputStreamReader( acConn.getInputStream())); String line = reader.readLine(); do { ... } while (line != null); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } return ListData; }