In MainActivity I create the DownloadTask which populate model class then listview via CustomListAdapter class but I created the function to recognize end of scroll and I want to load more items to the listview. I was reading and looking at code on internet but I can't figure it out to solve this because its a kind different. The MainActivity class
public void updateList() {
adap = new CustomListAdapter(this, feedList, null);
feedListView.setAdapter(adap);
feedListView.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view,
int scrollState) { // TODO Auto-generated method stub
int threshold = 1;
int count = feedListView.getCount();
if (scrollState == SCROLL_STATE_IDLE) {
if (feedListView.getLastVisiblePosition() >= count
- threshold) {
mHandler = new Handler();
mIsLoading = true;
Toast.makeText(getApplicationContext(), "END", Toast.LENGTH_LONG).show();
}
}
}
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
}
});
}
public class DownloadFilesTask extends AsyncTask<String, Integer, Void> {
@Override
protected void onProgressUpdate(Integer... values) {
}
@Override
protected void onPostExecute(Void result) {
if (null != feedList) {
updateList();
}
if (progressbar.isShown()) {
progressbar.setVisibility(View.INVISIBLE);
}
}
@Override
protected Void doInBackground(String... params) {
String url = params[0];
// getting JSON string from URL
JSONObject json = getJSONFromUrl(url);
//parsing json data
parseJson(json);
return null;
}}
public JSONObject getJSONFromUrl(String url) {
InputStream is = null;
JSONObject jObj = null;
String json = null;
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
public void parseJson(JSONObject json) {
try {
// parsing json object
if (json.getString("status").equalsIgnoreCase("ok")) {
JSONArray posts = json.getJSONArray("posts");
feedList = new ArrayList<FeedItem>();
for (int i = 0; i < posts.length(); i++) {
JSONObject post = (JSONObject) posts.getJSONObject(i);
FeedItem item = new FeedItem();
/////.....
feedList.add(item);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
CustomListAdapter
public class CustomListAdapter extends BaseAdapter
{
private int mCount = 25;
private ArrayList<FeedItem> listData;
private LayoutInflater layoutInflater;
private Context mContext;
private ArrayList<String> data;
protected ListView feedListView;
public CustomListAdapter( Context context, ArrayList<FeedItem> listData)
{
this.listData = listData;
layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContext = context;
}
public void addMoreItems(int count) {
mCount += count;
notifyDataSetChanged();
}
@Override
public int getCount()
{
return mCount;
}
@Override
public Object getItem(int position)
{
return position;
}
@Override
public long getItemId(int position)
{
return position;
}
public View getView( int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
View row=convertView;
if ((row == null) || (row.getTag()==null)) {
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
////
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
final FeedItem newsItem = (FeedItem) listData.get(position);
/////
return convertView;
}
static class ViewHolder
{
////
}
}
When I reach the bottom the toast is created.
Instead of using OnScrollListener, you can compare position to list data size and load more items accordingly within your adapter class.
public View getView( int position, View convertView, ViewGroup parent){
if(position == getCount()-1){
// load new items here. you can do a for loop here, if you'd like to add multiple items.
addMoreItems(newItem);
}
// rest of the getView implementation
}
And you also need to update the following methods:
public void addMoreItems(FeedItem newItem) {
listData.add(newItem); // since you want to add this item at the end of the list
notifyDataSetChanged();
}
@Override
public int getCount(){
return listData.size();
}
@Override
public Object getItem(int position){
return listData.get(position);
}
And don't create a new adapter when you want to update your listView, like you did in your update method. If you do that, it'll get rid of the previous content. Instead, just call addMoreItems method of your adapter, it'll do the trick for you.
@Override
public void onScrollStateChanged(int scrollState) {
// TODO Auto-generated method stub
if(scrollState==RecyclerView.SCROLL_STATE_IDLE){
visibleItemCount = mLayoutManager.getChildCount();
totalItemCount = mLayoutManager.getItemCount();
firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
if (loading) {
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
}
}
if (!loading && (totalItemCount - visibleThreshold) <= (firstVisibleItem + visibleItemCount)) {
Log.v("scroll","Last Item Wow !");
if(footerView.getVisibility()!=View.VISIBLE){
footerView.setVisibility(View.VISIBLE);
}
refreshExpListViewData();
}
}
}
A very simple way to implement "endless scrolling" is to use the EndlessAdapter
library by commonsguy.
来源:https://stackoverflow.com/questions/21029327/listview-load-more-on-scroll-bottom