views:

856

answers:

2

I have an Activity with an AutoComplete box on it. Whenever the text changes, I want to call a web service and populate the ArrayAdapter with the new String[] returned. This part all works great, except the list in the UI isn't being refreshed when there are all new values in String[] schools. The original list populated in my onCreate always remains.

I read somewhere I needed to update it on the same thread the UI is running on, so I tried the Runnable listed in my code below. But that, as well as just updating my class variable schools does not work alongside notifyOnDataSetChange()

Where am I going wrong?

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    schools = SchoolProxy.search("Co");
    autoCompleteAdapter = new ArrayAdapter(this,android.R.layout.simple_dropdown_item_1line, schools);
    autoComplete = (AutoCompleteTextView)  findViewById(R.id.edit);
    autoComplete.addTextChangedListener(textChecker);
    autoComplete.setAdapter(autoCompleteAdapter);
}
    ...
    ....
    ...

final TextWatcher textChecker = new TextWatcher() {
    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) 
    {
     schools = SchoolProxy.search(s.toString());
     runOnUiThread(updateAdapter);
    }
};

private Runnable updateAdapter = new Runnable() {
  public void run() {
         autoCompleteAdapter.notifyDataSetChanged();
        }

};

As a less important side note, if each item in schools has a name \n city,state. Is it possible to have the city & state on a second line within the auto drop down box? Just for formatting purposes. Would look cleaner if I could.

Thank you!

+1  A: 

Have you tried the setNotifyOnChange(true)? It is supposed to properly do what you are doing manually whenever you use methods that change the list (add(T), insert(T, int), remove(T), clear()). Perhaps you have to modify the array through these methods on the ArrayAdapter?

I'm not sure if the ArrayAdapter is actually holding the reference to schools or just copied the contents while constructing the ArrayAdapter. Maybe you can take a look at the AOSP code to see what they're doing in that constructor.

GrkEngineer
I will try adding true to the method tonight. If that does not work, I will try clearing the adapter, then looping through the string and adding elements individually (I hope this isn't the solution though).But I will report back my findings and accept if you are correct.
Hallik
I am going to go ahead and assume that I need to clear() then use either add() or insert(). I had the data setup as a String[]. But I am going to experiment with just returning it all as a JSONArray and doing a loop of it.Similar to: schools = SchoolProxy.search(s.toString()); for (int i = 0; i < schools.length; i++) { autoCompleteAdapter.add(schools[i]); }
Hallik
A: 

Guys,

Can you please help me, I am extending BaseAdapter and rendering the screen. Whenever there is a text change, it loads the latest records on my arraylist, but the records are getting reflected on the screen.

    searchText =  new EditText(this);
    searchText.addTextChangedListener( new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            // TODO Auto-generated method stub
            Log.d("on text", "String: " + s);
            loadData(s.toString());
            msgQueueAdapter = new ListAdapter(context, msgQueueList);

            searchText.bringToFront();
            runOnUiThread(new Runnable()  {

                @Override
                public void run() {
                    msgQueueAdapter.notifyDataSetChanged();

                }
            });
            searchText.setClickable(true);
        }

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


        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub

        }
    });

    msgQueueAdapter = new ListAdapter(this, msgQueueList);
    Log.d("list", "List Display - 1" + msgQueueAdapter);

    msgQueueListView = this.getListView();
    msgQueueListView.addHeaderView(searchText);

    setListAdapter(msgQueueAdapter);

Please help me guys...

Ram