ListView onScroll añadir más elementos

private class getArticles extends AsyncTask<Void, Void, Void> { String url; getArticles(String paramUrl) { this.url = paramUrl; } @Override protected void onPreExecute() { super.onPreExecute(); mProgressDialog = new ProgressDialog(App.this); mProgressDialog.setMessage("Učitavanje artikala..."); mProgressDialog.setIndeterminate(false); mProgressDialog.setCancelable(false); mProgressDialog.show(); } @Override protected Void doInBackground(Void... params) { arraylist = new ArrayList<>(); try { Document document = Jsoup.connect(url).get(); Elements els = document.select("ul.category3 > li"); for (Element el : els) { HashMap<String, String> map = new HashMap<>(); Elements slika = el.select("div.category3-image > a > img"); Elements naslov = el.select("div.category3-text > a.main-headline"); Element datum_noformat = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li").first(); Element datum = datum_noformat.html(datum_noformat.html().replaceAll("Posted ", "")); Elements desc = el.select("div.category3-text > p"); Elements link = el.select("div.category3-text > a.main-headline"); Element br_kom = el.select("div.category3-text > div.headlines-info > ul.headlines-info > li.comments-icon").first(); map.put("naslov", naslov.text()); map.put("datum", datum.text()); map.put("desc", desc.text()); map.put("ikona", slika.attr("src")); map.put("link", link.attr("abs:href")); map.put("brkom", br_kom.text()); arraylist.add(map); } } catch (IOException e) { e.printStackTrace(); } return null; } @Override protected void onPostExecute(Void result) { listview = (ListView) findViewById(R.id.listview); adapter = new ArtikliAdapter(App.this, arraylist); listview.setAdapter(adapter); mProgressDialog.dismiss(); } 

He buscado un montón de códigos para el desplazamiento de lista, pero no sabía cómo aplicarlo. El problema es que, cuando llamo a mi asynctask, tengo un parámetro de url, como new getArticles("http://example.com").execute();

Quiero implementar un listener de onscroll, pero va como esto, mi param se fija generalmente a: http://www.example.com/category/categoryname/ , así que la segunda página va como http://www.example.com/category/categoryname/page/2/ , el tercero va http://www.example.com/category/categoryname/page/3/ y así sucesivamente. Cada página tiene 7 elementos que necesitan ser analizados.

¿Cómo podría implementar onscrolllistener, debido a la url param?

Gracias por adelantado.

Base en este enlace , he escrito siguiente solución para añadir elementos (30 elementos a la vez, es decir, tamaño de página = 30) a listview asincrónicamente.

Cree una clase llamada EndlessListView de la siguiente manera:

 public class EndlessListView extends ListView implements OnScrollListener { private View footer; private boolean isLoading; private EndlessListener listener;// listner private EndlessAdapter endlessAdapter;// adapter. private int maxNoOfElement; public EndlessListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); this.setOnScrollListener(this); } public EndlessListView(Context context, AttributeSet attrs) { super(context, attrs); this.setOnScrollListener(this); } public EndlessListView(Context context) { super(context); this.setOnScrollListener(this); } public void setListener(EndlessListener listener) { this.listener = listener; } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (getAdapter() == null) return; if (getAdapter().getCount() == 0 || getAdapter().getCount() <= 5) return; int l = visibleItemCount + firstVisibleItem; if (l >= totalItemCount && !isLoading) { // It is time to add new data. We call the listener Log.e("LOAD", "DATA"); isLoading = true; listener.loadData(); } } public void setMaxElemnt(int maxNoOfElement) { this.maxNoOfElement = maxNoOfElement; } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } public void setLoadingView(int resId) { LayoutInflater inflater = (LayoutInflater) super.getContext() .getSystemService(Context.LAYOUT_INFLATER_SERVICE); footer = (View) inflater.inflate(resId, null); this.addFooterView(footer); } public void setAdapter(EndlessAdapter adapter) { super.setAdapter(adapter); this.endlessAdapter = adapter; } public void addNewData(List<Integer> data) { endlessAdapter.setData(data); endlessAdapter.notifyDataSetChanged(); isLoading = false; } public static interface EndlessListener { public void loadData(); } } 

Después de esto tenemos que crear el adaptador para él, llamado

EndlessAdapter

