0

I am new to Android and experimenting with AutoCompleteTextView and different adapters. Having gotten it working with an ArrayAdapter (discussed here) I am now trying the same using a chain of two AsyncTasks. I have seen a couple examples of this approach elsewhere and I think it is tidier than attempting to syncronise data between threads. it also allows me to keep a K,V hashmap of each item so hopefully I can pull the item ID when clicking on a suggestion for the next stage of this application.

Under this approach, I am again struggling to get the View to update with suggestions. Nothing appears at all apart from what I type into the Edit box. Is this a timing issue between the UI thread and the AsyncTask chain? or perhaps I a mistake in the adapter/view binding?

Note: I have already tried with the autoComplete.setAdapter(adapter); being applied in the ParserTask onPostExecute() method. That didn't work either.

public class MainActivity extends Activity {
    public String TAG = new String("MAINACTIVITY");
    public CustomAutoCompleteView autoComplete;
    public InputStream inputStream;
    private String serviceURL = new String("http://www.autocompare.co.uk/search.php?q=");
    public QueryTask queryTask;
    public ParserTask parserTask;
    public SimpleAdapter adapter;

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

        autoComplete = (CustomAutoCompleteView) findViewById(R.id.autocomparesayt);
        autoComplete.setHint(R.string.search_hint);
        autoComplete.setThreshold(1);
        autoComplete.setAdapter(adapter);

        autoComplete.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(final CharSequence s, int start, int before, int count) {
                int queryThreshold = 3;
                if (s.length() != 2 && (s.length() - 1) % queryThreshold != 0) {
                    return;
                }

                queryTask = new QueryTask();
                queryTask.execute(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) { }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
       });
    }

    private class QueryTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... vehicle) {
            // Go fetch data from webservice
            // this bit works fine
            return(data);
        }

        @Override
        protected void onPostExecute(String result) {
            Log.d(TAG, "now entered parser task");
            super.onPostExecute(result);
            parserTask = new ParserTask();
            parserTask.execute(result);
        }
    }

    private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {
        @Override
        protected List<HashMap<String, String>> doInBackground(String... jsonData) {
            List<HashMap<String, String>> vehicles = null;
            VehicleJSONParser vehicleJsonParser = new VehicleJSONParser();

            // parse JSON string and load data into vehicles
            // this bit works fine too

            return vehicles;
        }

        @Override
        protected void onPostExecute(List<HashMap<String, String>> result) {
            String[] from = {"name"};
            int[] to = new int[] { android.R.id.text1 };

            //  Attempt to set up adapter with data bubbled up from parserTask execution
            //  THIS BIT LOGS NO ERRORS, BUT AUTOCOMPLETETEXTVIEW REMAINS UNCHANGED
            adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1,
           from, to);
            adapter.notifyDataSetChanged();
        }
    }
}
Community
  • 1
  • 1
planetguru
  • 425
  • 3
  • 14
  • the stackoverflow code formatter is putting whacky line spacing in before some closing braces - darned if I can figure out how to stop that! – planetguru Mar 22 '13 at 23:58
  • Everything looks ok, except the correct approach is using `autoComplete.setAdapter()` in `onPostExecute()`. I see that you have made a custom `AutoCompleteTextView`, maybe there is something wrong within that code? – Ole Mar 23 '13 at 01:14
  • What is with that `if` clause in the `onTextChanged()`? Also , in the previous question, remember that I called `autoCompleteAdapter.getFilter().filter(s, autoComplete);` to trigger the drop down. Setting the adapter and calling notifyDataSetChanged will not show it. – user Mar 23 '13 at 06:14
  • Thanks for the pointers. Luksprog, what would you pass as 's' in autoCompleteAdapter.getFilter().filter(s, autoComplete); in this set up? – planetguru Mar 23 '13 at 19:38
  • Ok - sounds unbelievable, but it seems that moving the setAdapter() method back down to postExecute and keeping notifyDataSetChanged() in place, the darn thing is working! – planetguru Mar 23 '13 at 19:58
  • FYI, rolled back to the original code and moved the solution into the answer (where it belongs ;-) – Leigh Jun 13 '13 at 18:51

1 Answers1

2

Ok - sounds unbelievable, but it seems that moving the setAdapter() method back down to postExecute and keeping notifyDataSetChanged() in place, the darn thing is working!

(Next step is to figure out AutoCompleteTextView click events probably using intents/bundles/fragments.. wheee!)

Here is the final working code:

public class MainActivity extends Activity {
    public String TAG = new String("MAINACTIVITY");
    public CustomAutoCompleteView autoComplete;
    public InputStream inputStream;
    private String serviceURL = new String("http://www.blabla.co.uk/search.php?q=");
    public QueryTask queryTask;
    public ParserTask parserTask;
    public SimpleAdapter adapter;

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

        autoComplete = (CustomAutoCompleteView) findViewById(R.id.autocomparesayt);
        autoComplete.setHint(R.string.search_hint);
        autoComplete.setThreshold(1);

        autoComplete.addTextChangedListener(new TextWatcher() {

            @Override
            public void onTextChanged(final CharSequence s, int start, int before, int count) {
                int queryThreshold = 3;
                if (s.length() != 2 && (s.length() - 1) % queryThreshold != 0) {
                    return;
                }

                queryTask = new QueryTask();
                queryTask.execute(s.toString());
            }

            @Override
            public void afterTextChanged(Editable s) { }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
       });
    }

    private class QueryTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... vehicle) {
            // Go fetch data from webservice
            // this bit works fine
            return(data);
        }

        @Override
        protected void onPostExecute(String result) {
            Log.d(TAG, "now entered parser task");
            super.onPostExecute(result);
            parserTask = new ParserTask();
            parserTask.execute(result);
        }
    }

    private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {
        @Override
        protected List<HashMap<String, String>> doInBackground(String... jsonData) {
            List<HashMap<String, String>> vehicles = null;
            VehicleJSONParser vehicleJsonParser = new VehicleJSONParser();

            // parse JSON string and load data into vehicles
            // this bit works fine too

            return vehicles;
        }

        @Override
        protected void onPostExecute(List<HashMap<String, String>> result) {
            String[] from = {"name"};
            int[] to = new int[] { android.R.id.text1 };

            adapter = new SimpleAdapter(getBaseContext(), result, android.R.layout.simple_list_item_1,
           from, to);
           autoComplete.setAdapter(adapter);
           adapter.notifyDataSetChanged();
        }
    }
} 
Leigh
  • 28,765
  • 10
  • 55
  • 103
planetguru
  • 425
  • 3
  • 14