简体   繁体   中英

Load more items and add bottom to the list when scroll down in android

I tried to implement for adding more items to my adapter but its refreshing every time instead of adding new items to bottom of the list.I searched through the internet but i didn't get the solution Here is my code:

 import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.AbsListView;
    import android.widget.BaseAdapter;
    import android.widget.ListView;
    import android.widget.TextView;

    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.util.ArrayList;
    import java.util.Calendar;
    public class MainActivity extends AppCompatActivity {
        private DataListAdapter dataListAdapter;
        Activity _activity;
        ArrayList<DataObject> dataArrayList;
        private ListView lv;
        private String jsonResult;
        boolean loadingMore = false;
        private DataObject dataObject;
        private static final String TAG = MainActivity.class.getSimpleName();
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            _activity = this;
            lv = (ListView) findViewById(R.id.listView1);
            View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.loading_view, null, false);
            this.lv.addFooterView(footerView);

            if (isOnline(_activity)) {
    new LoadJsonData().execute();
    scrollNotifyChange();
    }

        }

        private void scrollNotifyChange() {
            lv.setOnScrollListener(new AbsListView.OnScrollListener() {

                @Override
                public void onScrollStateChanged(AbsListView view, int scrollState) {
                }

                @Override
                public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

                    //what is the bottom item that is visible
                    int lastInScreen = firstVisibleItem + visibleItemCount;

                    //is the bottom item visible & not loading more already? Load more!
                    if ((lastInScreen == totalItemCount) && !(loadingMore)) {

    //                    //start a new thread for loading the items in the list
                       Thread thread = new Thread(null, loadMoreListItems);
                        thread.start();

                    }
                }
            });


        }
        private Runnable loadMoreListItems = new Runnable() {

            @Override
            public void run() {

                //Set flag so we cant load new items 2 at the same time
                loadingMore = true;

                //Reset the array that holds the new items

                //Simulate a delay, delete this on a production environment!
                try {
                    Thread.sleep(1000);

                } catch (InterruptedException e) {
                }
                jsonResult = doInBackground();

                runOnUiThread(returnRes);
            }
        };
        private Runnable returnRes = new Runnable() {

            @Override
            public void run() {
                onPostExecute(jsonResult);
                loadingMore = false;
            }

        };

        public String doInBackground() {
            String jsonResult = "";
    //            jsonResult=get("https://datatables.net/examples/server_side/scripts/server_processing.php");
    //            return jsonResult;
            InputStream inputStream = null;
            String result = "";
            try {
                HttpClient httpclient = new DefaultHttpClient();
                HttpGet request = new HttpGet("https://datatables.net/examples/server_side/scripts/server_processing.php");

                HttpResponse httpResponse = httpclient.execute(request);
                inputStream = httpResponse.getEntity().getContent();
                if (inputStream != null) {
                    jsonResult = convertInputStreamToString(inputStream);
                } else {
                    jsonResult = "Did not work!";
                }
            } catch (Exception e) {
                Log.e(TAG, "GET failed", e);
            }

            return jsonResult;
        }

        public void onPostExecute(String result) {
            try {
    //            progress.dismiss();
                dataArrayList = new ArrayList<DataObject>();
                JSONObject dataJsontObject = new JSONObject(result);
                JSONArray dataJsonArray = dataJsontObject.getJSONArray("data");
                for (int i = 0; i < dataJsonArray.length(); i++) {
                    JSONArray dataSubArray = dataJsonArray.getJSONArray(i);

                    dataObject = new DataObject();
                    dataObject.setName((String) dataSubArray.get(0));
                    dataObject.setType((String) dataSubArray.get(1));
                    dataObject.setProfession((String) dataSubArray.get(2));
                    dataObject.setCountry((String) dataSubArray.get(3));
                    dataObject.setCurrency((String) dataSubArray.get(5));
                    dataArrayList.add(dataObject);
                }
                dataListAdapter = new DataListAdapter(dataArrayList);
                dataListAdapter.add(dataObject);
    //            lv.setAdapter(dataListAdapter);
    //            dataListAdapter.add(dataObject);
                dataListAdapter.notifyDataSetChanged();
                lv.setAdapter(dataListAdapter);
                lv.smoothScrollToPosition(dataListAdapter.getCount());

            } catch (JSONException e) {
                e.printStackTrace();
            }

        }

        public static boolean isOnline(Context context) {
            ConnectivityManager cm =
                    (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            return netInfo != null && netInfo.isConnectedOrConnecting();
        }

        private class LoadJsonData extends AsyncTask<Void, Void, String> {
            ProgressDialog progress;


            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                progress = ProgressDialog.show(_activity, "Progress",
                        "Please wait", true);


            }

            @Override
            protected String doInBackground(Void... params) {
                String jsonResult = "";
    //            jsonResult=get("https://datatables.net/examples/server_side/scripts/server_processing.php");
    //            return jsonResult;
                InputStream inputStream = null;
                String result = "";
                try {
                    HttpClient httpclient = new DefaultHttpClient();
                    HttpGet request = new HttpGet("https://datatables.net/examples/server_side/scripts/server_processing.php");

                    HttpResponse httpResponse = httpclient.execute(request);
                    inputStream = httpResponse.getEntity().getContent();
                    if (inputStream != null) {
                        jsonResult = convertInputStreamToString(inputStream);
                    } else {
                        jsonResult = "Did not work!";
                    }
                } catch (Exception e) {
                    Log.e(TAG, "GET failed", e);
                }

                return jsonResult;
            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);
                try {

                    progress.dismiss();
                    if(loadingMore)
                    {
    //                    listViwe.removeFooterView(loadingFooter);
                        loadingMore = false;
                    }
                    dataArrayList = new ArrayList<DataObject>();
                    JSONObject dataJsontObject = new JSONObject(result);
                    JSONArray dataJsonArray = dataJsontObject.getJSONArray("data");
                    for (int i = 0; i < dataJsonArray.length(); i++) {
                        JSONArray dataSubArray = dataJsonArray.getJSONArray(i);

                        DataObject dataObject = new DataObject();
                        dataObject.setName((String) dataSubArray.get(0));
                        dataObject.setType((String) dataSubArray.get(1));
                        dataObject.setProfession((String) dataSubArray.get(2));
                        dataObject.setCountry((String) dataSubArray.get(3));
                        dataObject.setCurrency((String) dataSubArray.get(5));
                        dataArrayList.add(dataObject);
                    }
                    dataListAdapter = new DataListAdapter(dataArrayList);
                    lv.setAdapter(dataListAdapter);
                    dataListAdapter.notifyDataSetChanged();


                } catch (JSONException e) {
                    e.printStackTrace();
                    if(loadingMore)
                    {
    //                    listViwe.removeFooterView(loadingFooter);
                        loadingMore = false;
                    }
                }

            }
        }

        public class DataListAdapter extends BaseAdapter {
            ArrayList<DataObject> dataListObject = new ArrayList<DataObject>();

            public DataListAdapter(ArrayList<DataObject> dataListObject) {
                this.dataListObject = dataListObject;
            }

            @Override
            public int getCount() {
                return dataListObject.size();
            }

            @Override
            public Object getItem(int position) {
                return dataListObject.get(position);
            }

            @Override
            public long getItemId(int position) {
                return position;
            }


            public void add(DataObject dataObject){
    //            Log.v("AddView", country.getCode());
                this.dataListObject.add(dataObject);
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder = null;
                if (convertView == null) {
                    LayoutInflater inflater = LayoutInflater.from(_activity);
                    convertView = inflater.inflate(R.layout.single_row, null);
                    holder = new ViewHolder();
                    holder.name = (TextView) convertView.findViewById(R.id.name);
                    holder.type = (TextView) convertView.findViewById(R.id.type);
                    holder.profession = (TextView) convertView.findViewById(R.id.profession);
                    holder.country = (TextView) convertView.findViewById(R.id.country);
                    holder.currency = (TextView) convertView.findViewById(R.id.currecy);
                    convertView.setTag(holder);
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
                final DataObject current = dataListObject.get(position);
                holder.name.setText("Name--" + current.getName());
                holder.type.setText("Type--" + current.getType());
                holder.profession.setText("Professoion--" + current.getProfession());
                holder.country.setText("Country--" + current.getCountry());
                holder.currency.setText("Currency--" + current.getCurrency());
                return convertView;

            }

        }

        static class ViewHolder {

            TextView name;
            TextView type;
            TextView profession;
            TextView country;
            TextView currency;


        }

        public static String convertInputStreamToString(InputStream inputStream) throws IOException {
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = "";
            String result = "";
            while ((line = bufferedReader.readLine()) != null) {
                result += line;
            }
            inputStream.close();
            return result;
        }

    }

