3

我想增加列表视图滚动到末尾时动态显示的项目数。就我而言,我的列表视图最初将显示 10 个项目。然后当我们滚动到最后一个项目时,它必须开始显示另外 10 个项目,依此类推。我怎样才能做到这一点??

这是我的自定义数组适配器

    package com.android.listview;

import java.util.ArrayList;

import com.android.listview.R;
import com.android.listview.Product;

import android.widget.ArrayAdapter;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.android.listview.ListViewActivity;

public class CustomArrayAdapter extends ArrayAdapter<Product> implements
        OnScrollListener {

    private final Context context;
    private final ArrayList<Product> values;

    static class ViewHolder {
        public TextView text;
        public ImageView image;
    }

    public CustomArrayAdapter(Context arg0, int arg1, int arg2,
            ArrayList<Product> arg3) {
        super(arg0, arg1, arg2, arg3);
        this.context = arg0;
        this.values = arg3;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        int product_id = 0;
        View rowView = inflater.inflate(R.layout.feed_items, parent, false);
        try {

            ImageView wic_logo = (ImageView) rowView.findViewById(R.id.logo);
            TextView label = (TextView) rowView.findViewById(R.id.label);

            Product p = values.get(position);
            product_id = p.productId;
            String date = new java.text.SimpleDateFormat("dd/MM/yy")
                    .format(new java.util.Date(p.timeStamp));
            label.setText(p.productName + "\n" + p.reportedPrice + "   MRP: "
                    + p.mrp + "\n" + "Discount: " + p.discount + "%   "
                    + p.area + "  " + p.city + "\n" + "Shared by " + p.userName
                    + " " + "on" + " " + date);

            wic_logo.setImageResource(R.drawable.wic_logo_small);
            Log.d("date", "" + date);

            Log.d("Custom Array Adapter", "at" + position);
        } catch (Exception e) {
            Log.d("Custom Array Adapter", "catch");
        }

        return rowView;
    }

    public void onScroll(AbsListView arg0, int firstVisibleItem,
            int visibleItemCount, int totalItemCount) {
        Log.d("entered onScroll", " " + firstVisibleItem + visibleItemCount
                + totalItemCount);
        if (((firstVisibleItem + visibleItemCount) >= totalItemCount - 1)) {
            Log.d("entered if", " " + firstVisibleItem + visibleItemCount
                    + totalItemCount);
            // if we're at the bottom of the listview, load more data
            addData(totalItemCount, values.get(totalItemCount).productId);
        }
    }

    private void addData(int totalItemCount, int productId) {

        Toast.makeText(getContext(), "last item", Toast.LENGTH_SHORT).show();
    }

    public void onScrollStateChanged(AbsListView arg0, int arg1) {

    }
}

这是我的活动

package com.android.listview;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.listview.CustomArrayAdapter;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Button;
import android.widget.ListView;

public class ListViewActivity extends Activity {

    static Product[] feed_products_list;
    private JSONArray JArray;
    private InputStream is;
    private StringBuilder sb;
    private String result;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button feed_button = (Button) findViewById(R.id.feedButton_feed);
        feed_button.setBackgroundResource(R.color.grey);
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        try {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost("http://10.0.2.2/wic2/mobile/feed");
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            ResponseHandler<String> responseHandler = new BasicResponseHandler();
            HttpResponse response = httpclient.execute(httppost);
            HttpEntity entity = response.getEntity();
            is = entity.getContent();

            try {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "iso-8859-1"), 8);
                sb = new StringBuilder();
                sb.append(reader.readLine() + "\n");
                String line = "0";
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();
                Log.d("result", result);
            } catch (Exception e) {
                Log.e("error", "Error in http connection" + e.toString());
            }

            Log.e("response", "response is:" + response.toString());
        } catch (Exception e) {
            Log.e("error", "Error in http connection" + e.toString());
        }

        ListView tv = (ListView) findViewById(R.id.feedListView);
        try {
            Log.d("JArray", "entered try");
            JArray = new JSONArray(result);
            int length = JArray.length();
            feed_products_list = new Product[length+1];
            Log.d("JArray", "try last line");
        } catch (JSONException e) {
            Log.d("JArray", "in catch");
            e.printStackTrace();
        }

        JSONObject jsonObj;

        for (int i = 0; i < JArray.length(); i++) {
            try {
                Log.d("jsonObj", "entered try");
                jsonObj = JArray.getJSONObject(i);
            } catch (Exception e) {
                Log.d("jsonObj", "in catch");
                continue;
            }

            try {
                Log.d("feed_products_list", "entered try");
                feed_products_list[i] = new Product(jsonObj.getInt("id"),
                        jsonObj.getString("image"),
                        jsonObj.getString("product_name"),
                        jsonObj.getString("reported_price_formated"),
                        jsonObj.getString("store_area"),
                        jsonObj.getString("store_city"),
                        jsonObj.getString("mrp"),
                        jsonObj.getString("user_name"),
                        jsonObj.getLong("reported_timestamp"),
                        jsonObj.getInt("discount"));
                Log.d("feed_products_list", feed_products_list[i].productName);
            } catch (JSONException e) {
                Log.d("feed_products_list in catch",
                        feed_products_list[i].productName);
                e.printStackTrace();
            }
        }

        tv.setAdapter(new CustomArrayAdapter(this, R.layout.feed_items,
                R.id.label, feed_products_list));


    }
}

