我在移动应用程序中使用Realm存储列表视图的订单项。我正在扩展RealmBaseAdapter,它工作正常。问题是,如果我对数据库进行查询以过滤我的项目,那么我的适配器不会拾取更改的列表并导致out of bound index
错误。
这是我使用初始值
设置我的适配器的地方results = realm.where(BillingLineItem.class).findAll();
adapter = new BillingListAdapter(getActivity(), results);
这是我根据规范编号进行过滤的部分,
results = realm.where(BillingLineItem.class)
.equalTo("SpecNumber", spec)
.findAll();
adapter.notifyDataSetChanged();
就像我之前说过的那样,查询结果将会更新,但适配器不会接收更改。
编辑:我的列表视图适配器
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 :(得分:1)
这里要指出的一些信息:
Android基于java,因此它的变量通过引用值(More Info)传递。 这意味着如果你有一个对象:
RealmResults<BillingLineItem> results;
并将此变量作为参数传递给Adapter构造函数:
adapter = new BillingListAdapter(getActivity(), results);
适配器外部的列表和适配器内的变量实际上是相同的对象(指向同一引用的两个变量)。
进行第二次查询后:
results = realm.where(BillingLineItem.class)
.equalTo("SpecNumber", spec)
.findAll();
您正在创建一个新引用并将其存储在结果对象中,因此适配器外部的列表以及之前传递给适配器的列表实际上是不同的对象,因此适配器将无法检测到更改而您获得错误。你可以像这样解决它:
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();