Android无限滚动列表视图
Posted
技术标签:
【中文标题】Android无限滚动列表视图【英文标题】:Android infinite Scroll List view 【发布时间】:2014-12-12 20:01:57 【问题描述】:我想实现OnScrollListener
以在滚动到底部时动态加载更多数据。以下代码给了我 NullPointerException,但是当我声明
BusinessListDataAdapter adapter = new BusinessListDataAdapter(this, this.imgFetcher, this.layoutInflator, this.businesses);
在setBusiness
内部,它没有显示任何错误并且工作正常。问题是当我滚动到页面底部时,它会用新数据替换 list view
中的当前数据,但我想要的是在附加新数据而不是替换时无限滚动,以便我可以查看第一个向上滚动的数据
import java.util.ArrayList;
import com.sp.sodhpuch.adapters.BusinessListDataAdapter;
import com.sp.sodhpuch.data.BusinessListData;
import com.sp.sodhpuch.tasks.BusinessListApiTask;
import com.sp.sodhpuch.tasks.BusinessListIconTask;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class ListResultActivity extends Activity
private ArrayList<BusinessListData> businesses;
private ListView businessList;
private LayoutInflater layoutInflator;
private BusinessListIconTask imgFetcher;
BusinessListDataAdapter adapter = new BusinessListDataAdapter(this,
this.imgFetcher, this.layoutInflator, this.businesses);
@SuppressWarnings("unchecked")
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.businesslist);
getData();
// @SuppressWarnings("deprecation")
// final Object[] data = (Object[]) getLastNonConfigurationInstance();
// if (data != null)
// setContentView(R.layout.businesslist);
// this.businessList = (ListView) findViewById(R.id.lvBusinesslist);
// this.imgFetcher = new BusinessListIconTask(this);
// this.layoutInflator = LayoutInflater.from(this);
//
// this.businesses = (ArrayList<BusinessListData>) data[0];
// this.imgFetcher = (BusinessListIconTask) data[1];
// businessList.setAdapter(adapter);
//
@Override
public Object onRetainNonConfigurationInstance()
Object[] myStuff = new Object[2];
myStuff[0] = this.businesses;
myStuff[1] = this.imgFetcher;
return myStuff;
/**
* Bundle to hold refs to row items views.
*
*/
public static class MyViewHolder
public TextView businessName, businessAddress, phoneNo;
public Button btnProfile;
public ImageView icon;
public BusinessListData business;
public void setBusinesses(ArrayList<BusinessListData> businesses)
this.businessList = (ListView) findViewById(R.id.lvBusinesslist);
this.imgFetcher = new BusinessListIconTask(this);
this.layoutInflator = LayoutInflater.from(this);
this.businesses = businesses;
this.businessList.setAdapter(adapter);
businessList.setOnScrollListener(new OnScrollListener()
public void onScrollStateChanged(AbsListView view, int scrollState)
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount)
if (businessList.getLastVisiblePosition() == totalItemCount - 1)
getData();
// adapter.notifyDataSetChanged();
);
private void getData()
// TODO Auto-generated method stub
Intent myIntent = getIntent();
// gets the arguments from previously created intent
String metroTxt = myIntent.getStringExtra("key");
String metroLoc = myIntent.getStringExtra("loc");
String metroId = myIntent.getStringExtra("qt");
BusinessListApiTask spTask = new BusinessListApiTask(
ListResultActivity.this);
try
spTask.execute(metroTxt, metroLoc, metroId);
catch (Exception e)
spTask.cancel(true);
这里是logcat
10-17 04:50:51.897: W/dalvikvm(6942): threadid=1: thread exiting with uncaught exception (group=0xb1d41b20)
10-17 04:50:51.897: E/AndroidRuntime(6942): FATAL EXCEPTION: main
10-17 04:50:51.897: E/AndroidRuntime(6942): Process: com.sp.sodhpuch, PID: 6942
10-17 04:50:51.897: E/AndroidRuntime(6942): java.lang.NullPointerException
10-17 04:50:51.897: E/AndroidRuntime(6942): at com.sp.sodhpuch.adapters.BusinessListDataAdapter.getCount(BusinessListDataAdapter.java:53)
10-17 04:50:51.897: E/AndroidRuntime(6942): at android.widget.ListView.setAdapter(ListView.java:480)
10-17 04:50:51.897: E/AndroidRuntime(6942): at com.sp.sodhpuch.ListResultActivity.setBusinesses(ListResultActivity.java:78)
10-17 04:50:51.897: E/AndroidRuntime(6942): at com.sp.sodhpuch.tasks.BusinessListApiTask.onPostExecute(BusinessListApiTask.java:119)
10-17 04:50:51.897: E/AndroidRuntime(6942): at com.sp.sodhpuch.tasks.BusinessListApiTask.onPostExecute(BusinessListApiTask.java:1)
10-17 04:50:51.897: E/AndroidRuntime(6942): at android.os.AsyncTask.finish(AsyncTask.java:632)
10-17 04:50:51.897: E/AndroidRuntime(6942): at android.os.AsyncTask.access$600(AsyncTask.java:177)
10-17 04:50:51.897: E/AndroidRuntime(6942): at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
10-17 04:50:51.897: E/AndroidRuntime(6942): at android.os.Handler.dispatchMessage(Handler.java:102)
10-17 04:50:51.897: E/AndroidRuntime(6942): at android.os.Looper.loop(Looper.java:136)
10-17 04:50:51.897: E/AndroidRuntime(6942): at android.app.ActivityThread.main(ActivityThread.java:5017)
10-17 04:50:51.897: E/AndroidRuntime(6942): at java.lang.reflect.Method.invokeNative(Native Method)
10-17 04:50:51.897: E/AndroidRuntime(6942): at java.lang.reflect.Method.invoke(Method.java:515)
10-17 04:50:51.897: E/AndroidRuntime(6942): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
10-17 04:50:51.897: E/AndroidRuntime(6942): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
10-17 04:50:51.897: E/AndroidRuntime(6942): at dalvik.system.NativeStart.main(Native Method)
【问题讨论】:
Android - ListView to load more items when reached end 的可能重复项 我已经附上了logcat java.lang.NullPointerException at com.sp.sodhpuch.adapters.BusinessListDataAdapter.getCount(BusinessListDataAdapter.java:53) - 检查 BusinessListDataAdapter.java,第 53 行 【参考方案1】:你需要做三件事。
1) 创建将向适配器列表添加十个项目的方法。
2) 在列表视图页脚中添加包含按钮的 xml。
3) 然后在调用步骤 1 方法的活动或片段类中为该按钮编写 clickListener,然后只需重置列表视图适配器。
【讨论】:
【参考方案2】:来自Android - ListView to load more items when reached end
您可以在 listView 上添加一个页脚,该页脚将有一个名为 LoadMore 的按钮。这是一个完整的教程List With Load more 或者您可以实现 onscrolllistener() 并将此侦听器添加到您的 ListView
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
public void onScrollStateChanged(AbsListView view, int scrollState)
this.currentScrollState = scrollState;
this.isScrollCompleted();
private void isScrollCompleted()
if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE)
/*** In this way I detect if there's been a scroll which has completed ***/
/*** do the work for load more date! ***/
if(!isLoading)
isLoading = true;
loadMoreData();
【讨论】:
我的问题是没有实现加载更多或 OnScrollListener。 OnScrollListener 正在工作,但新获取的数据替换了列表中的先前数据,我想要的是追加新数据以追加到当前数据下方【参考方案3】:嗨@carefree,这是一个解决方案,它可能会为您提供您想要实现的目标 https://github.com/rahulinaction/ImageGrid
【讨论】:
可以参考github.com/androidcodes/Surviving-with-android【参考方案4】:问题最有可能出在您的任务和适配器上,而不是列表滚动。 您可以在您的 listAdapter 中实现一个方法 addItems,如下所示:
public void addItems(BusniessListData... newItems)
for(BusniessListData newItem : newItems)
this.businesses.add(newItem);
notifyDataSetChanged();
在您的任务的 onPostExecute 或您使用的任何回调中,检查 listAdapter 是否有项目,然后调用 addItems 将新获取的项目传递给它。否则,启动并填充获取的数据集。
【讨论】:
以上是关于Android无限滚动列表视图的主要内容,如果未能解决你的问题,请参考以下文章
Android 高级UI设计笔记09:Android如何实现无限滚动列表
使用 Jetpack Compose 无限加载 Android Paging 3 库而无需滚动