AutoCompleteTextView not responding to changes to its ArrayAdapter

只愿长相守 提交于 2019-12-30 07:42:09

问题


The ArrayList appears to be populating just fine, but no matter what approach I use, I can't seem to get the adapter to populate with data. I have tried adding to the ArrayList, also to the ArrayAdapter. Either way I am unable to get a response at the AutoCompleteTextView level, or in the ArrayAdapter itself(and of course the AutoCompleteTextView is doing nothing). Can anybody see what's wrong?

public class MainActivity extends Activity implements TextWatcher {
// private AutoCompleteView autoComplete; 
public String TAG = new String("MAINACTIVITY");
public ArrayAdapter<String> autoCompleteAdapter;
public AutoCompleteTextView autoComplete;
public InputStream inputStream;
public List<String> data;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    data = new ArrayList<String>();
    autoCompleteAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line, data);
    autoCompleteAdapter.setNotifyOnChange(true);
    autoComplete = (AutoCompleteTextView) findViewById(R.id.acsayt);
    autoComplete.setHint(R.string.search_hint);
    autoComplete.setThreshold(2);
    autoComplete.addTextChangedListener(this);
    autoComplete.setAdapter(autoCompleteAdapter);
}

// uphold TextWatcher interface methods
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}

public void onTextChanged(CharSequence s, int start, int before, int count) {
    Log.d(TAG, "I detected a text change " + s.toString());
    data.clear();
    queryWebService();
}

private void queryWebService() {
    new Thread(new Runnable() {
        public void run() {
            Log.d(TAG, "spawned thread");

            //  Code in here to set up http connection, query webservice ...

            // parse the JSON response & add items to adapter
            try {
                JSONArray jArray = new JSONArray(resultString);
                int length = jArray.length();
                int countedValues, capturedValues;
                Log.d(TAG, "response had " + length + " items");
                int i = 0;
                while (i < length) {
                    JSONObject internalObject = jArray.getJSONObject(i);
                    String vehicleName = internalObject.getString("name").toString();
                    Log.d(TAG, "vehicle name is " + vehicleName);
                    try {
                        data.add(vehicleName);  
                        autoCompleteAdapter.add(vehicleName);   // not working
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    countedValues = data.size();    // correctly reports 20 values
                    capturedValues = autoCompleteAdapter.getCount();    //  is zero
                    Log.d(TAG, "array list holds " + countedValues + " values");
                    Log.d(TAG, "array adapter holds " + capturedValues + " values");
                    i++;
                }
            } catch (Exception e) {
                Log.d(TAG, "JSON manipulation err: " + e.toString());
            }
        }
    }).start();
}

}

LogCat shows the expected number of values from data.size(), but zero from autoCompleteAdapter.getCount().


回答1:


The ArrayList appears to be populating just fine, but no matter what approach I use, I can't seem to get the adapter to populate with data

You're going against how the AutoCompleTextView works. When the user starts entering characters in the input box the AutoCompleteTextView will filter the adapter and when that happens it will show the drop down with the values which managed to pass the filter request. Now you've setup the AutoCompleteTextView to make a thread each time the user enters a character, the problem is that the AutoCompleteTextview will never see those values as it requests the adapter to filter before the adapter actually gets populated with the right values. try something like this:

public static class BlockingAutoCompleteTextView extends
        AutoCompleteTextView {

    public BlockingAutoCompleteTextView(Context context) {
        super(context);
    }

    @Override
    protected void performFiltering(CharSequence text, int keyCode) {           
        // nothing, block the default auto complete behavior
    }

}

and to get the data:

public void onTextChanged(CharSequence s, int start, int before, int count) {
    if (autoComplete.getThreashold() < s.length()) {
        return;
    } 
    queryWebService();
}

You need to update the data on the main UI thread and also using the adapter's methods:

// do the http requests you have in the queryWebService method and when it's time to update the data:
runOnUiThread(new Runnable() {
        @Override
    public void run() {
        autoCompleteAdapter.clear();
        // add the data
                for (int i = 0; i < length; i++) {
                     // do json stuff and add the data
                     autoCompleteAdapter.add(theNewItem);                    
                } 
                // trigger a filter on the AutoCompleteTextView to show the popup with the results 
                autoCompleteAdapter.getFilter().filter(s, autoComplete);
    }
});

See if the code above works.



来源:https://stackoverflow.com/questions/15375291/autocompletetextview-not-responding-to-changes-to-its-arrayadapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!