Android usando GridView con OnScrollListener

Estoy construyendo un gridview que contiene un montón de imágenes probablemente alrededor de 1000 ++ imágenes. Para reducir el tiempo de carga para el gridview, quiero implementar un onScrollListener usando AbsListView. Voy a limitar 20 imágenes por vista, y luego cuando el desplazamiento llega a fondo se cargarán otras 20 imágenes. Esto se repetirá hasta que se hayan cargado todas las imágenes.

He estado googling muestras, pero no parece encontrar uno que se adapte a mis códigos. ¿Podría alguien por favor me guía cómo se hace? Actualmente utilizo imagévelador Lazylist para mis imágenes. También estoy usando AsyncTask.

MainGridView.class

public class MainGridView extends SherlockActivity { private ProgressDialog pDialog; ArrayList<HashMap<String, String>> songsList; static final String KEY_SONG = "song"; static final String KEY_ID = "id"; static final String KEY_TITLE = "title"; static final String KEY_ARTIST = "artist"; static final String KEY_CAT_ARTIST = "artistcat"; static final String KEY_DURATION = "duration"; static final String KEY_THUMB_URL = "thumb_url"; static final String KEY_BIG_URL = "big_url"; static final String KEY_CAT_URL = "cat_url"; static String IMAGE_POSITION; GridView grid; MainGridViewLazyAdapter adapter; String cat_url; String artist_url; private int visibleThreshold = 5; private int currentPage = 0; private int previousTotal = 0; private boolean loading = true; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gridview_main); getSupportActionBar().setDisplayHomeAsUpEnabled(true); checkInternetConnection(); grid = (GridView) findViewById(R.id.grid_view); grid.setOnScrollListener(new OnScrollListener() { @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // TODO Auto-generated method stub if (loading) { if (visibleItemCount > totalItemCount) { loading = false; previousTotal = totalItemCount; currentPage++; } } if (!loading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) { // I load the next page of gigs using a background task, // but you can call any function here. new loadGridView().execute(currentPage + 1); loading = true; } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub } }); } public class loadGridView extends AsyncTask<Integer, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); pDialog = new ProgressDialog(MainGridView.this); pDialog.setTitle("Connect to Server"); pDialog.setMessage("This process can take a few seconds to a few minutes, depending on your Internet Connection Speed."); pDialog.setIndeterminate(false); pDialog.setCancelable(false); pDialog.show(); } @Override protected String doInBackground(Integer... args) { // updating UI from Background Thread Intent in = getIntent(); songsList = new ArrayList<HashMap<String, String>>(); cat_url = in.getStringExtra(KEY_CAT_URL); artist_url = in.getStringExtra(KEY_CAT_ARTIST); XMLParser parser = new XMLParser(); String xml = parser.getXmlFromUrl(cat_url); // getting XML from URL Document doc = parser.getDomElement(xml); // getting DOM element NodeList nl = doc.getElementsByTagName(KEY_SONG); // looping through all song nodes <song> for (int i = 0; i < nl.getLength(); i++) { // creating new HashMap HashMap<String, String> map = new HashMap<String, String>(); Element e = (Element) nl.item(i); // adding each child node to HashMap key => value map.put(KEY_ID, parser.getValue(e, KEY_ID)); map.put(KEY_TITLE, parser.getValue(e, KEY_TITLE)); map.put(KEY_ARTIST, parser.getValue(e, KEY_ARTIST)); map.put(KEY_DURATION, parser.getValue(e, KEY_DURATION)); map.put(KEY_THUMB_URL, parser.getValue(e, KEY_THUMB_URL)); map.put(KEY_BIG_URL, parser.getValue(e, KEY_BIG_URL)); // adding HashList to ArrayList songsList.add(map); } return null; } @Override protected void onPostExecute(String args) { ActionBar ab = getSupportActionBar(); ab.setTitle(artist_url); adapter=new MainGridViewLazyAdapter(MainGridView.this, songsList); grid.setAdapter(adapter); pDialog.dismiss(); } } 

Supongo que quieres cargar imágenes de Urls. Para ello, puede utilizar esta solución: Carga de imágenes perezosa en ListView

Para controlar su paginación usando onScrollListener , creo que desea ver el ejemplo de desplazamiento sin fin . Este es un ejemplo simplista, pero lo único que tienes que añadir es un cheque si has llegado al último elemento de tu xml.

Dentro de su AsyncTask (llamado en cada nueva carga), sólo analizar un poco de datos de su xml (correspondiente a 20 elementos en su caso). Este es un ejemplo de uso basado en su código:

 public class MainGridView extends SherlockActivity implements OnScrollListener { public static final String KEY_SONG = "song"; public static final String KEY_ID = "id"; public static final String KEY_TITLE = "title"; public static final String KEY_ARTIST = "artist"; public static final String KEY_CAT_ARTIST = "artistcat"; public static final String KEY_DURATION = "duration"; public static final String KEY_THUMB_URL = "thumb_url"; public static final String KEY_BIG_URL = "big_url"; public static final String KEY_CAT_URL = "cat_url"; private final static int ITEMS_PPAGE = 20; private ProgressDialog mDialog; private ArrayList<HashMap<String, String>> mSongsList; private static String IMAGE_POSITION; private GridView mGridView; //MainGridViewLazyAdapter mAdapter; private ArrayAdapter<String> mAdapter; private String cat_url; private String artist_url; private int mVisibleThreshold = 5; private int mCurrentPage = 0; private int mPreviousTotal = 0; private boolean mLoading = true; private boolean mLastPage = false; private String mXml; @Override public void onCreate(Bundle savedInstanceState) { setTheme(SherlockBarUtils.getCurrentTheme(this)); super.onCreate(savedInstanceState); setContentView(R.layout.gridview_main); getSupportActionBar().setDisplayHomeAsUpEnabled(true); //checkInternetConnection(); mGridView = (GridView) findViewById(R.id.grid_view); mGridView.setOnScrollListener(this); mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1); //mAdapter=new MainGridViewLazyAdapter(MainGridView.this); mGridView.setAdapter(mAdapter); new DownloadDataAsyncTask().execute(); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (mLoading) { if (totalItemCount > mPreviousTotal) { mLoading = false; mPreviousTotal = totalItemCount; mCurrentPage++; // Find your own condition in order to know when you // have finished displaying all items if (mCurrentPage + 1 > 50) { mLastPage = true; } } } if (!mLastPage && !mLoading && (totalItemCount - visibleItemCount) <= (firstVisibleItem + mVisibleThreshold)) { new AddItemsAsyncTask().execute(); mLoading = true; } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } public class DownloadDataAsyncTask extends AsyncTask<String, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); mDialog = new ProgressDialog(MainGridView.this); mDialog.setTitle("Connect to Server"); mDialog.setMessage("This process can take a few seconds to a few minutes, depending on your Internet Connection Speed."); mDialog.setIndeterminate(false); mDialog.setCancelable(false); mDialog.show(); } @Override protected String doInBackground(String... args) { // Downloading XML /* Intent in = getIntent(); mSongsList = new ArrayList<HashMap<String, String>>(); cat_url = in.getStringExtra(KEY_CAT_URL); artist_url = in.getStringExtra(KEY_CAT_ARTIST); XMLParser parser = new XMLParser(); mXml = parser.getXmlFromUrl(cat_url); // getting XML from URL */ return null; } @Override protected void onPostExecute(String args) { /* getSupportActionBar().setTitle(artist_url); */ mDialog.dismiss(); mLoading = false; } } public class AddItemsAsyncTask extends AsyncTask<Integer, String, String> { @Override protected void onPreExecute() { super.onPreExecute(); } @Override protected String doInBackground(Integer... args) { MainGridView.this.runOnUiThread(new Runnable() { @Override public void run() { // Parsing 20 more items and adding them to the adapter for (int i = mCurrentPage * ITEMS_PPAGE; i < (mCurrentPage + 1) * ITEMS_PPAGE; i++) { MainGridView.this.mAdapter.add(String.valueOf(Math.random() * 5000)); } MainGridView.this.mAdapter.notifyDataSetChanged(); } }); return null; } @Override protected void onPostExecute(String args) { } } } 

Para la conveniencia, usé textos en lugar de imágenes dentro de GridView . Me centré en el sistema de paginación por lo que no analizar XML, acaba de añadir algunos valores al azar sobre la marcha.

Además, podría considerar el uso del mismo addItemsAsyncTask para descargar sólo una parte (20 elementos) de su xml en cada carga en lugar de descargar el conjunto de 1000 elementos antes de crear el GridView .

  • El diálogo de progreso de Android no se muestra en AsyncTask
  • Android AsyncTask ejemplo y explicación
  • Diferencia entre thread / runnable, handler, runonuithread, asynctask
  • Android AsyncTask con el ciclo de vida de la actividad
  • Cómo mostrar un spinner de progreso en android, cuando doInBackground () se está ejecutando
  • Dos AsyncTasks diferentes se ejecutan al mismo tiempo
  • Android: NoClassDefFoundError android.os.AsyncTask
  • ¿Cómo pasar el contexto de MenuItem onOptionsItemSelected a ASyncTask?
  • Llamada a Android Async Tarea en una actividad
  • Android asynctask con enhebrado
  • No se puede crear instancia de una tarea asíncrona por `cls.newInstance ()`?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.