2013-04-29 3 views
5

Ich verwende einen benutzerdefinierten Adapter der Listenansicht, um ein Bild und einen Titel anzuzeigen. In meiner Anwendung ich hinzufügen und entfernen Sie die Elemente in der Liste, und ich muss zeigen, dass Änderungen an der Schnittstelle. bei jeder Änderung in Daten Ich bekomme alle Liste aus der Datenbank und speichern Sie es in der Adapterliste und rufen Sie dann adapter.notifyDataSetChanged(); aber Interface zeigt keine Veränderung. auf der anderen Seite, wenn ich Artikel direkt vom Adapter hinzufügen oder entfernen, reagiert es richtig. Ich habe einen einfachen Adapter verwendet und für diesen adapter.notifyDataSetChanged(); funktioniert gut, aber für benutzerdefinierte antwortet es nicht. Ich habe auch viele Lösungen auf dem Stackoverflow ausprobiert, aber keiner von ihnen funktioniert. wie Updating the list view when the adapter data changesangepasst adapter.notifyDataSetChanged() funktioniert nicht

Android List view refresh

Adapter.notifyDataSetChanged() is not working

notifyDataSetChange not working from custom adapter

ich dies tun, als folows bei oncreate

enter code here 

      product_data = new ArrayList<Product>(); 
    Bundle extras = getIntent().getExtras(); 
    if (extras != null) { 
     value = extras.getInt("list_id"); 
    } 
    product_data = db.getAllProductsstatus(value, 1); 
    Collections.reverse(product_data); 

    adapter = new ProductAdopter(this, 
      R.layout.listview_item_row, product_data, 2); 
    ListView listView1 = (ListView)findViewById(R.id.listView1); 
    listView1.setAdapter(adapter); 
    registerForContextMenu(listView1); 

und in onMenuItemSelected

enter code here 
@Override 
public boolean onMenuItemSelected(int featureId, MenuItem item) { 
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 

     int menuItemIndex = item.getItemId(); 
     String listItemName = adapter.getItem(info.position)._name; 
     int id = adapter.getItem(info.position)._id; 

     if(menuItemIndex == 0) 
     { 

      db.deleteProduct(adapter.getItem(info.position)); 

      product_data = db.getAllProducts(value); 
      Collections.reverse(product_data); 
      //adapter.remove(adapter.getItem(info.position)); 
      adapter.notifyDataSetChanged(); 
     } 
     else if(menuItemIndex == 1){ 
      String name ; 
      if (adapter.getItem(info.position)._status == 0){ 
       popall("bar code", "no bar code entered");     
      } 
      else { 
      popall("bar code", adapter.getItem(info.position)._bar_code); 
      } 
     } 
     else if (menuItemIndex == 2){ 
      adapter.getItem(info.position)._status = 0; 
      adapter.getItem(info.position)._bar_code = "0"; 
      db.updateProduct(adapter.getItem(info.position)); 
       product_data = db.getAllProductsstatus(value, 1); 
      adapter.notifyDataSetChanged(); 

      popall("alert", "successfully done"); 
     } 
     return true; 
} 

meine kundenspezifische Adapter-Klasse unter

public class ProductAdopter extends ArrayAdapter<Product> { 
    Context context; 
    int layoutResourceId;  
    List<Product> data = null; 
    int source; 
    public ProductAdopter(Context context, int layoutResourceId, List<Product> product_data, int source) { 
     // TODO Auto-generated constructor stub 
     super(context, layoutResourceId, product_data); 
     this.layoutResourceId = layoutResourceId; 
     this.context = context; 
     this.data = product_data; 
     this.source = source; 
    } 
    // public ProductAdopter(MainActivity context2, int listviewItemRow, List<Product> product_data) { 
     // TODO Auto-generated constructor stub 
    //} 
    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View row = convertView; 
     ProductHolder holder = null; 

     if(row == null && source == 1) 
     { 
      LayoutInflater inflater = ((MainActivity)context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 

      holder = new ProductHolder(); 
      holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon); 
      holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle); 

