我如何创建一个列表,当你到达列表的末尾时,我会收到通知,这样我就可以加载更多的项目?
当前回答
我知道这是一个老问题,Android世界已经大部分转移到RecyclerViews,但对于任何感兴趣的人来说,你可能会发现这个库非常有趣。
它使用与ListView一起使用的BaseAdapter来检测列表何时已经滚动到最后一项或何时正在从最后一项滚动出去。
它附带了一个示例项目(只有100行活动代码),可以用来快速理解它是如何工作的。
简单的用法:
class Boy{
private String name;
private double height;
private int age;
//Other code
}
一个用于保存Boy对象的适配器看起来像这样:
public class BoysAdapter extends EndlessAdapter<Boy>{
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(parent
.getContext());
holder = new ViewHolder();
convertView = inflater.inflate(
R.layout.list_cell, parent, false);
holder.nameView = convertView.findViewById(R.id.cell);
// minimize the default image.
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Boy boy = getItem(position);
try {
holder.nameView.setText(boy.getName());
///Other data rendering codes.
} catch (Exception e) {
e.printStackTrace();
}
return super.getView(position,convertView,parent);
}
注意BoysAdapter的getView方法如何返回对EndlessAdapter超类的getView方法的调用。这是100%必要的。
现在要创建适配器,请执行以下操作:
adapter = new ModelAdapter() {
@Override
public void onScrollToBottom(int bottomIndex, boolean moreItemsCouldBeAvailable) {
if (moreItemsCouldBeAvailable) {
makeYourServerCallForMoreItems();
} else {
if (loadMore.getVisibility() != View.VISIBLE) {
loadMore.setVisibility(View.VISIBLE);
}
}
}
@Override
public void onScrollAwayFromBottom(int currentIndex) {
loadMore.setVisibility(View.GONE);
}
@Override
public void onFinishedLoading(boolean moreItemsReceived) {
if (!moreItemsReceived) {
loadMore.setVisibility(View.VISIBLE);
}
}
};
loadMore项是一个按钮或其他ui元素,可以单击它从url中获取更多数据。 当按照代码中描述的位置放置时,适配器确切地知道何时显示该按钮,何时禁用该按钮。只需在xml中创建按钮,并按照上面适配器代码所示的方式放置它。
享受。
其他回答
一种解决方案是实现OnScrollListener,并在ListAdapter的onScroll方法中以方便的状态对其进行更改(如添加项目等)。
下面的ListActivity显示了一个整数列表,从40开始,当用户滚动到列表末尾时添加项。
public class Test extends ListActivity implements OnScrollListener {
Aleph0 adapter = new Aleph0();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(adapter);
getListView().setOnScrollListener(this);
}
public void onScroll(AbsListView view,
int firstVisible, int visibleCount, int totalCount) {
boolean loadMore = /* maybe add a padding */
firstVisible + visibleCount >= totalCount;
if(loadMore) {
adapter.count += visibleCount; // or any other amount
adapter.notifyDataSetChanged();
}
}
public void onScrollStateChanged(AbsListView v, int s) { }
class Aleph0 extends BaseAdapter {
int count = 40; /* starting amount */
public int getCount() { return count; }
public Object getItem(int pos) { return pos; }
public long getItemId(int pos) { return pos; }
public View getView(int pos, View v, ViewGroup p) {
TextView view = new TextView(Test.this);
view.setText("entry " + pos);
return view;
}
}
}
显然,对于长时间运行的操作(如加载web-data),您应该使用单独的线程,并可能希望在最后一个列表项中指示进度(如市场或gmail应用程序)。
你可以在onScrollListener的帮助下检测列表的结尾,工作代码如下:
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if (view.getAdapter() != null && ((firstVisibleItem + visibleItemCount) >= totalItemCount) && totalItemCount != mPrevTotalItemCount) {
Log.v(TAG, "onListEnd, extending list");
mPrevTotalItemCount = totalItemCount;
mAdapter.addMoreData();
}
}
另一种方法(内部适配器)如下所示:
public View getView(int pos, View v, ViewGroup p) {
if(pos==getCount()-1){
addMoreData(); //should be asynctask or thread
}
return view;
}
注意,这个方法将被多次调用,因此需要添加另一个条件来阻止多次调用addMoreData()。
当你将所有元素添加到列表中时,请在适配器中调用notifyDataSetChanged()来更新视图(它应该在UI线程runOnUiThread上运行)
到目前为止,我见过的最好的解决方案是在FastAdapter库中用于回收器视图。它有一个EndlessRecyclerOnScrollListener。
下面是一个示例用法:EndlessScrollListActivity
一旦我使用它无休止的滚动列表,我已经意识到设置是一个非常强大的。我强烈推荐。
可能有点晚了,但下面的解决方案在我的情况下非常有用。 在某种程度上,所有你需要做的是添加到你的ListView页脚,并为它创建addOnLayoutChangeListener。
http://developer.android.com/reference/android/widget/ListView.html addFooterView (android.view.View)
例如:
ListView listView1 = (ListView) v.findViewById(R.id.dialogsList); // Your listView
View loadMoreView = getActivity().getLayoutInflater().inflate(R.layout.list_load_more, null); // Getting your layout of FooterView, which will always be at the bottom of your listview. E.g. you may place on it the ProgressBar or leave it empty-layout.
listView1.addFooterView(loadMoreView); // Adding your View to your listview
...
loadMoreView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
Log.d("Hey!", "Your list has reached bottom");
}
});
当页脚可见时,此事件会触发一次,效果非常好。
我知道这是一个老问题,Android世界已经大部分转移到RecyclerViews,但对于任何感兴趣的人来说,你可能会发现这个库非常有趣。
它使用与ListView一起使用的BaseAdapter来检测列表何时已经滚动到最后一项或何时正在从最后一项滚动出去。
它附带了一个示例项目(只有100行活动代码),可以用来快速理解它是如何工作的。
简单的用法:
class Boy{
private String name;
private double height;
private int age;
//Other code
}
一个用于保存Boy对象的适配器看起来像这样:
public class BoysAdapter extends EndlessAdapter<Boy>{
ViewHolder holder = null;
if (convertView == null) {
LayoutInflater inflater = LayoutInflater.from(parent
.getContext());
holder = new ViewHolder();
convertView = inflater.inflate(
R.layout.list_cell, parent, false);
holder.nameView = convertView.findViewById(R.id.cell);
// minimize the default image.
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Boy boy = getItem(position);
try {
holder.nameView.setText(boy.getName());
///Other data rendering codes.
} catch (Exception e) {
e.printStackTrace();
}
return super.getView(position,convertView,parent);
}
注意BoysAdapter的getView方法如何返回对EndlessAdapter超类的getView方法的调用。这是100%必要的。
现在要创建适配器,请执行以下操作:
adapter = new ModelAdapter() {
@Override
public void onScrollToBottom(int bottomIndex, boolean moreItemsCouldBeAvailable) {
if (moreItemsCouldBeAvailable) {
makeYourServerCallForMoreItems();
} else {
if (loadMore.getVisibility() != View.VISIBLE) {
loadMore.setVisibility(View.VISIBLE);
}
}
}
@Override
public void onScrollAwayFromBottom(int currentIndex) {
loadMore.setVisibility(View.GONE);
}
@Override
public void onFinishedLoading(boolean moreItemsReceived) {
if (!moreItemsReceived) {
loadMore.setVisibility(View.VISIBLE);
}
}
};
loadMore项是一个按钮或其他ui元素,可以单击它从url中获取更多数据。 当按照代码中描述的位置放置时,适配器确切地知道何时显示该按钮,何时禁用该按钮。只需在xml中创建按钮,并按照上面适配器代码所示的方式放置它。
享受。
推荐文章
- 在应用程序本身中更改Locale
- 如何循环通过所有但最后一项的列表?
- apk (.apk)和应用程序包(.aab)的区别
- 如何设置超时在改造库?
- Android - SPAN_EXCLUSIVE_EXCLUSIVE跨度不能为零长度
- TextView的字体大小在Android应用程序改变字体大小从本机设置
- 如何模拟Android杀死我的进程
- 禁用EditText闪烁光标
- Android Eclipse -无法找到*.apk
- 设置TextView文本从html格式的字符串资源在XML
- 如何允许所有网络连接类型HTTP和HTTPS在Android(9)馅饼?
- 如何克隆或复制一个列表在kotlin
- Android加载JS包失败
- Android Studio, logcat在应用程序关闭后清理
- 在android中从上下文获取活动