2011-09-26 9 views
12

Ho un ListView e uno BaseAdapter.I sto scaricando Prodotti webservice e visualizzare sul display listview.It correttamente sul ListView.righe Listview ordinare le modifiche in modo casuale sul rotolo di ListView in Android

Ma quando scorrere ListView visualizza righe in posizione casuale significa talvolta terzo display fila in prima posizione, esposizione fila posizione centrale su ultima posizione e così via.

Questo è il mio adattatore di classe

public class ProductListAdapter extends BaseAdapter implements OnClickListener{ 

    LayoutInflater inflater; 
    ArrayList<Product> arrProducts; 
    Context c; 

    public ProductListAdapter(Context c, ArrayList<Product> arrProducts) { 
     super(); 
     inflater = LayoutInflater.from(c); 
     this.arrProducts = arrProducts; 
     this.c = c; 
    } 

    @Override 
    public int getCount() { 
     return arrProducts.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return arrProducts.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View v, ViewGroup parent) { 
     Product product = null; 
     if(v == null) { 
      v = inflater.inflate(R.layout.product_listview_row, null); 
      product = (Product) getItem(position); 
      v.setTag(product); 
     }else { 
      product = (Product)v.getTag(); 
     } 

     v.setOnClickListener(this); 

     TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname); 
     tvProductname.setText(product.getTitle()); 

     String strReviewCount = product.getReviews(); 
     TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews); 
     if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews"); 

     Button btnPrice = (Button)v.findViewById(R.id.btnPrice); 
     btnPrice.setText(product.getSellingPrice()); 

     return v; 
    } 

    @Override 
    public void onClick(View v) { 
     Product product = (Product) v.getTag(); 
     Intent i = new Intent(c, ProductDetails.class); 
     i.putExtra(Product.PROD_ID, product.getId()); 
     startActivity(i); 
    } 

    @Override 
    public int getItemViewType(int position) { 
     return super.getItemViewType(position); 
    } 

    @Override 
    public int getViewTypeCount() { 
     return super.getViewTypeCount(); 
    } 
} 

Questo è ListView sul tracciato XML

<ListView android:id="@+id/lstProducts" style="@style/fill_parent" 
     android:dividerHeight="1dp" android:divider="#dbd3c5" 
     android:scrollbars="vertical" android:layout_below="@id/layLine"></ListView> 

anche quando cambio getView() metodo BaseAdapter come questo si sta lavorando bene

@Override 
    public View getView(int position, View v, ViewGroup parent) { 
     Product product = null; 
     v = inflater.inflate(R.layout.product_listview_row, null); 
     product = (Product) getItem(position); 
     v.setTag(product); 
     v.setOnClickListener(this); 

     TextView tvProductname = (TextView)v.findViewById(R.id.tvProductname); 
     tvProductname.setText(product.getTitle()); 

     String strReviewCount = product.getReviews(); 
     TextView tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews); 
     if(strReviewCount != null) tvReviewsCounts.setText(strReviewCount +" Reviews"); 

     Button btnPrice = (Button)v.findViewById(R.id.btnPrice); 
     btnPrice.setText(product.getSellingPrice()); 

     return v; 
    } 

Ma il problema in questo tipo è che io sono la visualizzazione immagine del prodotto in fila ListView che non avevo considerare here.By utilizzo di questo tipo di codice creare getView() metodo sempre nuovo Panorama quando rotolo mai di listView in modo che devo scaricare nuovamente immagine e again.I utilizzato ImageLoader classe che sta usando cash memory per scaricare immagini, ma problema è che quando ho impostato un'immagine per ImageView molte volte darmi out of memory error.

Please help me fuori da questo problema.

Grazie

risposta

10

ho atterrato qui a causa di un collegamento alla soluzione giusta .

Il problema qui è che si associa il prodotto una volta per la vista quando si crea un nuovo punto di vista. Si dovrebbe chiamare questo su ogni chiamata di getView:

product = (Product) getItem(position); 
v.setTag(product); 

Ma si potrebbe chiamare v.setOnClickListener(this) una volta che si crea la vista (che non cambierà comunque).

Questo dovrebbe fare il trucco. L'implementazione del tipo di vista è qui solo abusata. Vi consiglio di leggere my answer here ...

+0

So che la mia risposta non era il modo esatto per essere utilizzato, ma per temporanea scopo l'ho gestito usando il tipo di vista. Spero che la tua soluzione funzioni e venga controllata. –

+0

Grazie. Spero che non ti senta offeso, non era mia intenzione. Il problema qui è che le persone accettano il * trucco * come normale e funzionante e poi diventano veramente confusi quando le cose vanno male o vogliono usare un'implementazione di tipo vista reale ... Volevo solo che fosse chiaro, invece di iniziare le voci; -) – Knickedi

+0

No no, va bene anche a me per ottenere la soluzione esatta. Personalmente penso che la tua risposta funzionerà sicuramente e proverò anche io. E sentirsi male non è mai un caso, sono anche qui per imparare. Questo ha qualcosa di nuovo da te. Grazie. –

5

Pertanto, secondo il recommendations fatta dal Knickedi, il metodo getView() dovrebbe essere simile:

public View getView(int position, View v, ViewGroup parent) { 

    TextView tvProductname; 
    TextView tvReviewsCounts; 
    Button btnPrice; 

    // Phase 1... 
    if (v == null) { 
     v = inflater.inflate(R.layout.product_listview_row, null); 
     v.setOnClickListener(this); 

     tvProductname = (TextView)v.findViewById(R.id.tvProductname); 
     tvReviewsCounts = (TextView)v.findViewById(R.id.tvReviews); 
     btnPrice = (Button)v.findViewById(R.id.btnPrice); 

     v.setTag(R.id.tvProductname, tvProductname); 
     v.setTag(R.id.tvReviews, tvReviewsCounts); 
     v.setTag(R.id.btnPrice, btnPrice); 
    } 
    else { 
     tvProductname = (TextView) v.getTag(R.id.tvProductname); 
     tvReviewsCounts = (TextView) v.getTag(R.id.tvReviews); 
     btnPrice = (Button) v.getTag(R.id.btnPrice); 
    } 

    // Phase 2... 
    Product product = (Product) getItem(position); 

    tvProductname.setText(product.getTitle()); 
    btnPrice.setText(product.getSellingPrice()); 

    String strReviewCount = product.getReviews(); 
    if(strReviewCount != null) 
     tvReviewsCounts.setText(strReviewCount +" Reviews"); 

    return v; 
} 
+0

Fai attenzione a "public void setTag (int key, Object tag)" è stato aggiunto nel livello API 4 ... – eightyfive