      row.setTag(holder); 
     } 
     if(row == null && source == 2) 
     { 
      LayoutInflater inflater = ((purchased)context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 

      holder = new ProductHolder(); 
      holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon); 
      holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle); 

      row.setTag(holder); 
     } 
     if(row == null && source == 3) 
     { 
      LayoutInflater inflater = ((Skiped)context).getLayoutInflater(); 
      row = inflater.inflate(layoutResourceId, parent, false); 

      holder = new ProductHolder(); 
      holder.imgIcon = (ImageView)row.findViewById(R.id.imgIcon); 
      holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle); 

      row.setTag(holder); 
     } 


     else 
     { 
      holder = (ProductHolder)row.getTag(); 
     } 

     Product product = data.get(position); 
     holder.txtTitle.setText(product.getName()); 
     if(product.icon.equals("no")){ 
      holder.imgIcon.setImageResource(R.drawable.blank); 
     } 
     else{ 
      File imgFile = new File(product.icon); 
      if(imgFile.exists()){ 

       Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath()); 
       Bitmap resized = Bitmap.createScaledBitmap(myBitmap, 70, 70, true); 

       holder.imgIcon.setImageBitmap(resized); 
       myBitmap.recycle(); 
      }   
     } 

     return row; 
    } 
    static class ProductHolder 
    { 
     ImageView imgIcon; 
     TextView txtTitle; 
    } 

} 
+0

Ja. Das ist das Verhalten von ArrayAdapter <>: Es verfolgt nicht das ursprüngliche Array, das Sie angegeben haben. Sie müssen Objekte sowohl in Ihrem Array als auch im Adapter hinzufügen und löschen. – etienne

+0

Ich weiß, und das ist das Problem, dass ich keinen Artikel in beiden hinzufügen sollte – user2274314

Antwort

10

Das Problem gegeben ist, dass in Ihrem onMenuItemSelected() Sie diese Zeile haben:

product_data = db.getAllProducts(value); 

Wenn Sie den Adapter in onCreate() erstellt, ihr habt es ist ein Hinweis auf product_data. An diesem Punkt werden Ihre Änderungen an product_data in den Adapter weitergegeben, da es einen Verweis auf Ihre Liste enthält.

Aber sobald Sie eine neue Liste Ihrer product_data Variablen zuweisen (wie Sie in der onMenuItemSelected() tun) der Adapter hat jetzt einen Verweis auf die alte Liste, während product_data jetzt auf eine neue Liste verweist. Ihr Adapter kennt Ihre Änderungen in der neuen Liste nicht.

Statt die Variable der Neuzuordnung, versuchen Sie es Löschen und Kopieren Ihre Artikel wie folgt aus:

product_data.clear(); 
product_data.addAll(db.getAllProducts(value)); 

Auf einer anderen Anmerkung, wenn Sie Ihre Daten aus der Datenbank zu lesen, sollten Sie stattdessen eine CursorAdapter betrachten verwenden.

Hier ist ein einfaches Tutorial: http://blog.cluepusher.dk/2009/11/16/creating-a-custom-cursoradapter-for-android/

+0

Ich habe in diesem für den Pass einige Stunden untersucht und konnte es nicht herausfinden. Wirklich tolle Antwort, wirklich großartige Erklärung. – TrueCoke

+0

Perfekte Antwort danke –

0

Das Problem in Ihrem Code ist, dass Sie Ihren Adapter werden benachrichtigt die Liste zu aktualisieren, aber Sie sind nicht frisch Daten (I.e after add/remove items.) Um es zu liefern.

wie folgt durchführen:

if(menuItemIndex == 0) { db.deleteProduct(adapter . Get item(info.position)); product_data = db.getAllProducts(value); 
    Collections.reverse(product_data); 


    adapter = new ProductAdopter(this, R.layout.listview_item_row, product_data, 2); ListView listView1 = (ListView)findViewById(R.id.listView1); 
    listView1.setAdapter(adapter); 

//adapter.remove(adapter.getItem(info.position)); 
//adapter.notifyDataSetChanged(); 

} 

dies tun Sie neue Daten liefern an Adapter So wird es Listenansicht aktualisieren frisch geändert Daten zeigen auch ohne Aufruf adapter.notifyDataSetChanged();

Sie auch müssen Listenansicht Objekt als global machen, um es zu verwenden, während Settimg neuen Adapter in onMenuItemSelected()

Ich hoffe, dass dies Ihr Problem lösen wird.

Verwandte Themen