java - 让 AutoCompleteTextView 响应 SimpleAdapter 中的更改

标签 java android autocompletetextview simpleadapter

我是 Android 新手,正在尝试使用 AutoCompleteTextView 和不同的适配器。让它与 ArrayAdapter ( discussed here ) 一起工作后,我现在正在尝试使用两个 AsyncTasks 链进行相同的操作。我在其他地方看到过这种方法的几个例子,我认为它比尝试在线程之间同步数据更整洁。它还允许我保留每个项目的 K,V HashMap ,因此希望我可以在单击此应用程序下一阶段的建议时提取项目 ID。

在这种方法下,我再次努力让 View 根据建议进行更新。除了我在编辑框中输入的内容之外,什么也没有出现。这是 UI 线程和 AsyncTask 链之间的计时问题吗?或者也许我在适配器/ View 绑定(bind)中犯了一个错误?

注意:我已经尝试过使用 autoComplete.setAdapter(adapter);在 ParserTask onPostExecute() 方法中应用。这也不起作用。

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();
        }
    }
}

最佳答案

好吧 - 听起来令人难以置信,但似乎将 setAdapter() 方法移回到 postExecute 并保持 notifyDataSetChanged() 就位,该死的东西正在工作!

(下一步是找出可能使用 Intent/bundle/fragment 的 AutoCompleteTextView 点击事件..哇!)

这是最终的工作代码:

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();
        }
    }
} 

关于java - 让 AutoCompleteTextView 响应 SimpleAdapter 中的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15581677/

相关文章:

android - 一直调用 AutoCompleteTextView 的 performFiltering

java - 除了互斥锁或垃圾收集之外还有哪些机制可以减慢我的多线程 Java 程序的速度?

java - Java 设计模式 : Does this look familiar to anyone?

java - 将树结构解析为关系型数据存储

android - 如何使用改造将图像发送到服务器

Android:自定义 SeekBar 图层列表未按预期工作

android AutoCompleteTextView 白色上的白色下拉列表

java - Gson格式输出Json

android - 无法转换 com.google.gson.internal.LinkedTreeMap

android - 如何使用具有完成阈值的 MaterialAutoCompleteTextView