无尽的滚动监听器
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<Item> 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();
【讨论】:
以上是关于无尽的滚动监听器的主要内容,如果未能解决你的问题,请参考以下文章