【问题标题】:Volley gson request on a ExpandableListView causes java.lang.IndexOutOfBoundsExceptionExpandableListView 上的 Volley gson 请求导致 java.lang.IndexOutOfBoundsException
【发布时间】:2017-04-12 13:10:14
【问题描述】:

我有订单列表,在 recyclerview 中,当我点击其中一个订单时,会显示一个新活动,显示该主订单的子订单的可展开列表,现在位于每个子订单的标题我必须显示供应商名称和子订单总价..!

我为 ExpandableListView 使用了this 库,它很棒,当我使用静态数据时它通常对我有用,现在当我尝试从服务器填充 json 数据时,它一直给我下面提到的错误,我 json 很漂亮复杂但我尝试了几天没有运气,模型数据是由 Pojo 生成的。!

下面的 json 链接是我实际链接的简化副本 使用,因为我正在使用的那个充满了数据(你需要一分钟 滚动查看它的最后一个)但下面的那个有确切的 相同的结构..!

JSON URL Link

错误

java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
                                                                                       at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
                                                                                       at java.util.ArrayList.get(ArrayList.java:308)
                                                                                       at com.alaasamizarifa.driver_aghrady.FrontEnd.Adapters.ExpandAdapter$ReyclerViewHolder.SetHeaderData(ExpandAdapter.java:90)
                                                                                       at com.alaasamizarifa.driver_aghrady.FrontEnd.Adapters.ExpandAdapter.onBindViewHolder(ExpandAdapter.java:57)
                                                                                       at com.alaasamizarifa.driver_aghrady.FrontEnd.Adapters.ExpandAdapter.onBindViewHolder(ExpandAdapter.java:23)
                                                                                       at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6356)

仓库内的请求

 final JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, getOrdersURL(FETCH_ORDERS_URI, userID), null,
            new Response.Listener<JSONObject>() {
                @Override
                public void onResponse(JSONObject response) {

                    Gson gson = new Gson();
                    Type listType = new TypeToken<List<OrderPresenter>>() {
                     }.getType();
                    try {

                       List<OrderPresenter> TheOrders;
                        TheOrders = gson.fromJson(response.getJSONArray("orders").toString(), listType);
                        ArrayList<OrderPresenter> result = new ArrayList<>();
                        for (OrderPresenter sub : TheOrders) {
                            sub.getSubOrders().toString();
                            result.addAll(TheOrders);
                        }
                        refreshUi.onSuccess(result);

                    } catch (JSONException e) {
                     refreshUi.onFail(e);
                        Toast.makeText(context, "catched", Toast.LENGTH_SHORT).show();

                    }

                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                   refreshUi.onFail(error);
                }
            });

适配器

   public class ExpandAdapter extends RecyclerView.Adapter<ExpandAdapter.ReyclerViewHolder> {
private LayoutInflater layoutInflater;
private HashSet<Integer> expandedPositionSet = new HashSet<>();
ArrayList<OrderPresenter> theSubOrders;
private Context context;

public ExpandAdapter(ArrayList<OrderPresenter> theSubOrders, Context context) {
    this.layoutInflater = LayoutInflater.from(context);
    this.theSubOrders = theSubOrders;

}

@Override
public ReyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    View item = layoutInflater.inflate(viewType == 0 ? R.layout.cart_item : R.layout.cart_item, parent, false);


    return new ReyclerViewHolder(item);
}

@Override
public void onBindViewHolder(ReyclerViewHolder holder, int position) {

   /* this for showing the icon indicator when expanded or not */
    holder.updateItem(position);

   /* what causes the crash */
    holder.SetHeaderData(theSubOrders.get(position), position);
}

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

@Override
public int getItemCount() {
    return theSubOrders.size();
}

class ReyclerViewHolder extends RecyclerView.ViewHolder {

    private TextView subOrderVendorName;
    private TextView subOrderTotalPrice;

    private ExpandableLayout expandableLayout;
    private ImageView showInfo;


    private ReyclerViewHolder(final View view) {
        super(view);

        subOrderVendorName = (TextView) view.findViewById(R.id.sub_order_vendor_name);
        subOrderTotalPrice = (TextView) view.findViewById(R.id.sub_order_total_price);
        expandableLayout = (ExpandableLayout) view.findViewById(R.id.expandable_layout);
        showInfo = (ImageView) view.findViewById(R.id.showChild);
    }