 public class EndlessAdapter extends BaseAdapter { private List<Integer> mIntegers; private Context context; public EndlessAdapter(Context context) { this.context = context; } public void setData(List<Integer> mIntegers) { this.mIntegers = mIntegers; } @Override public int getCount() { if (mIntegers == null) return 0; return mIntegers.size(); } @Override public Integer getItem(int index) { if (mIntegers == null) { return null; } else { return mIntegers.get(index); } } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return 0; } class ViewHolder { TextView textView; } @Override public View getView(int index, View view, ViewGroup viewGroup) { ViewHolder holder; if (view == null) { holder = new ViewHolder(); view = ((LayoutInflater) context .getSystemService(Context.LAYOUT_INFLATER_SERVICE)) .inflate(R.layout.rows, viewGroup, false); holder.textView = (TextView) view.findViewById(R.id.mtext); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } holder.textView.setText(getItem(index) + ""); return view; } } 

Ahora en xml de la actividad podríamos usar EndlessListView (en el paquete com.example.stackoverflow) como sigue:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.stackoverflow.EndlessListView android:id="@+id/endlessListView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </RelativeLayout> 

Después de este paso necesitamos hacer el siguiente cambio en MainActivity

  public class MainActivity extends Activity implements EndlessListener { private EndlessAdapter adapter; private EndlessListView endlessListView; private List<Integer> data; private int gStartIndex = 30; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); endlessListView = (EndlessListView) findViewById(R.id.endlessListView); adapter = new EndlessAdapter(this); data = new ArrayList<Integer>(); endlessListView.setLoadingView(R.layout.footer); // endlessListView.showFooter(); endlessListView.setListener(this); endlessListView.setAdapter(adapter); gStartIndex = 0; fillData(gStartIndex); } private void fillData(int startIndex) { new AsyncLoadData().execute(startIndex); } @Override public void loadData() { fillData(gStartIndex); } private class AsyncLoadData extends AsyncTask<Integer, Integer, Void> { @Override protected Void doInBackground(Integer... params) { int gendIndex = params[0] + 30; gStartIndex = gendIndex; /*** * Here you could add your n/w code. To simulate the n/w comm. i am * adding elements to list and making it sleep for few sec. * */ for (int i = params[0]; i < gendIndex; i++) { publishProgress(i); } try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } @Override protected void onProgressUpdate(Integer... values) { super.onProgressUpdate(values); data.add(values[0]); } @Override protected void onPostExecute(Void result) { endlessListView.addNewData(data); } } } 

Este ScrollListView personalizado que acabo de encontrar tiene OnBottomReachedListener que puedes implementar desde tu Activity o Fragment y recibir eventos cuando el usuario toca la parte inferior de la página. También necesitará realizar un seguimiento de la página actual y cuando se pulse la parte inferior para descargar la siguiente página. Los datos más recientes deben agregarse a su ArrayList existente y debe llamar a notifyDataSetChanged() en su adaptador para que ListView pueda procesar los nuevos datos. No tiene que crear un nuevo adaptador, solo necesita actualizar el origen de datos que es su ArrayList .

Si apoya el cambio de orientación, deberá guardar en onSaveInstanceState() su número de página actual, de modo que cuando se recrea la Activity o el Fragment , puede continuar desde la página correcta. Y usted tendría que mantener el origen de datos de ArrayList seguro de los cambios de configuración porque no desea descargarlo de nuevo. Yo sugeriría usar el Fragment con setRetainInstance() establecido en true para persistir ArrayList .

Aquí está mi código personalizado para mantener los datos utilizando RetainFragment:

 /** * A simple non-UI Fragment that stores a single Object * and is retained over configuration changes. */ public class RetainFragment<E extends Object> extends Fragment { /** Object for retaining. */ private E mObject; /** * Empty constructor as per the Fragment documentation */ public RetainFragment() {} @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Make sure this Fragment is retained over a configuration change setRetainInstance(true); } /** * Store a single object in this Fragment. * * @param object The object to store */ public void setObject(E object) { mObject = object; } /** * Get the stored object. * * @return The stored object */ public E getObject() { return mObject; } } 

Ejemplo de uso de RetainFragment en su Activity :

 FragmentManager fm = getFragmentManager(); mRetainFragment = (RetainFragment<ArrayList>) fm.findFragmentByTag(RETAIN_FRAG); if (mRetainFragment == null) { mRetainFragment = new RetainFragment<>(); mRetainFragment.setObject(new ArrayList()); fm.beginTransaction().add(mRetainFragment, RETAIN_FRAG).commit(); } ArrayList yourArrayList = mRetainFragment.getObject(); // Now your ArrayList is saved accrossed configuration changes 

Aquí lo que quieres fist add onscrolllistner to listview

  boolean loading_flage = false; yourlistview.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged( AbsListView view, int scrollState) { // TODO Auto-generated method stub } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { final int lastItem = firstVisibleItem + visibleItemCount; if ((lastItem == totalItemCount) & loading_flage == false) { //this to prevent the list to make more than one request in time loading_flage = true; //you can put the index for your next page here loadMore(int page); } } }); 

Y luego en la carga más después de cargar la página de establecer la carga con el falso y analizar los datos añadir a los datos que aleardy tienen

  //notify the adapter adapter.notifyDataSetChanged(); loading_flage = false; 

Se puede lograr agregando el lista de desplazamiento en listview y verifique la condición si el último elemento visible de la lista es el último de ArrayList y luego llama al asynctask con el número de página incrementado y actualiza el listview, significa que agrega la vista en listview y después de obtener el resultado del servidor remove the Cargando más vista desde el listview como esta – AndroidListViewLoadMoreActivity.java

 public class AndroidListViewLoadMoreActivity extends Activity { ArrayList<Country> countryList; MyCustomAdapter dataAdapter = null; int page = 0; boolean loadingMore = false; View loadMoreView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); ListView listView = (ListView) findViewById(R.id.listView1); loadMoreView = ((LayoutInflater)this .getSystemService(Context.LAYOUT_INFLATER_SERVICE)) .inflate(R.layout.loadmore, null, false); listView.addFooterView(loadMoreView); //create an ArrayAdaptar from the String Array countryList = new ArrayList<Country>(); dataAdapter = new MyCustomAdapter(this, R.layout.country_info, countryList); listView.setAdapter(dataAdapter); //enables filtering for the contents of the given ListView listView.setTextFilterEnabled(true); listView.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // When clicked, show a toast with the TextView text Country country = (Country) parent.getItemAtPosition(position); Toast.makeText(getApplicationContext(), country.getCode(), Toast.LENGTH_SHORT).show(); } }); listView.setOnScrollListener(new OnScrollListener(){ @Override public void onScrollStateChanged(AbsListView view, int scrollState) {} @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { int lastInScreen = firstVisibleItem + visibleItemCount; if((lastInScreen == totalItemCount) && !(loadingMore)){ String url = "http://10.0.2.2:8080/CountryWebService" + "/CountryServlet"; grabURL(url); } } }); String url = "http://example.com"; grabURL(url); } public void grabURL(String url) { Log.v("Android Spinner JSON Data Activity", url); new GrabURL().execute(url); } private class GrabURL extends AsyncTask<String, Void, String> { private static final int REGISTRATION_TIMEOUT = 3 * 1000; private static final int WAIT_TIMEOUT = 30 * 1000; private final HttpClient httpclient = new DefaultHttpClient(); final HttpParams params = httpclient.getParams(); HttpResponse response; private String content = null; private boolean error = false; private ProgressDialog dialog = new ProgressDialog(AndroidListViewLoadMoreActivity.this); protected void onPreExecute() { dialog.setMessage("Getting your data... Please wait..."); dialog.show(); } protected String doInBackground(String... urls) { String URL = null; loadingMore = true; try { URL = urls[0]; HttpConnectionParams.setConnectionTimeout(params, REGISTRATION_TIMEOUT); HttpConnectionParams.setSoTimeout(params, WAIT_TIMEOUT); ConnManagerParams.setTimeout(params, WAIT_TIMEOUT); HttpPost httpPost = new HttpPost(URL); //add name value pair for the country code List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2); nameValuePairs.add(new BasicNameValuePair("page",String.valueOf(page))); httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); response = httpclient.execute(httpPost); StatusLine statusLine = response.getStatusLine(); if(statusLine.getStatusCode() == HttpStatus.SC_OK){ ByteArrayOutputStream out = new ByteArrayOutputStream(); response.getEntity().writeTo(out); out.close(); content = out.toString(); } else{ //Closes the connection. Log.w("HTTP1:",statusLine.getReasonPhrase()); response.getEntity().getContent().close(); throw new IOException(statusLine.getReasonPhrase()); } } catch (ClientProtocolException e) { Log.w("HTTP2:",e ); content = e.getMessage(); error = true; cancel(true); } catch (IOException e) { Log.w("HTTP3:",e ); content = e.getMessage(); error = true; cancel(true); }catch (Exception e) { Log.w("HTTP4:",e ); content = e.getMessage(); error = true; cancel(true); } return content; } protected void onCancelled() { dialog.dismiss(); Toast toast = Toast.makeText(AndroidListViewLoadMoreActivity.this, "Error connecting to Server", Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 25, 400); toast.show(); } protected void onPostExecute(String content) { dialog.dismiss(); Toast toast; if (error) { toast = Toast.makeText(AndroidListViewLoadMoreActivity.this, content, Toast.LENGTH_LONG); toast.setGravity(Gravity.TOP, 25, 400); toast.show(); } else { displayCountryList(content); } } } private void displayCountryList(String response){ JSONObject responseObj = null; try { Gson gson = new Gson(); responseObj = new JSONObject(response); JSONArray countryListObj = responseObj.getJSONArray("countryList"); //countryList = new ArrayList<Country>(); if(countryListObj.length() == 0){ ListView listView = (ListView) findViewById(R.id.listView1); listView.removeFooterView(loadMoreView); } else { for (int i=0; i<countryListObj.length(); i++){ //get the country information JSON object String countryInfo = countryListObj.getJSONObject(i).toString(); //create java object from the JSON object Country country = gson.fromJson(countryInfo, Country.class); //add to country array list countryList.add(country); dataAdapter.add(country); } page++; dataAdapter.notifyDataSetChanged(); loadingMore = false; } } catch (JSONException e) { e.printStackTrace(); } } 

}

Hacer MyCustomAdapter.java como adaptador

