2016-07-25 11 views
0

Ich verwende Realm in meiner mobilen Anwendung, um Werbebuchungen für meine Listenansicht zu speichern. Ich erweitere den RealmBaseAdapter, der gut funktioniert. Problem ist, dass, wenn ich eine Abfrage an die Datenbank mache, um meine Artikel zu filtern, mein Adapter die geänderte Liste nicht aufnimmt und den out of bound index Fehler verursacht.Listenadapter übernimmt keine Änderungen nach Realm-Abfrage

Dies ist, wo ich meinen Adapter mit den Anfangswerten gesetzt,

results = realm.where(BillingLineItem.class).findAll(); 
adapter = new BillingListAdapter(getActivity(), results); 

Und das ist der Teil, den ich die Filterung mache basierend auf der Spezifikation Nummer,

results = realm.where(BillingLineItem.class) 
      .equalTo("SpecNumber", spec) 
      .findAll(); 
adapter.notifyDataSetChanged(); 

Und wie Ich sagte vorher Nach dieser Abfrage Ergebnisse werden aktualisiert, aber Adapter nimmt die Änderungen nicht auf.

EDIT: Mein Adapter für die Listenansicht

public class BillingListAdapter extends RealmBaseAdapter<BillingLineItem> { 

private LayoutInflater inflater = null; 

private HashMap<Integer, Boolean> mSelection = new HashMap<Integer, Boolean>(); 
private boolean isActionMode; 

public BillingListAdapter(Context mContext, RealmResults<BillingLineItem> lineItems) { 
    super(mContext,lineItems); 
    inflater = (LayoutInflater) mContext. 
      getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    this.isActionMode = false; 
} 
// I commented out this part because RealmBaseAdapter automaticly implements this methods in the super class 
/*@Override 
public int getCount() { 
    return lineItems.size(); 
} 

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

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

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    View vi = convertView; 
    ViewHolder holder; 

    if (convertView == null) { 

     /****** Inflate billing_foreground_item.xml file for each row (Defined below) *******/ 
     vi = inflater.inflate(R.layout.billing_foreground_item, null); 

     /****** View Holder Object to contain billing_foreground_item.xml file elements ******/ 

     holder = new ViewHolder(); 
     holder.SubOper = (TextView) vi.findViewById(R.id.tvSubOper); 
     holder.Spec = (TextView) vi.findViewById(R.id.tvSpec); 
     holder.Address = (TextView) vi.findViewById(R.id.tvAddress); 
     holder.SKU = (TextView) vi.findViewById(R.id.tvSku); 
     holder.SKUDesc = (TextView) vi.findViewById(R.id.tvSkuDesc); 
     holder.Quantity = (TextView) vi.findViewById(R.id.tvQuantity); 
     holder.Unit = (TextView) vi.findViewById(R.id.tvUnit); 
     holder.BilledQty = (TextView) vi.findViewById(R.id.tvBBilledQty); 
     holder.RemainingQty = (TextView) vi.findViewById(R.id.tvRemainingQty); 
     holder.ivLineIcon = (ImageView) vi.findViewById(R.id.ivLineIcon); 
     holder.rlItem = (RelativeLayout) vi.findViewById(R.id.rlItem); 
     holder.ErrorMessage = (TextView) vi.findViewById(R.id.txtErrorDisplay); 
     /************ Set holder with LayoutInflater ************/ 
     vi.setTag(holder); 
    } else { 
     holder = (ViewHolder) vi.getTag(); 
    } 

    /************ Set Model values in Holder elements ***********/ 
    if (adapterData.get(position).getFinalFlag()) { 
     holder.ivLineIcon.setImageResource(R.drawable.finalflagblue); 

     holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255)); 

     if (adapterData.get(position).getCompleted()) { 
      holder.rlItem.setBackgroundColor(Color.rgb(223, 235, 245)); 
     } 
     if (adapterData.get(position).getErrorFlag()){ 
      holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57)); 
      holder.ErrorMessage.setVisibility(View.VISIBLE); 
      holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage()); 
     } 

    } else if (adapterData.get(position).getDeleteFlag()) { 
     holder.ivLineIcon.setImageResource(R.drawable.trashiconred); 

     holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255)); 
     if (adapterData.get(position).getErrorFlag()){ 
      holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57)); 
      holder.ErrorMessage.setVisibility(View.VISIBLE); 
      holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage()); 
     } 
    } else if (adapterData.get(position).getChanged()) { 
     holder.ivLineIcon.setImageResource(R.drawable.changedicongreen); 

     holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255)); 
     if (adapterData.get(position).getErrorFlag()){ 
      holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57)); 
      holder.ErrorMessage.setVisibility(View.VISIBLE); 
      holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage()); 
     } 
    } else if (adapterData.get(position).getNewLine()) { 
     holder.ivLineIcon.setImageResource(R.drawable.newlineicon); 

     holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255)); 

     if (adapterData.get(position).getErrorFlag()){ 
      holder.rlItem.setBackgroundColor(Color.rgb(231, 25, 57)); 
      holder.ErrorMessage.setVisibility(View.VISIBLE); 
      holder.ErrorMessage.setText(adapterData.get(position).getErrorMessage()); 
     } 
    } else { 
     holder.ivLineIcon.setImageResource(R.drawable.linesiconblack); 

     holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 255)); 
     holder.ErrorMessage.setVisibility(View.GONE); 
    } 

    if (mSelection.get(position) != null) { 
     //Log.d(TAG, "Item Selected"); 
     holder.rlItem.setBackgroundColor(Color.rgb(255, 255, 192));// this is a selected position so make it hilighted 
    } 

    holder.SubOper.setText(adapterData.get(position).getSubOper()); 
    holder.Spec.setText(adapterData.get(position).getSpecNumber()); 
    holder.Address.setText(adapterData.get(position).getAddress()); 
    holder.SKU.setText(adapterData.get(position).getSKUNumber()); 
    holder.SKUDesc.setText(adapterData.get(position).getSKUDesc()); 
    holder.Quantity.setText(adapterData.get(position).getQuantity()); 
    holder.Unit.setText(adapterData.get(position).getUnit()); 
    holder.BilledQty.setText(adapterData.get(position).getBilledQty()); 
    holder.RemainingQty.setText(adapterData.get(position).getRemainingQty()); 

    return vi; 
} 


