无尽滚动的ListView [英] Endless scrolling ListView

查看:93
本文介绍了无尽滚动的ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我填充与来自在线服务,它提供了在页上的数据读取的数据一个ListView。而不是提供下一页按钮,我试图自动加载数据的下一个页面时靠近页面底部的用户滚动。

I am populating a ListView with data fetched from an online service, which provides the data in pages. Rather than providing a 'next page' button, I am attempting to automatically load the next page of data when the user scrolls near the bottom of the page.

取数据时使用的AsyncTask:

Data is fetched using an AsyncTask:

class RecentTracksTask extends AsyncTask<Integer, Void, Void> {

    ArrayList<Track> recentTracks;

    @Override
    protected Void doInBackground(Integer... page) {
        try {
            // Get a page of 15 tracks
            // Simplified - getPage accepts 'page' and 'limit' parameters and returns a Collection<Track>
            recentTracks = new ArrayList<Track>(getPage(page[0], 15));

        } catch () {}

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
            TracksAdapter mTracksAdapter = new TracksAdapter(getActivity(),
                    recentTracks);

            ListView listView = (ListView) getActivity().findViewById(R.id.listview);
            listView.setAdapter(mTracksAdapter);
            listView.setOnScrollListener(new EndlessScrollListener());

    }
}

和适配器:

class TracksAdapter extends ArrayAdapter<Track> {
    private final Context context;
    private final ArrayList<Track> tracks;

    public TracksAdapter(Context context,
                         ArrayList<Track> recentTrackArrayList) {
        super(context, 0, recentTrackArrayList);
        this.context = context;
        this.tracks = recentTrackArrayList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.list_item,
                    parent, false);
        }

        final Track track = tracks.get(position);

        final TextView tv = (TextView) convertView
                .findViewById(R.id.tv);
        // Repeat for other views

        tv.setText(track.getName());
        // Repeat for other views

        return convertView;
    }
}

从这里 ,我已经试过这EndlessScrollListener

From here, I've tried this EndlessScrollListener:

class EndlessScrollListener implements AbsListView.OnScrollListener {

    private int visibleThreshold = 5;
    private int currentPage = 0;
    private int previousTotal = 0;
    private boolean loading = true;

    public EndlessScrollListener() {
    }

    public EndlessScrollListener(int visibleThreshold) {
        this.visibleThreshold = visibleThreshold;
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem,
                         int visibleItemCount, int totalItemCount) {
        if (loading) {
            if (totalItemCount > previousTotal) {
                loading = false;
                previousTotal = totalItemCount;
                currentPage++;
            }
        }
        if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
            // I load the next page of gigs using a background task,
            // but you can call any function here.
            new RecentTracksTask().execute(currentPage + 1);
            loading = true;
        }
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
    }
}

我试图简化了code尽可能不删除任何有用的,但我知道它仍然是一个有点长读通过。

I tried simplifying the code as much as possible without removing anything useful but I know it's still a little long to read through.

在片段的onCreateView,我称之为新RecentTracksTask()执行(1); 成功地加载第15项到ListView中。当附近的ListView的底部滚动,其全部内容被替换为所述第二页面,视图返回到列表的顶部。重复这个动作只是我到列表的顶部,还是显示第二页。

In the fragment's onCreateView, I call new RecentTracksTask().execute(1); which successfully loads the first 15 items into the ListView. When scrolling near the bottom of the ListView, the entire contents are replaced with the second page, and the view is returned to the top of the list. Repeating this just moves me to the top of the list, still displaying the second page.


  • 我怎样才能得到它,使项目的第N个页面插在列表的底部,而不是替换列表?

  • 我怎么能阻止它从视图移动到列表的顶部?

在此先感谢!

推荐答案

首先,摆脱EndlessScrollListener的。然后,更新的AsyncTask获取数据,将其附加到的已在使用的适配器,并通知所述数据集变化的适配器。最后,在适配器中,添加一个检查,因为如果你到达列表的末尾并请求下一个页面。我要提醒你,但是,你要保持跟踪你的异步任务和prevent它从你滚动最后一个视图到位,同时它已经被加载重新创建。

First, get rid of the EndlessScrollListener. Then, update your AsyncTask to fetch the data, append it to the already-in-use adapter, and notify the adapter of the data set change. Finally, in your adapter, add a check for if you reach the end of the list and request the next page. I should warn you, however, that you'll want to keep track of your async task and prevent it from being recreated if you scroll the last view into place while it's already loading.

的AsyncTask

AsyncTask

class RecentTracksTask extends AsyncTask<Integer, Void, Void> {

    ArrayList<Track> recentTracks;

    @Override
    protected Void doInBackground(Integer... page) {
        try {
            // Get a page of 15 tracks
            // Simplified - getPage accepts 'page' and 'limit' parameters and returns a Collection<Track>
            recentTracks = new ArrayList<Track>(getPage(page[0], 15));

        } catch () {}

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        ListView listView = (ListView) getActivity().findViewById(R.id.listview);
        ArrayAdapter adapter = (ArrayAdapter) listView.getAdapter();
        if(adapter == null) {
            adapter = new TracksAdapter(getActivity(), recentTracks);
            listView.setAdapter(adapter);
        } else {
            adapter.addAll(recentTracks);
            adapter.notifyDataSetChanged();
        }
    }
}

适配器:

class TracksAdapter extends ArrayAdapter<Track> {
    private final Context context;
    private final ArrayList<Track> tracks;
    private int currentPage = 0;

    public TracksAdapter(Context context,
                         ArrayList<Track> recentTrackArrayList) {
        super(context, 0, recentTrackArrayList);
        this.context = context;
        this.tracks = recentTrackArrayList;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.list_item,
                    parent, false);
        }

        final Track track = tracks.get(position);

        final TextView tv = (TextView) convertView
                .findViewById(R.id.tv);
        // Repeat for other views

        tv.setText(track.getName());
        // Repeat for other views

        //Check if we're at the end of the list
        if(position == getCount() - 1) {
            currentPage++;
            new RecentTracksTask().execute(currentPage);
        }

        return convertView;
    }
}

这篇关于无尽滚动的ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