我遇到了问题,我知道问题出在哪里,但我不明白为什么它有时会起作用,有时却不行。这就是我想做的事。
我有一个显示Google MapView的Android应用程序,在这个MapView之上有一个自动完成的textview。我从Google获得了价值(以json格式),我可以在此自动完成文本视图中显示它们。这种情况一直有效。现在当我按下我从谷歌获得的一个选项时,我想放大到那个位置。这大部分时间都适用。
因此,当我按下Elfde地址时,我会从Google获得5个选项/预测。之后我显示这些选项。其中一个选择是比利时的Elfde-Liniestraat。 Google MapView会缩放到该位置。如果我输入不来梅,并选择德国不来梅,它会缩放到那个位置。但是当我输入Peer并选择Peer,比利时时,我在ArrayAdapter中得到一个indexOutOfBounds异常。
现在代码:
当我的自动完成TextView中的文本更改时,我使用此代码:
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (count % 3 == 1){
// Get the places and pass the argument in the TextView to the task.
GetPlaces task = new GetPlaces();
task.execute(_txtFindLocation.getText().toString());
}
}
当我点击某个项目时,我使用此代码:
_txtFindLocation.setOnItemClickListener(new OnItemClickListener(){
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// Hide the keyboard.
InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(_txtFindLocation.getWindowToken(), 0);
Log.v("Take a look on variables", "item: " + String.valueOf(arg2) + ", AdapterView: " + arg0.getCount() + ", _strArrayAdapter: " + _strArrayAdapter.getCount());
// Move to specified location.
moveToLocation(arg0.getItemAtPosition(arg2).toString());
// Clear the adapter, to decrease the size.
_strArrayAdapter.clear();
}
});
这是indexOutOfBoundsException发生的地方。 输入和选择Elfde-Liniestraat,比利时:arg2 = 0,arg0.getCount()= 5,_strArrayAdapter(与arg0链接为源)= 5 输入和选择不来梅,德国:arg2 = 3,arg0.getCount()= 5,_strArrayAdapter = 5 输入和选择Peer,比利时(抛出错误):arg2 = 0,arg0.getCount()= 0,_strArrayAdapter = 0
因此,这里是一个错误被抛出的地方。 _strArrayAdapter填入此函数:
private class GetPlaces extends AsyncTask<String, Void, ArrayList<String>>{
@Override
protected ArrayList<String> doInBackground(String... params) {
ArrayList<String> myPredictions = new ArrayList<String>();
Log.d("Search places", "params: " + params[0].toString());
try{
URL myURL = new URL("https://maps.googleapis.com/maps/api/place/autocomplete/json?input="
+ URLEncoder.encode(params[0], "UTF-8")
+ "&types=geocode&language=en&sensor=true&key=API_KEY");
URLConnection myURLConnection = myURL.openConnection();
BufferedReader myBufferReader = new BufferedReader(new InputStreamReader(myURLConnection.getInputStream()));
String strLine;
StringBuffer strBuffer = new StringBuffer();
// Take Google's legible JSON and turn it into on big String.
while((strLine = myBufferReader.readLine()) != null){
strBuffer.append(strLine);
}
// Turn String into a JSON Object.
JSONObject jsonPredictionsObject = new JSONObject(strBuffer.toString());
// Get a JSON Array that is inside the JSON Object.
JSONArray jsonPredictionsArray = new JSONArray(jsonPredictionsObject.getString("predictions"));
for (int i = 0; i < jsonPredictionsArray.length(); i++){
jsonPredictionsObject = (JSONObject) jsonPredictionsArray.get(i);
myPredictions.add(jsonPredictionsObject.getString("description"));
}
}
catch (IOException e){
Log.e("Search places", "GetPlaces: doInBackGround", e);
}
catch (JSONException e){
Log.e("Search places", "GetPlaces: doInBackGround", e);
}
return myPredictions;
}
protected void onPostExecute(ArrayList<String> result){
Log.d("YourApp", "onPostExecute: " + result.size());
// Update the adapter.
_strArrayAdapter = new ArrayAdapter<String>(getBaseContext(), R.layout.activity_list_item);
_strArrayAdapter.setNotifyOnChange(true);
// Attach the adapter to the TextView.
_txtFindLocation.setAdapter(_strArrayAdapter);
for (String text : result){
Log.d("Search places", "onPostExecute: result = " + text);
_strArrayAdapter.add(text);
}
_strArrayAdapter.clear();
Log.d("Search places", "onPostExecute: autoCompleteAdapter " + _strArrayAdapter.getCount());
}
对于所有三个测试用例,最后一个Log.d(“搜索位置”,“onPostExecute:autoCompleteAdapter”+ _strArrayAdapter.getCount());给出值5!
所以_strArrayAdapter在所有情况下都被填充,但是当我在某些情况下选择一个Item时,_strArrayAdapter的值被设置为0,所以它没有被填充。
为什么会这样?
善意, Martijn Haex
编辑感谢回复,我已经重新审视了我的代码(上图),现在它就像一个魅力。
答案 0 :(得分:0)
问题似乎出现在onTextChanged
函数的以下代码段中。顺便说一下,为什么在lengthOfModifiedText % 3 == 1
时清除阵列?:
if (count % 3 == 1){
_strArrayAdapter.clear();
当您输入"Peer"
时,您的阵列将被清除(无元素)。
每当您输入长度为L, where L % 3 == 1
的文字时,您的strArrayAdapter
将根据您的代码清除。
答案 1 :(得分:0)
好像你在char *为x * 3 + 1(1,4,7,10,...)时清除结果:
if (count % 3 == 1){
_strArrayAdapter.clear();
好像你只想搜索3个或更多字符的地方,对吧?那应该是
if (count > 3){
_strArrayAdapter.clear();
同样在postExecute中我发现你在添加适配器的每个项目上调用notifyDataSetChanged()。你可以稍微优化一下。实际上你可以完全删除它:
protected void onPostExecute(ArrayList<String> result){
Log.d("YourApp", "onPostExecute: " + result.size());
// Update the adapter.
_strArrayAdapter = new ArrayAdapter<String>(getBaseContext(), R.layout.activity_list_item);
for (String text : result){
Log.d("Search places", "onPostExecute: result = " + text);
temp.add(text);
_strArrayAdapter.add(text);
}
// Attach the adapter to the TextView.
_txtFindLocation.setAdapter(_strArrayAdapter);
Log.d("Search places", "onPostExecute: autoCompleteAdapter " + _strArrayAdapter.getCount());
}
此外,如果你得到并且异常,请将堆栈跟踪放在帖子中,并在代码中添加一些代替行号,这样就可以更容易地跟踪问题。