android - vista de lista dinámica que agrega "Cargar más elementos" al final del desplazamiento
listview dynamic-loading (3)
Tengo una vista de lista que está obteniendo datos de la base de datos sqlite por Json.
Quiero convertirlo en una vista de lista dinámica que, al final del desplazamiento, aparece "cargar más elementos" en el pie de página de la lista al cargar más elementos y agregarlos al adaptador (por ejemplo, 10 elementos cada vez). Tengo un problema al implementar esta característica. Por favor ayúdame con eso. Gracias.
public class AllProductsActivity extends Activity {
... defining variables...;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new LoadAllProducts().execute();
}
class LoadAllProducts extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
super.onPreExecute();
... progress dialog...
}
protected String doInBackground(String... args) {
countryList = new ArrayList<Country>();
List<NameValuePair> params = new ArrayList<NameValuePair>();
JSONObject json = jParser.makeHttpRequest(url_all_products, "GET", params);
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// products found
// Getting Array of Products
products = json.getJSONArray(TAG_PRODUCTS);
// looping through All Products
for (int i = 0; i < products.length(); i++) {
JSONObject c = products.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(TAG_PID);
String name = c.getString(TAG_NAME);
String description = c.getString(TAG_DESCRIPTION);
String due_date = c.getString(TAG_DUE_DATE);
String staff = c.getString(TAG_STAFF);
String status = c.getString(TAG_STATUS);
country = new Country(id,name,description,
due_date, staff, status);
countryList.add(country);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
displayListView();
}
});
}
}
private void displayListView() {
dataAdapter = new MyCustomAdapter(this,
R.layout.country_info, countryList);
ListView listView = (ListView) findViewById(R.id.listView1);
listView.setAdapter(dataAdapter);
}
private class MyCustomAdapter extends ArrayAdapter<Country> {
... blah blah blah ...
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
Log.v("ConvertView", String.valueOf(position));
if (convertView == null) {
... blah blah blah ...
}
return convertView;
}
}
}
Existe la solución, Activity tiene que implementar la interfaz AbsListView.OnScrollListener
En actividad:
int currentFirstVisibleItem = 0;
int currentVisibleItemCount = 0;
int totalItemCount = 0;
int currentScrollState = 0;
boolean loadingMore = false;
Long startIndex = 0L;
Long offset = 10L;
View footerView;
@Override
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
this.currentFirstVisibleItem = firstVisibleItem;
this.currentVisibleItemCount = visibleItemCount;
this.totalItemCount = totalItemCount;
}
@Override
public void onScrollStateChanged(AbsListView absListView, int scrollState) {
this.currentScrollState = scrollState;
this.isScrollCompleted();
}
private void isScrollCompleted() {
if (this.currentVisibleItemCount > 0 && this.currentScrollState == SCROLL_STATE_IDLE && this.totalItemCount == (currentFirstVisibleItem + currentVisibleItemCount)) {
/*** In this way I detect if there''s been a scroll which has completed ***/
/*** do the work for load more date! ***/
if (!loadingMore) {
loadingMore = true;
new LoadMoreItemsTask(this).execute();
}
}
}
private class LoadMoreItemsTask extends AsyncTask<Void, Void, List<ListItem>> {
private Activity activity;
private View footer;
private LoadMoreItemsTask(Activity activity) {
this.activity = activity;
loadingMore = true;
footer = activity.getLayoutInflater().inflate(R.layout.base_list_item_loading_footer, null);
}
@Override
protected void onPreExecute() {
list.addFooterView(footer);
list.setAdapter(adapter);
super.onPreExecute();
}
@Override
protected List<ListItem> doInBackground(Void... voids) {
return getNextItems(startIndex, offset);
}
@Override
protected void onPostExecute(List<ListItem> listItems) {
if (footer != null) {
list.removeFooterView(footer);
}
list.setAdapter(adapter);
loadingMore = false;
if (listItems.size() > 0) {
startIndex = startIndex + listItems.size();
setItems(listItems);
}
super.onPostExecute(listItems);
}
}
Oncreate:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.base_list);
list = (ListView) findViewById(R.id.list);
list.setOnItemClickListener(this);
list.setOnScrollListener(this);
footerView = ((LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.base_list_item_loading_footer, null, false);
initAdapter();
new LoadMoreItemsTask(this).execute();
}
base_list_item_loading_footer.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_item_footer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="15dp" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal" >
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ProgressBar>
<TextView
style="@style/ItemHeadTextStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/loading_list_items" />
</LinearLayout>
</RelativeLayout>
Espero que ayude.
La mejor forma de implementar Dynamic Expandaple LW con el pie de página se explica a continuación:
private int firstVisibleItem, visibleItemCount,totalItemCount;
expandapleListView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScroll(AbsListView view,
int firstVisibleItemm, int visibleItemCountt,
int totalItemCountt) {
firstVisibleItem = firstVisibleItemm;
visibleItemCount = visibleItemCountt;
totalItemCount = totalItemCountt;
}
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
final int lastItem = firstVisibleItem + visibleItemCount;
if (lastItem == totalItemCount && scrollState == SCROLL_STATE_IDLE) {
expandapleInt++;
new AsyncTask().execute();
//get next 10-20 items(your choice)items
}
}
});
Implementación de pie de página:
Dado el siguiente código xml, debe estar en la parte inferior del diseño que su ListView dentro de él ...
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="45dp"
android:layout_gravity="center"
android:id="@+id/footer">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_toLeftOf="@+id/textView3"
android:layout_toStartOf="@+id/textView3">
</ProgressBar>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Loading"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/textView3" />
Enlazarlo en tu actividad
footer = (RelativeLayout) findViewById(R.id.footer);
footer.setVisibility(View.GONE);
onPreExecute
footer.setVisibility(View.VISIBLE);
onPostExecute
footer.setVisibility(View.GONE);
prueba el siguiente código
list.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if(firstVisibleItem+visibleItemCount == totalItemCount && totalItemCount!=0)
{
if(flag_loading == false)
{
flag_loading = true;
additems();
}
}
}
});
en additem()
agregue los siguientes 10 elementos a la lista de arreglos y configure flag_loading
como false
. y llame a notifydatasetchanged
. deberia de funcionar.