创建Android搜索结果列表

时间:2011-10-02 14:18:42

标签: android android-activity android-asynctask listactivity

我正在尝试实现以下逻辑:

用户在文本框(活动)中输入搜索字符串 - >调用Web服务以异步执行搜索 - >搜索结果显示在列表中(另一个活动)

到目前为止,我有以下内容:

活动,输入搜索字符串并点击“搜索”按钮

public class Search extends Activity
{
    // ...
    // called when "Search" button is clicked
    private void runSearch()
    {
        ProgressDialog progressDialog = ProgressDialog.show(
            this, "Search", "Search...");
        searchAsyncTask = new SearchAsyncTask();

        SearchAsyncTaskParam param = new SearchAsyncTaskParam();
        param.SearchString = getSearchCode(); // gets input from text box
        param.ProgressDialog = progressDialog;

        searchAsyncTask.execute(param);
    }
}

然后我有一个类来执行异步搜索

public class SearchAsyncTask extends AsyncTask<SearchAsyncTaskParam,
    Void, SearchAsyncTaskResult> {

    private SearchAsyncTaskParam param;

    @Override
    protected SearchAsyncTaskResult doInBackground(
        SearchAsyncTaskParam... params) {
        if (params.length > 0)
            param = params[0];
        SearchAsyncTaskResult result = new SearchAsyncTaskResult();

        // call Webservice and fill result object with status (success/failed)
        // and a list of hits (each hit contains name, city, etc.)

        return result;
    }

    @Override
    protected void onPostExecute(SearchAsyncTaskResult result) {
        param.ProgressDialog.dismiss();
        if (!result.Success)
            // throw an AlertBox
        else
        {
            // this part is incomplete and doesn't look good, does it?
            // And how would I pass my result data to the new activity?
            Intent intent = new Intent(param.ProgressDialog.getContext(),
                SearchResultList.class);
            param.ProgressDialog.getContext().startActivity(intent);
        }
    }
}

最后一个元素是活动,用于显示包含搜索结果的列表

public class SearchResultList extends ListActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setListAdapter(new ArrayAdapter<String>(
            this, android.R.layout.simple_list_item_1, data));
        // String was only for testing, should be a class with holds the data
        // for each item, i.e. Name, City, etc. And where do I get "data" from?
    }
    // ...
}

现在我的问题

  1. onPostExecute实例的AsyncTask方法中启动结果列表的活动是个好主意吗?我已经用上面描述的简单测试对它进行了测试,它似乎有效。但这是安全的,我是否在正确的线程(UI线程)?如果这是不好的做法,那么启动结果活动的替代方法是什么?

  2. ProgressDialog使用Intent的上下文并启动活动看起来特别奇怪。它只是AsyncTask实例中唯一可用的上下文。这可能是一个问题,因为ProgressDialog已经被解雇了吗?我可以使用哪种上下文?

  3. 如何将结果数据传递到SearchResultList活动?

  4. 如果搜索成功(上述else方法中的onPostExecute个案例),我想用文本框关闭Search个活动,以便按下后退按钮,用户返回主屏幕(搜索活动从中打开),而不是Search活动。这有可能吗?我该怎么做?

1 个答案:

答案 0 :(得分:2)

  1. 是的,因为你在UI线程上。如果您不使用AsyncTask而只是一个简单的线程,那么另一种选择就是。在这种情况下,您将使用Handler通知UI线程工作已完成。这是Asynctask存在的原因之一,因此您不必执行后一版本。

  2.   

    “使用ProgressDialog的上下文看起来特别奇怪   对于意图和开始活动。“

    这根本不奇怪,因为当您创建ProgressDialog时,您传递了搜索的上下文,因此当您检索ProgressDialog的上下文时,您实际上获得了搜索活动的上下文。没问题。

  3. 这取决于您要传递的数据。如果你只是想传递一个字符串数组,你可以这样做:

    String [] data = getData();
    Intent intent = new Intent(param.ProgressDialog.getContext(),
        SearchResultList.class);
    intent.putExtra("key1", data);
    param.ProgressDialog.getContext().startActivity(intent);
    

    然后在SearchResultList活动中你会这样做:

    String [] data = this.getIntent().getStringArrayExtra("key1");
    

    如果您想传递自己的对象,请参阅此问题:How to declare global variables in Android?

  4. 有可能吗?是。在你的情况下,有两种方法可以做到这一点。您可以像我一样,将SearchAsyncTask写为Search类中的内部类,并且只需调用

    Search.this.finish();
    

    如果某些条件成立,或者您可以查看此问题的接受答案:android how to finish an activity from other activity

  5. 祝你好运!