 private class MyCustomAdapter extends ArrayAdapter<Country> { private ArrayList<Country> countryList; public MyCustomAdapter(Context context, int textViewResourceId, ArrayList<Country> countryList) { super(context, textViewResourceId, countryList); this.countryList = new ArrayList<Country>(); this.countryList.addAll(countryList); } private class ViewHolder { TextView code; TextView name; TextView continent; TextView region; } public void add(Country country){ Log.v("AddView", country.getCode()); this.countryList.add(country); } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder = null; Log.v("ConvertView", String.valueOf(position)); if (convertView == null) { LayoutInflater vi = (LayoutInflater)getSystemService( Context.LAYOUT_INFLATER_SERVICE); convertView = vi.inflate(R.layout.country_info, null); holder = new ViewHolder(); holder.code = (TextView) convertView.findViewById(R.id.code); holder.name = (TextView) convertView.findViewById(R.id.name); holder.continent = (TextView) convertView.findViewById(R.id.continent); holder.region = (TextView) convertView.findViewById(R.id.region); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } Country country = this.countryList.get(position); holder.code.setText(country.getCode()); holder.name.setText(country.getName()); holder.continent.setText(country.getContinent()); holder.region.setText(country.getRegion()); return convertView; } } } 

Crear País.Java como pojo –

