Android:AutoCompleteTextView listview滚动监听器(用于无限滚动)

时间:2015-03-26 10:48:42

标签: android listview autocompletetextview



我使用 AutoCompleteTextView 让我的Android应用用户使用自定义网络服务搜索内容:它按预期工作但是,目前我还不能找到一种方法来实现" Endless Scrolling"在下拉列表视图中。

现在,我的AutoCompleteTextView适配器是一个实现可过滤接口的ArrayAdapter;每当用户更改AutoCompleteTextView的文本时,我的过滤器的 performFiltering()方法都会被触发,我可以向我的自定义Web服务发出HTTP请求以显示适当的内容。但是我希望在用户滚动下拉列表时加载更多内容,这是一个分页系统,所以我可以避免一次加载数百个结果......我无法想象如何!

  • 如何获取与AutoCompleteTextView关联的ListView 实现我自己的OnScrollListener / EndlessScrollListener?
  • 还有其他方法吗?

谢谢你们:)

我的片段代码

AutoCompleteTextView search = (AutoCompleteTextView) view.findViewById(R.id.search);

SearchAdapter searchAdapter = new SearchAdapter(getActivity(), 0);

search.setAdapter(searchAdapter);

我的适配器代码(已修改)

class SearchAdapter extends ArrayAdapter<Parcelable> implements Filterable {

    Integer numberPerPage = 10;
    Boolean moreDataIsAvailable = false;

    FragmentActivity activity;
    public ArrayList<Parcelable> items = new ArrayList<Parcelable>();

    public SearchAdapter(FragmentActivity a, int textViewResourceId) {
        super(a, textViewResourceId);
        activity = a;
    }

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

    @Override
    public Parcelable getItem(int index) {
        if(items.size() > index) {
            return items.get(index);
        } else {
            return null;
        }
    }

    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();
                if (constraint != null && constraint.toString().length() >= 3) {
                    autocomplete(constraint.toString(), items);
                    filterResults.count = items.size();
                    filterResults.values = items;
                } else {
                    items.clear();
                    filterResults.count = items.size();
                    filterResults.values = items;
                }
                return filterResults;
            }

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

    static class ViewHolder {
    }

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

        ViewHolder holder = null;

        View rowView = convertView;

        if (rowView == null) {

            rowView = LayoutInflater.from(activity).inflate(R.layout.search_row, parent, false);
            holder = new ViewHolder();
            rowView.setTag(holder);

        } else {

            holder = (ViewHolder) rowView.getTag();

        }

        // Setting my row data

        return rowView;

    }

    private void autocomplete(String input, ArrayList<Parcelable> items) {

        ArrayList<Parcelable> data = new ArrayList<Parcelable>();

        try {

            RequestHandler request = new RequestHandler();

            JSONObject requestParameters = new JSONObject();
            requestParameters.put("offset", 0);
            requestParameters.put("keyword", input);
            requestParameters.put("limit", numberPerPage);

            ResponseDescription response = request.request(activity, requestParameters);

            if(!response.error) {

                JSONArray searchedItems = response.getJSONArray("items");

                if(searchedItems.length() == numberPerPage) {
                    moreDataIsAvailable = true;
                } else {
                    moreDataIsAvailable = false;
                }

                for(int i = 0 ; i < searchedItems.length(); i++) {

                    JSONObject searchedItem = searchedItems.getJSONObject(i);

                    MyObject object = new MyObject();
                    object.initWithJSONObject(searchedItem);
                    data.add(object);

                }
            }

        } catch (Exception e) {

            e.printStackTrace();

        }

        items.clear();
        items.addAll(data);

    }

}

1 个答案:

答案 0 :(得分:3)

不幸的是,没有OnScrollListener自动完成界面,但我认为你可以解决这个问题。

以下是我认为的配方:

  • 为您的autocomplete方法添加另一个参数参数以进行偏移。

我注意到你有&#39; 0&#39;硬编码的偏移量。您希望能够使用该值调用autocomplete。此外,您在items.clear()的末尾有autocomplete,并且当偏移量为零时,您只想要这样做。

  • 为自动填充方法设置AsyncTask

除了autocomplete中的performFiltering方法之外,您还可以在后台运行Filter。此异步任务需要访问您的适配器,以便它可以将结果添加到items列表,并像过滤器一样调用notifyDataSetChanged()

您的适配器需要保留对此任务的引用,以便您可以在用户再次开始键入时取消它。

  • getView()添加一些逻辑以执行异步任务。

我们没有OnScrollListener因此我们会使用getView()作为代理。

设置启动下一个请求的常量阈值。它需要小于numberPerPage,所以让我们说&#39; 5&#39;举个例子。

现在,当ListView调用getView()的位置在距离结尾的阈值范围内时,执行异步任务。例如,在第一次过滤操作后,列表中有10个项目。当ListView请求项目5的视图时,启动异步任务,其偏移量等于列表大小 - 在本例中为10(获取项目11-20)。

我的基础是假设ListView只会请求项目视图&amp;当用户向下滚动到该项目时。

  • performFiltering()中,取消所有正在运行的异步任务。

我做过这种&#34;无休止的&#34;滚动,ListViewAsyncTask调用OnScrollListener以逐页返回搜索结果,我认为对我有用的是请求响应包含总大小,因此我能够将其用于getCount()

我还使用了自动填充来获取远程结果,但我没有必要对这些结果进行分页。事实上,我认为我只是在输入改变并且我的过滤方法是无操作时运行了异步任务。

您可以将自动填充和分页结合使用。如果用户在异步任务可以更新之前到达列表末尾,则可能会因滚动下拉列表而出现一些卡顿行为。因此,您可能需要使用页面大小,阈值甚至getCount()的返回值来获得可接受的滚动体验。但我认为这是可行的。