public void setNewSelection(int position, boolean value) { 
    mSelection.put(position, value); 
    notifyDataSetChanged(); 
} 

public boolean isPositionChecked(int position) { 
    Boolean result = mSelection.get(position); 
    return result == null ? false : result; 
} 

public Set<Integer> getCurrentCheckedPosition() { 
    return mSelection.keySet(); 
} 

public void removeSelection(int position) { 
    mSelection.remove(position); 
    notifyDataSetChanged(); 
} 

public void clearSelection() { 
    mSelection = new HashMap<Integer, Boolean>(); 
    notifyDataSetChanged(); 
} 

public void setActionMode(boolean isActionMode) 
{ 
    this.isActionMode = isActionMode; 
} 

@Override 
public boolean isEnabled(int position) 
{ 
    final BillingLineItem item = (BillingLineItem) getItem(position); 
    if (!item.getDeleteFlag().equals("true")) 
    { 
     //only enable items that are not inside the basket 
     return true; 
    } 
    //all other items are disabled during actionmode 
    return false; 
} 

public static class ViewHolder { 
    public TextView SubOper; 
    public TextView Spec; 
    public TextView Address; 
    public TextView SKU; 
    public TextView SKUDesc; 
    public TextView Quantity; 
    public TextView Unit; 
    public TextView BilledQty; 
    public TextView RemainingQty; 
    public ImageView ivLineIcon; 
    public RelativeLayout rlItem; 
    public TextView ErrorMessage; 
} 

}

+0

was ist realm.where (BillingLineItem.class) .equalTo ("SpecNumber", spec) .findAll() size() ?!. ist es größer als Null ?! –

+0

Ja, nach der Abfrage ist die Größe dieser Ergebnisse 8 –

+0

Haben Sie den richtigen Wert in Ihrem getitemcount() in Ihrem Adapter? –

Antwort

1

hier einige Informationen hinweisen:

Android auf Java basiert somit ist es Variablen, die durch Referenzwert übergeben werden (More Info). Es bedeutet, dass, wenn Sie ein Objekt:

RealmResults<BillingLineItem> results; 

Und Sie geben diese Variable als Parameter an den Adapter Konstruktor:

adapter = new BillingListAdapter(getActivity(), results); 

Die Liste, die Sie außerhalb des Adapters und die Variable innerhalb der haben Adapter sind eigentlich die gleichen Objekte (zwei Variablen, die auf die gleiche Referenz verweisen).

Nachdem Sie Ihre zweite Abfrage machen:

results = realm.where(BillingLineItem.class) 
      .equalTo("SpecNumber", spec) 
      .findAll(); 

Sie eine neue Referenz zu machen und es im Ergebnisobjekt somit die Liste außerhalb des Adapters und die Liste zu speichern, die Sie zuvor mit dem Adapter übergeben sind buchstäblich anders Objekte, so dass der Adapter die Änderung nicht erkennt und Sie den Fehler erhalten. Sie können es wie folgt beheben:

results.clear(); 
//adapter.notifyDataSetChanged() if you want to show the change before data fetched... 
results.addAll(realm.where(BillingLineItem.class) 
      .equalTo("SpecNumber", spec) 
      .findAll()); 
adapter.notifyDataSetChanged(); 
+0

'clear()' und 'addAll()' Funktionen sind in RealmResults veraltet und ich konnte keine andere Methode finden, um diese Funktionen zu ersetzen. Ich kannte dieses Referenzproblem, ich konnte einfach keinen Weg finden, damit umzugehen. –

+0

@EsatIBIS verwenden Sie dann RealmList dann. Fügen Sie die Ergebnisse zur Liste hinzu und verwenden Sie stattdessen diese Liste. https://github.com/realm/realm-java/blob/master/realm/realm-library/src/main/java/io/realm/RealmList.java –

+0

Die Sache ist, wenn ich zu RealmList ändere, kann ich Führe die Änderungen an den Gegenständen, die ich gerade mache, nicht durch.In diesem Fall muss ich 2 Listen haben, eine wird die RealmResults für Datenänderungen und RealmList für die Anzeigezwecke sein. Ich denke, es ist kein effizienter Weg, Dinge zu tun. –

Verwandte Themen