2011-12-06 32 views
12
olarak adlandırılıyor

Siparişler listesindeki her sırayı görselleştiren özel bir bağdaştırıcım var.BaseAdapter notifyDatasetChanged() çağrıldı ama getView() hiçbir zaman

public class OrderRowAdapter extends BaseAdapter implements OnClickListener { 
    OrderList items_; 
    LayoutInflater inflater_; 
    int list_view_resource_id_; 
    private final String TAG = "OrderRowAdapter"; 

    public OrderRowAdapter(Context context, int list_view_resource_id, 
      OrderList items) { 
     this.list_view_resource_id_ = list_view_resource_id; 
     this.items_ = items; 
     this.inflater_ = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    public Object getItem(int position) { 
     return items_.getOrders(position); 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     Log.d(TAG, "View updated for item in position = " + position); 

     View v = convertView; 
     if (v == null) { 
      v = inflater_.inflate(list_view_resource_id_, parent); 
     } 

     Order item = items_.getOrders(position); 
     if (item != null) { 
      TextView order_info_tv = (TextView) v.findViewById(R.id.order_info); 
      TextView order_status_tv = (TextView) v.findViewById(R.id.order_status); 

      if (order_info_tv != null) { 
       order_info_tv.setText(
         String.format("For customer: %s\nTotal of %d items", item.getCustomerId(), item.getItemsCount())); 
      } 
      if (order_status_tv != null) { 
       order_status_tv.setText("Status: " + getStatusText(item.getStatus())); 
      } 
     } 
     return v; 
    } 

    public int getCount() { 
     if (items_ == null) { 
      Log.d(TAG, "Null so get count returned 0"); 
      return 0; 
     } else { 
      Log.d(TAG, "Get count returned " + items_.getOrdersCount()); 
      return items_.getOrdersCount(); 
     } 
    }; 

bir web hizmetinden siparişlerin yeni bir liste sorgulama sonra ListView İçeriği güncellemek istediğinizde, bu yüzden) (benim Etkinlik notifyDataSetChanged çağırmadan önce güncellenmesi yapar sahip

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.orders); 

    initThreading(); 
    findViews(); 
    setUrls(); 

    // Load the list of order from disk 
    try { 
     order_list_ = OrderList.parseFrom(new FileInputStream(
       "/sdcard/orderList.bin")); 
    } catch (FileNotFoundException e) { 
     Log.e(TAG, "Cannot find the file", e); 
    } catch (IOException e) { 
     Log.e(TAG, "Cannot read the file", e); 
    } 

    order_row_adapter_ = new OrderRowAdapter(OrderActivity.this, 
      R.layout.order_row, order_list_); 
    orders_listview_.setAdapter(order_row_adapter_); 

    // Request new updates from the server 
    updateOrderInformation(-1); 
} 

public void updateOrders(InputStream new_order_stream) { 
    Log.d(TAG, "Updating order UI"); 
    try { 
     order_list_.parseFrom(new_order_stream); 
    } catch (IOException e) { 
     Log.e(TAG, "IOException" , e); 
    } 

    runOnUiThread(new Runnable() { 
     public void run() { 
      guiUpdateOrders(); 
     } 
    }); 
} 

private void guiUpdateOrders() { 
    order_row_adapter_.notifyDataSetChanged(); 
    Log.d(TAG, "Dataset notified that it has changed. GUI update anytime now."); 
} 

Ama OrderRowAdapter'ın getView() yöntemi hiçbir zaman çağrılmaz. ListView asla güncellenmez.

cevap

12

getView() numaralı telefonumun çağrılmadığı için görünür değil. Düzenim xml, yüksekliği için fill_parent ile üst TextView sahiptir. Böylelikle tüm görünüm yalnızca tek bir TextView görünür.

Çözüm:ListView görünür olmasını sağlamak için söz konusu düzeni grafiksel görünümünü kontrol edin.

+0

IMO bu çok açık bir sorundur. Özellikle '' Spinner'ı görüntülemek için '' AdaptörView''ü saklamak hala ortak bir paradigma olduğundan, birçok insan için sinir bozucu vahşi kaz olduğunu görebiliyorum. – alexgophermix

1

ListView'unuzun içeriğini değiştirmek için, aynı başvuruyu Listeye kullanmaya devam etmelisiniz. Burada başka bir liste oluşturuyorsunuz ve onu items_ değişkenine atayarak (listenin kendisini içermiyor, sadece bir Listeye bir referansı saklamak için bir yer), ancak View öğenizin hala eski listeye bir referansı var. Yerine items_ = new_order_list ait

bu çalışması gerekir:

items_.clear(); 
items_.addAll(new_order_list); 

DÜZENLEME:

, daha iyi açıklamak old_items adında yeni bir değişken oluşturmak için denemek için: Bu sorunu çıkıyor

public void setNewOrderList(List<Order> new_order_list) 
{ 
    Log.d(TAG, "New Order List available. Num items = " + new_order_list.size()); 

    List<Order> old_items = items_; // store the reference to the old list 
    items_ = new_order_list; 

    Log.d(TAG, "items_.size() = " + items_.size()); 
    Log.d(TAG, "old_items.size() = " + old_items.size()); // The old list still exists, and it's the one used by your ListView 

    notifyDataSetChanged(); 
} 
+0

Olsa bile, getCount 5'i geri almaya devam ederse getView yöntemimi çağırmamalı mıyım? Ben senin öneri denedim ve java.lang.UnsupportedOperationException java.util.Collections $ unmodifiableCollection.clear olsun –

+0

Senin 'getCount() yöntemi sizin yeni listenizde yer alan öğeyi sayar. Bellekte bir yerde kayboldu. Cevabımı düzenledim. – Dalmas

+0

İstisnaınız, listenizin salt okunur olduğu anlamına gelir. Bunu nasıl yaratıyorsunuz? – Dalmas

2

emin olun BaseAdapter yöntemleri

registerDataSetObserver(DataSetObserver observer) 
unregisterDataSetObserver(DataSetObserver observer) 

geçersiz değildir.

0

her şeyden cevapları() invalidateViews ile deneyin çalışmıyor ise

ListView.invalidateViews() tüm alt öğe görünümlerini (bunların yeniden çizilmesine) geçersiz kılmak için ListView anlatmak için kullanılır.

Öğelerden eşit sayıda görüntülemeye gerek olmadığını unutmayın. Bunun nedeni bir ListView'in öğe görünümlerini geri dönüştürmesi ve siz kaydırırken ekranın etrafını akıllı bir şekilde hareket ettirmesidir. Bu yanıt herhangi bir hata hatalarımı lütfen düzeltin

listView.invalidateViews() 

Benim örnek uygulama

,

    lvitems.post(new Runnable() { 
         @Override 
         public void run() { 
          lvitems.invalidateViews(); //invalidate old 
          CustomAdapter customAdapter=new CustomAdapter(context, names, images); // load new data 
          customAdapter.notifyDataSetChanged();// call notifydatasetChanged 
         } 
        }); 

edin.

İlgili konular