AsyncTask spawns a new intelligent thread on its own, runs things in background and also posts results of UI thread in onPostExecute method.

You should not call the methods of AsyncTask on your own. Android does it by itself. Instead of calling a new thread in scrollchangelistener,like:

Thread thread = new Thread(null, loadMoreListItems);

call

new LoadJsonData().execute();

you don't need two Runnable threads to do the same thing your asyncTask does.

The problem is this code of yours:

          dataListAdapter = new DataListAdapter(dataArrayList);
          lv.setAdapter(dataListAdapter);

Every time your scrolling reaches the end, it eventually calls the onPostExecute method to post results on the UI. But here you are making a new Adapter eveytime with a new dataset which is why it always refreshes the whole list.

Remove this part and set it inside onCreate of your Activity.Add new values to your adapter's datalist in onPostExecute. Then just do a notifyDataSetChanged inside onPostExecute of your AsyncTask.

you need to create an adapter inside onCreate method

like this:

ArrayList<DataObject> list;
onCreate() {
 list=new ArrayList(); 
 ListAdapter dataListAdapter =new ListAdapter(list) // creating an adapter with empty list of data
 listView.setAdpater(adpater);
}

then, in onPostExceute() method : add data to the ArrayList and notifythe adapter like this:

onPostExecute(){ 
 ....
 .....
 list.add(dataObject);  //here you can add 'n' number of object to the list
 dataListAdapter.notifyDataSetChanged(); //  notify the adapter to update the listview 
 .....
}

