Вопрос по dynamic-loading, listview, android – динамический просмотр списка с добавлением «Load more items» в конце прокрутки

47

У меня есть просмотр списка, который выбирает данные из базы данных sqlite от Json.

Я хочу превратить его в динамический просмотр списка, который в конце прокрутки, "загрузить больше предметов " появляется в нижнем колонтитуле списка при загрузке дополнительных элементов и добавлении их в адаптер (например, 10 элементов каждый раз). У меня есть проблема в реализации этой функции. Пожалуйста, помогите мне с этим. Благодарю.

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 {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        ... progress dialog...
    }

    protected String doInBackground(String... args) {
        countryList = new ArrayList();
        List params = new ArrayList();
        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 {

    ... 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;
    }
}
}

Ваш Ответ

3   ответа
14

Есть решение, активность должна реализовывать интерфейсAbsListView.OnScrollListener

В деятельности:

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 {

    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 doInBackground(Void... voids) {

        return getNextItems(startIndex, offset);
    }

    @Override
    protected void onPostExecute(List 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



    

        
        

        
    
 

Я надеюсь, что это помогает.

Пожалуйста, предоставьте следующую функцию setItems (); Vinil Chandran
8

Лучший способ реализовать Dynamic Expandaple LW с нижним колонтитулом описан ниже:

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

                }
            }
        });

Реализация нижнего колонтитула:

Приведенный ниже код XML, должен быть в нижней части макета, чтобы ваш ListView внутри него ...

 





Свяжите это в своей деятельности

footer = (RelativeLayout) findViewById(R.id.footer);
footer.setVisibility(View.GONE);

onPreExecute

footer.setVisibility(View.VISIBLE);

onPostExecute

footer.setVisibility(View.GONE);
90

вы попробуйте следующий код

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();
                }
            }
        }
    });

вadditem() добавить следующие 10 элементов в список массивов и установитьflag_loading какfalse, и позвонитьnotifydatasetchanged, он должен работать.

@ Хардип нет, не будет. flag_loding будет true во второй раз, чтобы он не загружался дважды. null pointer
хороший подход, но этопоследняя попытка получить больше строк, когда вы остаетесь в конце списка IgniteCoders
У меня сработало .. спасибо :) Snehal
Спасибо, дорогой. Кажется, это должно работать. Namikaze Minato

Похожие вопросы