如何只需点击一下即可显示搜索结果?

时间:2015-05-09 00:33:27

标签: java android android-asynctask

我正在创建一个Android应用,它具有搜索在线数据库的搜索功能。当我想要搜索某些内容时,我必须双击搜索按钮才能显示正确的结果。我相信问题在于我在按钮的onClick中使用了Asynctask函数。这是我的onClick:

public void onSearchClick(View view) throws TVDBOutboundConnectionException {
    ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
    if (networkInfo != null && networkInfo.isConnected()) {
        // fetch data
        new SeriesSearchTask().execute(text.getText().toString());
    } else {
        // display error
    }

    final ListView listview = (ListView) findViewById(R.id.listview);

    final ArrayList<String> list = new ArrayList<String>();
    for (int i = 0; i < ALTS.size(); i++) {
        list.add(ALTS.get(i).getSeriesName());
    }
    final StableArrayAdapter adapter = new StableArrayAdapter(this,
            android.R.layout.simple_list_item_1, list);
    listview.setAdapter(adapter);

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, final View view,
                                int position, long id) {
            final String item = (String) parent.getItemAtPosition(position);
            view.animate().setDuration(2000).alpha(0)
                    .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            list.remove(item);
                            adapter.notifyDataSetChanged();
                            view.setAlpha(1);
                        }
                    });
        }

    });

}

这是我的Asynctask方法:

private class SeriesSearchTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        // params comes from the execute() call: params[0] is the url.
        try {
            ALTS = DB.searchSeriesInTVDB(urls[0], Language.ENGLISH);
            return Integer.toString(ALTS.size());
        } catch (TVDBOutboundConnectionException e) {
            return "Unable to retrieve web page. URL may be invalid.";
        }
    }
    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {
    }
}

所以我的问题是如何让方法在一次搜索点击上显示正确的结果,因为这是正常的和预期的。感谢任何帮助,并提前感谢您的努力。

1 个答案:

答案 0 :(得分:0)

您面临的问题是AsyncTask的工作原理。 AsyncTask中的代码在一个单独的线程上运行,因此之后的行会在AsyncTask完成工作之前立即执行

要在AsyncTask完成后更新UI,您需要在onPostExecute()方法中执行代码。

然后将代码移到自己的方法中:

public void updateUi(){
    final ListView listview = (ListView) findViewById(R.id.listview);

    final ArrayList<String> list = new ArrayList<String>();

    for (int i = 0; i < ALTS.size(); i++) {
        list.add(ALTS.get(i).getSeriesName());
    }

    final StableArrayAdapter adapter = new StableArrayAdapter(this,
      android.R.layout.simple_list_item_1, list);
    listview.setAdapter(adapter);

    //...
}

然后将Activity切换到AsyncTask并在执行后在UI线程上运行此方法。

private class SeriesSearchTask extends AsyncTask<String, Void, String> {
    MyActivity mActivity;

    public SeriesSearchTask(final MyActivity _activity){
        mActivity = _activity;
    }

    @Override
    protected String doInBackground(String... urls) {
        // params comes from the execute() call: params[0] is the url.
        try {
            ALTS = DB.searchSeriesInTVDB(urls[0], Language.ENGLISH);
            return Integer.toString(ALTS.size());
        } catch (TVDBOutboundConnectionException e) {
            return "Unable to retrieve web page. URL may be invalid.";
        }
    }

    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {

        //updating the UI here
        if(mActivity != null){
            mActivity.runOnUiThread(new Runnable(){
                public void run(){
                    mActivity.updateUi();
                }
            }
        }

    }
}

更好的解决方案是使用像Otto之类的事件总线来通知活动。查看他们的网站,这是非常直接的。