【问题标题】:dynamic listview adding "Load more items" at the end of scroll动态列表视图在滚动结束时添加“加载更多项目”
【发布时间】:2013-04-30 05:15:05
【问题描述】:

我有一个列表视图,它通过 Json 从 sqlite 数据库中获取数据。

我想把它变成动态列表视图,在滚动结束时,“加载更多项目”出现在列表的页脚中,同时加载更多项目并将它们添加到适配器(例如每次 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<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;
    }
}
}

【问题讨论】:

    标签: android listview dynamic-loading


    【解决方案1】:

    你试试下面的代码

    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。它应该工作。

    【讨论】:

    • 我应该定义first visble itemvisible item counttotalitemcount吗?
    • 我应该这样定义它们:int first visible item = 1; int visibleitemcount = 10;整数总数= 45; ?
    • 没有。当您滚动列表时,将调用 onScroll。并且您将获得第一个可见项目等的值。您不必定义它们
    • 谢谢。你的意思是我在我的 php 文件中使用 LIMIT 1,10,其中 1 由应用程序发布到服务器(意味着第一页),并且对于每个负载,我有计数 + 最后一页的数量,例如我的应用程序将数字 5 发送到服务器并且它这次发送 5*10,10 进行加载。对吗?
    • 这将无限次连续调用添加项目功能..如果您将留在应用程序中的同一位置,即最后一项是否可见。
    【解决方案2】:

    有解决办法,Activity要实现接口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<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);
        }
    
    
    }
    

    创建:

    @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> 
    

    我希望,它会有所帮助。

    【讨论】:

    • 请提供以下函数setItems();
    【解决方案3】:

    使用页脚实现动态 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 代码,应该在 Layout 的底部,你的 ListView 在里面...

     <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" />
    

    将其绑定到您的活动中

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

    onPreExecute

    footer.setVisibility(View.VISIBLE);
    

    onPostExecute

    footer.setVisibility(View.GONE);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-03
      • 1970-01-01
      • 2015-12-05
      • 2014-03-14
      • 1970-01-01
      • 2012-01-27
      • 1970-01-01
      相关资源
      最近更新 更多