3

I use an ArrayList and an ArrayAdapter to log down the contents of AutoCompleteTextView, and I want to dynamically refresh the AutoCompleteTextView when the list is modified. The modification of the list is triggered in a webviewClient.

However, my code doesn't work. The AutoCompleteTextView can only be updated when the whole activity is reloaded. There is no dynamic update at all. Could anyone help me to find out what was wrong?

    final ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, mHistory); //mHistory is the list of data
    adapter.setNotifyOnChange(true);
    mEditText1.setAdapter(adapter); //mEditText1 is the AutoCompleteTextView

    mWebView1.setWebViewClient(new WebViewClient() {

        public void onPageFinished(WebView view, String url){
            super.onPageFinished(view, url);

            if (!mHistory.contains(mWebView1.getUrl())){
                mHistory.add(mWebView1.getUrl());
                writeList(view.getContext(), mHistory, "history");  //this is to store the list elsewhere
            }
            adapter.notifyDataSetChanged();

        }

    });         
user1731839
  • 125
  • 2
  • 9

2 Answers2

6

I would like to suggest you to try NOT to modify your list mHistory, but instead modify your ArrayAdapter by using add(), clear() and so on.

adapter.add(mWebView1.getUrl());

Also if that wont help, you could try creating your own custom adapter instead of default ArrayAdapter. You could force filtering when you want by having public function callFiltering Custom adapter could be something like this:

public class CustomArrayAdapter extends ArrayAdapter<String> implements
        Filterable {
    private List<String> list;
    private CustomFilter customFilter;

    public CustomArrayAdapter(Context context, int textViewResourceId) {
        super(context, textViewResourceId);
        list = new ArrayList<String>();
    }

    @Override
    public void add(String object) {
        list.add(object);
        notifyDataSetChanged();
    }

    @Override
    public void clear() {
        list.clear();
    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public String getItem(int position) {
        return list.get(position);
    }

    @Override
    public CustomFilter getFilter() {
        if (customFilter == null) {
            customFilter = new CustomFilter();
        }
        return customFilter;
    }

    public void callFiltering(String term) {
        customFilter.performFiltering(term);
    }

    private class CustomFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            if (constraint != null) {
                results.values = list;
                results.count = list.size();
            }
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {
            if (results != null && results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

    }

}
-2

if you add the line:

adapter = new ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, mHistory);

before adapter.notifyDataSetChanged();, it should work.

As far as I know ArrayAdapter takes in a List (mHistory in your case) and calls it something like mOriginalValues. Then creates it's own list from mOriginalValues by filtering it according to what's typed in the ACTV, which it then diplays.

adapter.notifyDataSetChanged() refers to the filtered list, not the the mOriginalValues. So you must make a new adapter and feed it the new list.

Smern
  • 18,746
  • 21
  • 72
  • 90
ShanieMoonlight
  • 1,623
  • 3
  • 17
  • 28