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


    }
}

もう 1 つの問題は、配列 feed_products_list[length] を JArray 内の項目数で初期化する必要があることです。そのため、最後の項目までスクロールしてリスト全体を再入力するたびに配列サイズを変更することはできません

4

6 に答える 6

3

まず、コードにいくつかの問題があります。作成後に配列の長さを操作できないためActivity、変数valuesをに変更します。ArrayList<Product>次に、JArray の名前を jArray に変更します。最初の文字が大文字で、変数ではなくクラスを扱っていることを示す必要があります。

また、ViewHolder パターンを使用していないため、パフォーマンスが大幅に向上します。vogella.com で ListView に関するこのリンクを確認してください。より具体的には、章 3.1 および 3.2 を確認してください

で、必要なメソッドCustomArrayAdapterを実装OnScrollListenerして追加します。次に、 でonScroll(...)、データを追加するかどうかを決定します (例: ユーザーがリストの一番下に達した)。values.add(product)最後に、新しい項目を読み込み、 orを使用してデータセットに追加し、values.addAll(products)商品がListofProductの場合、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を作成し、 -method を次のようにimplement OnScrollListener設定します。onScroll()

    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 に答える
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 の例を示しました。リストビューの他のリンクですその他のリンク

于 2012-04-14T09:09:05.967 に答える
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 に答える