Android infinite Scroll List view
Asked Answered
O

4

7

I want to implement OnScrollListener to load more data, when scrolled to bottom, dynamically. Following code is giving me NullPointerException, but when I declare

  BusinessListDataAdapter adapter = new BusinessListDataAdapter(this,
            this.imgFetcher, this.layoutInflator, this.businesses);

inside setBusiness, it doesn't show any error and works fine. Problem with this is when I scroll to the bottom of page it replaces current data in list view with new data but what I wanted is endless scrolling while appending new data instead of replacing so that I can view first data scrolling up

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);
        }
    }

}

Here is 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)
Osteomalacia answered 17/10, 2014 at 9:6 Comment(3)
possible duplicate of Android - ListView to load more items when reached endImprobity
I've attached logcatOsteomalacia
java.lang.NullPointerException at com.sp.sodhpuch.adapters.BusinessListDataAdapter.getCount(BusinessListDataAdapter.java:53) - Check BusinessListDataAdapter.java, line 53Eckhart
U
0

You need to do three things.

1) Create Method which will add ten more items to adapter list.

2) Add xml that contain button in listview footer.

3) Then write clickListener for that button in activity or fragment class in which you call step 1 method and then just reset the listview adapter.

Unmuzzle answered 17/10, 2014 at 9:11 Comment(0)
I
0

From Android - ListView to load more items when reached end

You can add a footer on the listView which will have a button named LoadMore. Here is a complete tutorial List With Load more Or you can implement onscrolllistener() and add this listener to your 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();
    }
}
}
Improbity answered 17/10, 2014 at 9:18 Comment(1)
My problem is not implementing load more or OnScrollListener. OnScrollListener is working but newly fetched data replaces the previous data on the list, what I want is append newer data to append below current dataOsteomalacia
W
0

Hi @carefree here is a solution which might get you exactly what you want to achieve https://github.com/rahulinaction/ImageGrid

Wideopen answered 8/4, 2015 at 5:28 Comment(1)
you can take reference from github.com/androidcodes/Surviving-with-androidUlrikeulster
W
0

The problem most likely to be with your task and adapter not with list scrolling. You can implement a method, addItems, in your listAdapter as follows:

    public void addItems(BusniessListData... newItems){
        for(BusniessListData newItem : newItems){
            this.businesses.add(newItem);
        }           
        notifyDataSetChanged();
    }

In onPostExecute of your task, or whatever callback you use, check if listAdapter has items, then call addItems passing it newly fetched items. Otherwise, initiate and populate fetched data-set.

Women answered 28/9, 2015 at 18:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.