6

これはListViewのスクロールに関する質問ではないと言って始めましょう。ユーザーがリストの一番下までスクロールしたことを知る方法を知りたくないので、その質問に対する回答を提供したり、これを重複としてマークしたりしないでください。

AsyncTaskLoader を拡張するクラスを使用して、Web サービスからのデータを ListView に入力しています。

最初に、50 個のアイテムをロードしましたが、すべてうまく機能しています。次の 50 個のアイテムを段階的にロードするようローダーに指示する方法を知る必要があります。ListViewコードでこれを行う場所は理解していますが、データをリセットしてすべてを再度ロードすることなく、より多くのデータをロードしたいことをローダーに伝える最良の方法がわかりません。

繰り返しますが、明確にするために、ここで解決しようとしている問題は、より多くのデータをロードする必要があることをローダーに通知することです。loadInBackground() が 2 回目に呼び出されたときにさらにデータをロードする方法を既に認識しており、ListView はローダーに通知する場所/タイミングを既に認識しています

関連するコードの一部:

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    super.onActivityCreated(savedInstanceState);

    m_adapter = new SearchAdapter(getActivity());
    setListAdapter(m_adapter);

    // if the loader doesn't already exist, one will be created
    // otherwise the existing loader is reused so we don't have
    // to worry about orientation and other configuration changes
    getLoaderManager().initLoader(SEARCH_LOADER_ID, null, this);
}

@Override
public Loader<List<Result>> onCreateLoader(int id, Bundle args)
{
    String query = args != null ? args.getString(QUERY_KEY) : "";
    return new SearchLoader(getActivity(), query);
}

private class SearchAdapter extends ArrayAdapter<Result>
{
    // ...

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {

        // ...

        if (position == getCount() - 2)
            // TODO: Need to notify Loader here

        // ...
    }
}

private static class SearchLoader extends OurAsyncTaskLoader<List<Result>>
{
    public SearchLoader(Context context, String query)
    {
        super(context);

        m_query = query;
        m_data = Lists.newArrayList();
        m_loadedAllResults = false;
    }

    @Override
    public List<Result> loadInBackground()
    {
        if (m_loadedAllResults)
            return m_data;

        // the Loader implementation does a == check rather than a .equals() check
        // on the data, so we need this to be a new List so that it will know we have
        // new data
        m_data = Lists.newArrayList(m_data);

        MyWebService service = new MyWebService();
        List<Result> results = service.getResults(m_query, m_data.size(), COUNT);
        service.close();

        if (results == null)
            return null;

        if (results.size() < COUNT)
            m_loadedAllResults = true;

        for (Result result : results)
            m_data.add(result)

        return m_data;
    }

    private static final int COUNT = 50;

    private final String m_query;

    private boolean m_loadedAllResults;
    private List<Result> m_data;
}
4

2 に答える 2

3

私はうまくいく方法を考え出しました。私のSearchAdapter#getView()方法では、次のコードがあります。

private class SearchAdapter extends ArrayAdapter<Result>
{
    // ...

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {

        // ...

        if (position == getCount() - 2)
            getLoaderManager().getLoader(SEARCH_LOADER_ID).onContentChanged();
        // ...
    }
}

これが「ベストプラクティス」の方法であるかどうかはまだ知りたいのですが、今のところ私の問題は解決しているようです。

于 2013-06-06T18:52:09.767 に答える