 public class Country { String code = null; String name = null; String continent = null; String region = null; Double lifeExpectancy = null; Double gnp = null; Double surfaceArea = null; int population = 0; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContinent() { return continent; } public void setContinent(String continent) { this.continent = continent; } public String getRegion() { return region; } public void setRegion(String region) { this.region = region; } public Double getLifeExpectancy() { return lifeExpectancy; } public void setLifeExpectancy(Double lifeExpectancy) { this.lifeExpectancy = lifeExpectancy; } public Double getGnp() { return gnp; } public void setGnp(Double gnp) { this.gnp = gnp; } public Double getSurfaceArea() { return surfaceArea; } public void setSurfaceArea(Double surfaceArea) { this.surfaceArea = surfaceArea; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } } 

Crear main.xml para el diseño principal

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10dp" android:text="@string/some_text" android:textSize="20sp" /> <ListView android:id="@+id/listView1" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> 

Crear country_info.xml

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="6dip" > <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:text="Code: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1" android:text="Name: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView2" android:layout_below="@+id/textView2" android:text="Continent: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView3" android:layout_below="@+id/textView3" android:text="Region: " android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/continent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView3" android:layout_alignBottom="@+id/textView3" android:layout_toRightOf="@+id/textView3" android:text="TextView" /> <TextView android:id="@+id/region" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/textView4" android:layout_alignBottom="@+id/textView4" android:layout_alignLeft="@+id/continent" android:text="TextView" /> <TextView android:id="@+id/name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/textView3" android:layout_toRightOf="@+id/textView3" android:text="TextView" /> <TextView android:id="@+id/code" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/textView2" android:layout_alignLeft="@+id/name" android:text="TextView" /> </RelativeLayout> 

Ver texto de pie de página – loadmore.xml

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:gravity="center_horizontal" android:padding="3dp" android:layout_height="fill_parent"> <TextView android:id="@id/android:empty" android:layout_width="wrap_content" android:layout_height="fill_parent" android:gravity="center" android:padding="5dp" android:text="Loading more data..."/> </LinearLayout> 

No olvide mencionar el permiso de Internet con –

 <uses-permission android:name="android.permission.INTERNET" /> 

Primero, necesitas un método OnScrollListener como este:

 private OnScrollListener onScrollListener() { return new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { int threshold = 1; int count = listView.getCount(); if (scrollState == SCROLL_STATE_IDLE) { if (listView.getLastVisiblePosition() >= count - threshold && pageCount < 2) { Log.i(TAG, "loading more data"); // Execute LoadMoreDataTask AsyncTask //It reached ListView bottom getDataFromUrl(url_page2); } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }; } 

listView.setOnScrollListener(onScrollListener()); oyente de desplazamiento de vista de lista por listView.setOnScrollListener(onScrollListener());

Tengo un tutorial completo AQUÍ ! ¡Usted puede visitarlo!

  • ListView haga clic para mostrar la imagen en ImageView
  • Se barajaron las imágenes al desplazar un ListView con un ViewHolder
  • Cómo obtener id de un elemento particular de listview en android?
  • Enumera el alineamiento de elementos con Recycler View
  • Nesting Android ViewPager, Swiping ListItems dentro de un ListView horizontalmente
  • ¿Cómo puedo cambiar el color de fondo de una fila específica correctamente en un ListView? (Androide)
  • EditText con la lista de sugerencias a continuación
  • Android smoothScrollBy se comporta mal
  • Problema en un grupo de vistas personalizado al actualizar ListViews
  • Android: ¿Los elementos de las listas no se vuelven naranjas cuando se hace clic?
  • Android BaseAdapter con Fragmento
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.