Android infinite Scroll List view

carefree picture carefree · Oct 17, 2014 · Viewed 11.5k times · Source

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)

Answer

Danial Hussain picture Danial Hussain · Oct 17, 2014

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.