简体   繁体   English

在android中向下滚动时,加载更多项目并在列表底部添加底部

[英]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. AsyncTask自己产生一个新的智能线程,在后台运行事物,并在onPostExecute方法中发布UI线程的结果。

You should not call the methods of AsyncTask on your own. 您不应自己调用AsyncTask的方法。 Android does it by itself. Android自行完成。 Instead of calling a new thread in scrollchangelistener,like: 而不是在scrollchangelistener中调用新线程,例如:

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. 您不需要两个Runnable线程即可完成asyncTask要做的同一件事。

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. 每次滚动结束时,它最终都会调用onPostExecute方法将结果发布到UI上。 But here you are making a new Adapter eveytime with a new dataset which is why it always refreshes the whole list. 但是在这里,您正在使用新的数据集进行新的Adapter eveytime,这就是为什么它总是刷新整个列表的原因。

Remove this part and set it inside onCreate of your Activity.Add new values to your adapter's datalist in onPostExecute. 删除此部分并将其设置在Activity的onCreate中。在onPostExecute中将新值添加到适配器的数据列表中。 Then just do a notifyDataSetChanged inside onPostExecute of your AsyncTask. 然后,只需在AsyncTask的onPostExecute内执行notifyDataSetChanged即可。

you need to create an adapter inside onCreate method 您需要在onCreate方法中创建一个适配器

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: 然后,在onPostExceute()方法中:将数据添加到ArrayList中,并像这样通知适配器:

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 编辑:我根据@ user3422948请求更新了此答案

   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 您应该看到此链接如何在listView中使用notifyDataSetChanged

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android-如何在滚动视图中使用列表视图加载更多项目? - Android-How to Load more items using list view inside scroll view? Android:保存ListView项目并加载/添加更多内容 - Android: Saving ListView items and load/add more 当用户尝试向下滚动时,如何在列表底部实现刷新? - How to implement refresh at the bottom of the list when user try to scroll down? ListView-滚动加载更多项目 - ListView - Load more items with scroll 在列表视图中向下滚动时如何加载更多项目? - How can I load more items when scrolling down in listview? 将项目添加到JavaFX时滚动到tableview的底部 - JavaFX scroll to bottom of tableview when items are added to it Android sqlite 数据库 - 如何显示列表视图在滚动末尾添加“加载更多项目” - Android sqlite database - how to show listview adding “Load more items” at the end of scroll 当我向下滚动时,滚动以在recyclerview中添加项目总是自动显示在顶部 - on scrolled to add items in recyclerview always comes to top automatically when i scroll down 首先将ListView项目添加到列表底部 - Add ListView items to bottom of list first Android recyclerview向上滚动加载更多数据 - Android recyclerview load more data on scroll up
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM