无尽的滚动监听器

Posted

技术标签:

【中文标题】无尽的滚动监听器【英文标题】:Endless Scroll Listener 【发布时间】:2015-09-20 16:59:39 【问题描述】:

我是 Java 新手,我正在阅读有关列表视图的信息,所以 如果我是对的,如果列表视图有数千个项目,它将消耗设备的内存,以避免我应该创建一个滚动监听器,每次已经加载了 x 个项目时,它会加载更多的项目。对吧?

我找到了这段代码,我正在尝试使用它,但是在我尝试实现它并设置 onLoadMOre 的主要活动中,我不知道该怎么做。

public abstract class EndlessScrollListener implements AbsListView.OnScrollListener 
    // The minimum amount of items to have below your current scroll position
    // before loading more.
    private int visibleThreshold = 5;
    // The current offset index of data you have loaded
    private int currentPage = 0;
    // The total number of items in the dataset after the last load
    private int previousTotalItemCount = 0;
    // True if we are still waiting for the last set of data to load.
    private boolean loading = true;
    // Sets the starting page index
    private int startingPageIndex = 0;

    public EndlessScrollListener() 
    

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

    public EndlessScrollListener(int visibleThreshold, int startPage) 
        this.visibleThreshold = visibleThreshold;
        this.startingPageIndex = startPage;
        this.currentPage = startPage;
    

    // This happens many times a second during a scroll, so be wary of the code you place here.
    // We are given a few useful parameters to help us work out if we need to load some more data,
    // but first we check if we are waiting for the previous load to finish.
    @Override
    public void onScroll(AbsListView view,int firstVisibleItem,int visibleItemCount,int totalItemCount)
    
        // If the total item count is zero and the previous isn't, assume the
        // list is invalidated and should be reset back to initial state
        if (totalItemCount < previousTotalItemCount) 
            this.currentPage = this.startingPageIndex;
            this.previousTotalItemCount = totalItemCount;
            if (totalItemCount == 0)  this.loading = true; 
        
        // If it’s still loading, we check to see if the dataset count has
        // changed, if so we conclude it has finished loading and update the current page
        // number and total item count.
        if (loading && (totalItemCount > previousTotalItemCount)) 
            loading = false;
            previousTotalItemCount = totalItemCount;
            currentPage++;
        

        // If it isn’t currently loading, we check to see if we have breached
        // the visibleThreshold and need to reload more data.
        // If we do need to reload some more data, we execute onLoadMore to fetch the data.
        if (!loading && (totalItemCount - visibleItemCount)<=(firstVisibleItem + visibleThreshold)) 
            onLoadMore(currentPage + 1, totalItemCount);
            loading = true;
        
    

    // Defines the process for actually loading more data based on page
    public abstract void onLoadMore(int page, int totalItemsCount);

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) 
        // Don't take any action on changed
    

我的代码:

public class MainActivity extends ActionBarActivity implements EndlessScrollListener

    List<Paises> paisesList = new ArrayList<Paises>();
    EditText j_search;

    ListView j_listview;

    String[] j_paises;
    String[] j_nota;

  PaisesAdapter j_adapter;


    int[] j_flags  =
            
                    R.drawable.flag_brazil,
                    R.drawable.flag_bolivia,
                    R.drawable.flag_argentina,
                    R.drawable.flag_chile,
                    R.drawable.flag_colombia,
                    R.drawable.flag_equador,
                    R.drawable.flag_france,
                    R.drawable.flag_guyana,
                    R.drawable.flag_paraguay,
                    R.drawable.flag_peru,
                    R.drawable.flag_suriname,
                    R.drawable.flag_uruguay,
                    R.drawable.flag_venezuela

            ;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        j_paises = getResources().getStringArray(R.array.r_arrayPais);
        j_nota = getResources().getStringArray(R.array.r_arrayNota);

        j_listview = (ListView)findViewById(R.id.l_lView);
        j_search = (EditText)findViewById(R.id.l_searchView);

        j_adapter = new PaisesAdapter(this, paisesList);


        j_adapter.notifyDataSetChanged();
        j_listview.setAdapter(j_adapter);
        j_listview.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);


        int i = 0;
        for(String paises : j_paises)
        
            Paises dataProvider = new Paises(j_flags[i], paises, j_nota[i]);
            j_adapter.add(dataProvider);
            i++;
        

        Collections.sort(paisesList, new AbcComparator());

        j_listview.setTextFilterEnabled(true);
        j_search.addTextChangedListener(new TextWatcher() 
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) 

            

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) 
                System.out.println("Text ["+s+"]");
                j_adapter.getFilter().filter(s.toString());
            

            @Override
            public void afterTextChanged(Editable s) 

            
        );
    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    


    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in androidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) 
            return true;
        

        return super.onOptionsItemSelected(item);
    

    @Override
    public void onLoadMore(int page, int totalItemsCount) 

    



【问题讨论】:

你不知道onLoadMore应该做什么?? 是的,我不知道我应该放什么。 onLoadMore你应该得到一组新的数据并把它放入适配器中,并调用Adapter.notifyDataSetChanged刷新数据。你找到它的示例代码了吗? 所以我应该使用 asyncTask 来填充我的适配器并将其恢复为 onLoadmore? 【参考方案1】:

在这种情况下,您需要处理存储在适配器中的项目。 适配器是处理模型列表(项目、数据)的适配器。

假设你的适配器

扩展ArrayAdapter 有一个 getter/setter 来更新其项目列表MyAdapter.getItems()/setItems(List&lt;Item&gt; newItems)

并且您有一个参考可以使用您的适配器或列表视图,然后

@Override
public void onLoadMore(int page, int totalItemsCount) 
    // download or fetch next page(s) items, then add them to your adapter list
    List<Item> newPageOfItems = .....;

    // if list view reference, cast and get a reference to your adapter
    MyAadapter myAdapter = (MyAdapter) listView.getAdapter();

    if (newPageOfItems != null && !newPageOfItems.isEmpty()) 
        List<Item> currentItems = myAdapter.getItems();
        currentItems.addAll(newPageOfItems);
        currentItems.setItems(currentItems);
        // if for some reason new page is not updated properly, uncomment below
        // myAdapter.notifyDataSetChanged();
    

【讨论】:

以上是关于无尽的滚动监听器的主要内容,如果未能解决你的问题,请参考以下文章

如何用js监听滚动条滚动事件?

如何用js监听滚动条滚动事件

js监听两个滚动条,JavaScript、Html

JS原生监听滚动条

两种监听页面滚动的方法

js如何监听屏幕滚动到底了