    public void SetHeaderData(final OrderPresenter data, final int position) {

 subOrderVendorName.setText(data.getSubOrders().get(position).getLineItems().get(position).getProductObject().getVendorName());

        subOrderTotalPrice.setText(data.getSubOrders().get(position).getTotal());   

    }

    private void updateItem(final int position) {
        expandableLayout.setOnExpandListener(new ExpandableLayout.OnExpandListener() {
            @Override
            public void onExpand(boolean expanded) {
                registerExpand(position, showInfo);

            }
        });
        expandableLayout.setExpand(expandedPositionSet.contains(position));

    }
}

private void registerExpand(int position, ImageView plus) {
    if (expandedPositionSet.contains(position)) {
        removeExpand(position);
        plus.setImageResource(R.drawable.ic_add_circle);
    } else {
        addExpand(position);
        plus.setImageResource(R.drawable.ic_remove_circle);
    }
}

private void removeExpand(int position) {
    expandedPositionSet.remove(position);
}

private void addExpand(int position) {
    expandedPositionSet.add(position);
}
}

显示数据的活动

public class OrderDetails extends BaseActivity {

RecyclerView recyclerView;
ExpandAdapter expandAdapter;
ArrayList<OrderPresenter> OrderDetailsList;


@Override
protected void onCreate(Bundle savedInstanceState) {
    setContentView(R.layout.activity_order_details);
    this.title = getString(R.string.OrderDetails);

    super.onCreate(savedInstanceState);
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view1);

    OrderDetailsList = new ArrayList<>();
    final LinearLayoutManager layoutManager = new LinearLayoutManager(this);
    layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(layoutManager);
    expandAdapter = new ExpandAdapter(OrderDetailsList, this);
    expandAdapter.onAttachedToRecyclerView(recyclerView);
    recyclerView.setAdapter(expandAdapter);

    OrderRepository.SubOrdersRequest(this, OrderDetailsList, new RefreshUi() {
        @Override
        public void onSuccess(Object o) {

            OrderDetailsList.addAll((Collection<? extends OrderPresenter>) o);
            Toast.makeText(OrderDetails.this, "" + OrderDetailsList.size(), Toast.LENGTH_SHORT).show();
            expandAdapter.notifyDataSetChanged();
        }

        @Override
        public void onFail(Object o) {

        }
    });


}
}

更新


模型类

OrderPresenter Class

Order Class

Sub_Orders Class

【问题讨论】:

    标签: java android json android-volley expandablelistview


    【解决方案1】:

    适配器的onBindViewHolder 方法内部存在问题。第一次调用theSubOrders.get(position) 应该不会有任何问题,但是它的结果会发送到holder.SetHeaderData 方法,在那里再次获得具有相同position 值的子元素data.getSubOrders().get(position).getTotal()。可能你的意思是改用data.getTotal()

    让我们仔细看看。

    public void SetHeaderData(final OrderPresenter data, final int position) {
        subOrderVendorName.setText(
            data.getSubOrders().get(position) //first
             .getLineItems().get(position) //second
             .getProductObject().getVendorName());
        subOrderTotalPrice.setText(data.getSubOrders().get(position).getTotal()); //third
    }
    

    您在方法中使用了 3 次 position 变量。这是不正常的,因为它是您的data 变量在theSubOrders 列表中的位置。所以你需要彻底改变这个方法。

    删除方法的第二个参数使其类似于public void SetHeaderData(final OrderPresenter data) 的最佳方法。但我不知道你的适配器工作算法,所以我无法获得更换代码的建议。另一种方式 - 在每个 get(position) 调用列表大小的位置检查之前。但对我来说,这似乎是错误的。

    if(data.getSubOrders().size() > position) {
        ... subList = data.getSubOrders().get(position);
        if(subList.size() > position) {
            ... //etc
        }
    }
    

    【讨论】:

    • 让我们从我添加的 json url 中获取 vendor_name 和 total 并在 viewholder 中提到的 textviews 中显示它们,,..!您的 volley 请求将如何以及 setData 方法将如何,..!?请伙计,我为此画了好几天。!
    • @SamZar 我不知道OrderPresenter 类包含什么。你能发布它的代码吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    • 2016-07-25
    • 2019-01-26
    相关资源
    最近更新 更多