还有一个问题是我必须用 JArray 中的项目数来初始化我的数组 feed_products_list[length]。所以每次滚动到最后一项并重新填充整个列表时,我都无法更改数组大小

4

6 回答 6

3

首先,您的代码存在一些问题。在您的Activity,将您的变量更改values为 anArrayList<Product>因为您无法在创建后操纵数组的长度。接下来,将 JArray 重命名为 jArray;如果第一个字母是大写字母,则表明您正在处理的是类而不是变量。

此外,您没有使用 ViewHolder 模式,这大大提高了性能。查看vogella.com 上有关 ListView 的链接;更具体地说,请查看第 3.1 和 3.2 章

CustomArrayAdapter中,实现OnScrollListener并添加所需的方法。然后,在 中onScroll(...),确定是否要添加数据(例如,用户到达列表底部)。最后,加载新项目,将它们添加到您的数据集中,values.add(product)其中values.addAll(products)products 是ListsProduct的 a ,并在每次调用or后notifyDataSetChanged从您的内部调用。CustomArrayAdaptervalues.add(...)values.addAll(...)

例如,您可以在代码中更改以下内容:

在您的活动中:

  • 删除线条

    int length = JArray.length();
    feed_products_list = new Product[length+1];
    
  • 从您的中删除“静态”feed_products_list并将其更改为 ArrayList:

    private ArrayList<Product> feed_products_list = new ArrayList<Product>();
    
  • 而不是feed_products_list[i] = new Product(jsonObj.getInt("id"), .... yadiya ...调用 feed_products_list.add(new Product(jsonObj.getInt("id"), ... yadiya ...`。

在您的适配器中:

  • 创建class implement OnScrollListener,并将onScroll()-method 设置为如下所示:

    public void onScroll(AbsListView view, int firstVisibleItem,
                            int visibleItemCount, final int totalItemCount) {
        if(((firstVisibleItem + visibleItemCount) >= totalItemCount)) {
    
            // if we're at the bottom of the listview, load more data
            addData(totalItemCount);
        }
    }
    
  • 创建一个方法addData(long offset)

    private void addData(long offset) {
    
        // download your data, pass the offset so you know where to start
        // and when you convert your json into `Product`s
        Product product = new Product(JSONObject.getInt("id"), ... yadiya ...);
        this.add(product);
        this.notifyDataSetChanged();
    
        // make sure to call notifyDataSetChanged() on your UI-Thread.
    }
    
于 2012-04-14T09:11:51.287 回答
2

对于动态增加大小,最好使用 ArrayList。对于滚动,您可以使用 @Mayank 想法。

于 2012-04-14T08:51:12.997 回答
1

你应该scroll listener在你的listview

ListView lv = (ListView)findViewById(R.id.list_view); 
lv.setOnScrollListener(new OnScrollListener() { 
    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem,  
        int visibleItemCount, int totalItemCount) { 
        //Check if the last view is visible 
        if (view.getLastVisiblePosition()+1 == 10) { 
            //load more content 
        } 
    } 
});

更新

因此,最初在您的项目中feed_products_list,您将有 10 个项目,当用户向下滚动时,向列表中添加 10 个项目并将其重置CustomArrayAdapterlistView. 继续这样做,直到您拥有列表中的所有项目。

于 2012-04-14T08:45:59.150 回答
0

您不需要这样做。Android 列表视图可以轻松处理数千个条目——前提是您仔细编写适配器并重用视图。因此,在您的 getView() 方法中,您必须检查是否提供了 converView 并且是否正确,然后使用新值填充它。(Andriod 非常聪明,它提供回收现在不可见的列表条目) - 这将立即提升性能

像这样做:

View rowView = convertView;
if(rowView == null) {
   // do what you are doing now to inflate view
}
// do what you are doing now to set up view

return rowView;

如果您不想立即从任何存储中加载所有条目,则增加列表的大小是有意义的——在这种情况下,您必须注册滚动侦听器并通过加载丢失的条目来对其做出反应,然后发出列表数据已更改的信号。而且您不必使用数组作为后备存储 - 列表将完美匹配此目的

于 2012-04-14T08:50:50.250 回答
0

使用 ArrayList 而不是这样的数组

public class CustomArrayAdapter extends ArrayAdapter<Object> {

    private final Context context;
    private final ArrayList<Product> values;

在你的getView()

            Product p = values.get(position);

您可以在适配器内部提供一个方法来向 ArrayList 添加元素,notifyDataSetChange()它看起来像这样

public void addElement(Product p){
values.add(p);
notifiyDataSetChange();
}

使用OnScrollListener加载更多数据示例:

listView.setOnScrollListener(new OnScrollListener() { 
    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem,  
        int visibleItemCount, int totalItemCount) { 

        if (totalItemCount - visibleItemCount <= firstVisibeItem + 5) { 
            //load more content 

            .....
            adpater.addElement(p);

        } 


     } 
    });
于 2012-04-14T09:00:20.777 回答
0

我认为您想要像Lazy loading 之类的东西。

它被称为延迟加载。我相信你还没有尝试过这样的搜索。我给了你GridView的例子。这是 Listview 的其他链接 Other Link

于 2012-04-14T09:09:05.967 回答