EDIT : I updated this answer as per @user3422948 request

   DataListAdapter dataListAdapter;
   ArrayList<DataObject> dataArrayList;
   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        _activity = this;

        //edit: declare your arraylist and adapter here
        dataArrayList = new ArrayList<DataObject>();
        dataListAdapter = new DataListAdapter(dataArrayList);


        lv = (ListView) findViewById(R.id.listView1);
        View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.loading_view, null, false);
        this.lv.addFooterView(footerView);

        if (isOnline(_activity)) {
            new LoadJsonData().execute();
            scrollNotifyChange();
        }

    }
    ......
    ....... 

    public void onPostExecute(String result) {
        try {
//            progress.dismiss();
            //dataArrayList = new ArrayList<DataObject>(); //edit 
            JSONObject dataJsontObject = new JSONObject(result);
            JSONArray dataJsonArray = dataJsontObject.getJSONArray("data");
            for (int i = 0; i < dataJsonArray.length(); i++) {
                JSONArray dataSubArray = dataJsonArray.getJSONArray(i);

                dataObject = new DataObject();
                dataObject.setName((String) dataSubArray.get(0));
                dataObject.setType((String) dataSubArray.get(1));
                dataObject.setProfession((String) dataSubArray.get(2));
                dataObject.setCountry((String) dataSubArray.get(3));
                dataObject.setCurrency((String) dataSubArray.get(5));
                dataArrayList.add(dataObject);
            }
            //edit: your creating new adapter for every execution
            //dataListAdapter = new DataListAdapter(dataArrayList);
            //dataListAdapter.add(dataObject);
//            lv.setAdapter(dataListAdapter);
//            dataListAdapter.add(dataObject);
            dataListAdapter.notifyDataSetChanged();
            //lv.setAdapter(dataListAdapter);
            lv.smoothScrollToPosition(dataListAdapter.getCount());

        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

the problem is for every execution you are creating new Adapter

you should see this link how to use notifyDataSetChanged in listView

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM