【问题标题】:Android - How to handle multidimensional JSON results into a spinner using Volley libraryAndroid - 如何使用 Volley 库将多维 JSON 结果处理为微调器
【发布时间】:2020-04-05 06:06:20
【问题描述】:

我的 android 应用上显示了一个产品列表视图。我正在使用返回 JSON 的 Web 服务。早些时候,我只有一个要显示的产品列表。但是现在对于每个列表,我必须添加一个带有来自 JSON 的 variants 值的微调器。我如何做到这一点?

我目前的代码给了我以下错误

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 168 path $[0].variants

下面是我的代码:

JSON 响应

{
"responce": "true",
"top_selling_product": [
{
"product_id": "10",
"product_name": "Palm Ruchi (Pack of 10)",
"product_name_arb": "",
"product_description_arb": "",
"category_id": "8",
"product_description": "",
"variants": [
{
"variant_id": "7",
"variant_name": "2L",
"in_stock": "0",
"price": "120",
"mrp": "130",
"unit_value": "25"
},
{
"variant_id": "8",
"variant_name": "5L",
"in_stock": "1",
"price": "240",
"mrp": "255",
"unit_value": "25"
},
{
"variant_id": "9",
"variant_name": "10L",
"in_stock": "1",
"price": "0",
"mrp": "0",
"unit_value": "0"
}
],
"product_image": "product-placeholder2.jpg",
"status": "",
"unit": "Box",
"increment": "0",
"rewards": "0",
"stock": "",
"title": "Oil"
},
{
"product_id": "11",
"product_name": "Sunflower Sunrich 1 ltr Box(pack of 10)",
"product_name_arb": "",
"product_description_arb": "",
"category_id": "8",
"product_description": "",
"variants": [],
"product_image": "product-placeholder3.jpg",
"status": "",
"unit": "Box",
"increment": "0",
"rewards": "0",
"stock": "",
"title": "Oil"
},
{
"product_id": "26",
"product_name": "TestName4",
"product_name_arb": "",
"product_description_arb": "",
"category_id": "8",
"product_description": "TestAddress4",
"variants": [],
"product_image": "img8",
"status": "",
"unit": "kg",
"increment": "1",
"rewards": "20",
"stock": "",
"title": "Oil"
}
]
}

Top_Selling_model.java


import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;



public class Top_Selling_model implements Serializable {

    @SerializedName("product_id")
    @Expose
    private String productId;
    @SerializedName("product_name")
    @Expose
    private String productName;
    @SerializedName("product_name_arb")
    @Expose
    private String productNameArb;
    @SerializedName("product_description_arb")
    @Expose
    private String productDescriptionArb;
    @SerializedName("category_id")
    @Expose
    private String categoryId;
    @SerializedName("product_description")
    @Expose
    private String productDescription;
    @SerializedName("variants")
    @Expose
    private List<VariantsModel> variants = null;
    @SerializedName("product_image")
    @Expose
    private String productImage;
    @SerializedName("status")
    @Expose
    private String status;
    @SerializedName("unit")
    @Expose
    private String unit;
    @SerializedName("increment")
    @Expose
    private String increment;
    @SerializedName("rewards")
    @Expose
    private String rewards;
    @SerializedName("stock")
    @Expose
    private String stock;
    @SerializedName("title")
    @Expose
    private String title;

    public String getProductId() {
        return productId;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public String getProductName() {
        return productName;
    }

    public void setProductName(String productName) {
        this.productName = productName;
    }

    public String getProductNameArb() {
        return productNameArb;
    }

    public void setProductNameArb(String productNameArb) {
        this.productNameArb = productNameArb;
    }

    public String getProductDescriptionArb() {
        return productDescriptionArb;
    }

    public void setProductDescriptionArb(String productDescriptionArb) {
        this.productDescriptionArb = productDescriptionArb;
    }

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(String categoryId) {
        this.categoryId = categoryId;
    }

    public String getProductDescription() {
        return productDescription;
    }

    public void setProductDescription(String productDescription) {
        this.productDescription = productDescription;
    }

    public List<VariantsModel> getVariants() {
        return variants;
    }

    public void setVariants(List<VariantsModel> variants) {
        this.variants = variants;
    }

    public String getProductImage() {
        return productImage;
    }

    public void setProductImage(String productImage) {
        this.productImage = productImage;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public String getUnit() {
        return unit;
    }

    public void setUnit(String unit) {
        this.unit = unit;
    }

    public String getIncrement() {
        return increment;
    }

    public void setIncrement(String increment) {
        this.increment = increment;
    }

    public String getRewards() {
        return rewards;
    }

    public void setRewards(String rewards) {
        this.rewards = rewards;
    }

    public String getStock() {
        return stock;
    }

    public void setStock(String stock) {
        this.stock = stock;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }




}

Variants_model.java


import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

import java.io.Serializable;

public class VariantsModel implements Serializable {

    @SerializedName("variant_id")
    @Expose
    private String variantId;
    @SerializedName("variant_name")
    @Expose
    private String variantName;
    @SerializedName("in_stock")
    @Expose
    private String inStock;
    @SerializedName("price")
    @Expose
    private String price;
    @SerializedName("mrp")
    @Expose
    private String mrp;
    @SerializedName("unit_value")
    @Expose
    private String unitValue;

    public String getVariantId() {
        return variantId;
    }

    public void setVariantId(String variantId) {
        this.variantId = variantId;
    }

    public String getVariantName() {
        return variantName;
    }

    public void setVariantName(String variantName) {
        this.variantName = variantName;
    }

    public String getInStock() {
        return inStock;
    }

    public void setInStock(String inStock) {
        this.inStock = inStock;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    public String getMrp() {
        return mrp;
    }

    public void setMrp(String mrp) {
        this.mrp = mrp;
    }

    public String getUnitValue() {
        return unitValue;
    }

    public void setUnitValue(String unitValue) {
        this.unitValue = unitValue;
    }

}

Top_sales_Adapter.java


import android.content.Context;
import android.content.SharedPreferences;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;

import java.util.ArrayList;
import java.util.List;

import Config.BaseURL;
import Model.Top_Selling_model;
import gogrocer.tcc.R;

import static android.content.Context.MODE_PRIVATE;


public class Top_Selling_Adapter extends RecyclerView.Adapter<Top_Selling_Adapter.MyViewHolder> {

    private List<Top_Selling_model> modelList;
    ArrayList<String> variantsData = new ArrayList<>();
    private Context context;
SharedPreferences preferences;
    public class MyViewHolder extends RecyclerView.ViewHolder {
        public TextView product_nmae, product_prize;
        public ImageView image;
        public Spinner spinner;

        public MyViewHolder(View view) {
            super(view);
            product_nmae = (TextView) view.findViewById(R.id.product_name);
            product_prize = (TextView) view.findViewById(R.id.product_prize);
            image = (ImageView) view.findViewById(R.id.iv_icon);
            spinner=(Spinner) view.findViewById(R.id.variants);

        }
    }

    public Top_Selling_Adapter(List<Top_Selling_model> modelList) {
        this.modelList = modelList;
    }

    @Override
    public Top_Selling_Adapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.row_top_selling, parent, false);
        context = parent.getContext();
        return new Top_Selling_Adapter.MyViewHolder(itemView);
    }
    @Override
    public void onBindViewHolder(Top_Selling_Adapter.MyViewHolder holder, int position) {
        Top_Selling_model mList = modelList.get(position);
         preferences = context.getSharedPreferences("lan", MODE_PRIVATE);
    String language=preferences.getString("language","");
        Glide.with(context)
                .load(BaseURL.IMG_PRODUCT_URL + mList.getProduct_image())
                .placeholder(R.drawable.icon)
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .dontAnimate()
                .into(holder.image);
      //  variantsData.add(mList.getVariants().getVariantName());
        Log.e("Top_selling_array",mList.getVariants().getVariantName());
        holder.product_prize.setText(context.getResources().getString(R.string.currency) + mList.getVariants().getPrice());
       // Log.e("Top_selling_array",mList.getVariants().toString());
        if (language.contains("english")) {
            holder.product_nmae.setText(mList.getProduct_name());
        }
        else {
            holder.product_nmae.setText(mList.getProduct_name_arb());

        }

    }

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

}

Home_fragment.java

private void make_top_selling() {
        String tag_json_obj = "json_category_req";
        ArrayList<VariantsModel> variantsList = new ArrayList<VariantsModel>();
        isSubcat = false;
        Map<String, String> params = new HashMap<String, String>();
        params.put("parent", "");
        isSubcat = true;
       /* if (parent_id != null && parent_id != "") {
        }*/

        CustomVolleyJsonRequest jsonObjReq = new CustomVolleyJsonRequest(Request.Method.POST,
                BaseURL.GET_TOP_SELLING_PRODUCTS, params, new Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                Log.d(TAG, response.toString());

                try {
                    if (response != null && response.length() > 0) {
                        Boolean status = response.getBoolean("responce");
                        if (status) {
                            Gson gson = new Gson();
                            Type listType = new TypeToken<List<Top_Selling_model>>() {
                            }.getType();
                            Type listType2 = new TypeToken<List<VariantsModel>>() {
                            }.getType();
                            top_selling_models = gson.fromJson(response.getString("top_selling_product"), listType);
                            top_selling_adapter = new Top_Selling_Adapter(top_selling_models);
                            rv_top_selling.setAdapter(top_selling_adapter);
                            top_selling_adapter.notifyDataSetChanged();
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new Response.ErrorListener() {

            @Override
            public void onErrorResponse(VolleyError error) {
                VolleyLog.d(TAG, "Error: " + error.getMessage());
                if (error instanceof TimeoutError || error instanceof NoConnectionError) {
                    Toast.makeText(getActivity(), getResources().getString(R.string.connection_time_out), Toast.LENGTH_SHORT).show();
                }
            }
        });
        jsonObjReq.setRetryPolicy(new DefaultRetryPolicy(
                retry,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        // Adding request to request queue
        // Adding request to request queue
        AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);

    }

CustomVolleyJsonRequest.java

public class CustomVolleyJsonRequest extends Request<JSONObject> {

    private Response.Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomVolleyJsonRequest(String url, Map<String, String> params,
                                   Response.Listener<JSONObject> reponseListener, Response.ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    public CustomVolleyJsonRequest(int method, String url, Map<String, String> params,
                                   Response.Listener<JSONObject> reponseListener, Response.ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    protected Map<String, String> getParams()
            throws com.android.volley.AuthFailureError {
        return params;
    };

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                    HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
        }
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        // TODO Auto-generated method stub
        listener.onResponse(response);
    }
}

编辑:更改了我的 POJO 课程。

【问题讨论】:

    标签: java android android-volley


    【解决方案1】:

    根据此 JsonResponce,我认为您的模型存在问题。 将您的 json 响应粘贴到此处 https://jsoneditoronline.org 并查看格式化的 json 并将您的 json http://www.jsonschema2pojo.org 粘贴到此处以创建模型。在http://www.jsonschema2pojo.org 你必须选择目标语言Java, 源类型 Json、Annotation Style Gson 和预览。从那里获取您的模型,然后重试。

    【讨论】:

    • 感谢您的回复。我已经更改了我的 POJO 类,并且能够解决上述问题。但是,我仍然需要弄清楚如何将这些 variants 填充到微调器中。你能帮忙吗?
    • 您需要一个微调器适配器。在您的 json 响应中,您有变体作为每个产品的列表。您必须从此列表中获取值并将其放入适配器中。这是一个微调器适配器的简单示例mkyong.com/android/android-spinner-drop-down-list-example
    • 嗨@okan,我如何访问 JSON 中的值,例如:在我的 Top_ sell_Adapter.java 中,我尝试使用 variantsData.add(mList.getVariants().get(position).getVariantName()); 将 Variants 添加到 Arraylist 中,但它给了我 java.lang.IndexOutOfBoundsException: Index: 1, Size: 0
    • 我认为这是错误的,因为每个产品都有 3 个变体。因此,您必须为每个变体列表创建 for 循环。
    • 我为您添加了另一个答案。您需要有 2 个 for 循环。一个用于您的 mList。一个用于 mList 成员中的 variantList。
    【解决方案2】:

    for (mList:mList){
       for (variant : Variants){
          variantList.add (variant)
       }
    }

    【讨论】:

    • 嗨@okan,你能帮我看看我在我的Top_ sell_Adapter.java 中的哪里添加这个。我还不太明白如何使用这个
    • 您想在一个微调器中显示所有变体吗?或者您的 listViews 每个项目都有更多的微调器?哪个
    • 我每件商品只有一个微调器。所以,我想在微调器中显示该项目的所有变体。
    • 首先创建一个字符串列表。 List 类别 = new ArrayList();
    • 如果你用可以生成微调器的 sn-ps 指导我。这真的很有帮助。
    【解决方案3】:

    首先创建一个字符串列表。

    List<String> variantNameList = new ArrayList<String>();
    
    
    
    for (mList:mList){
       for (variant : Variants){
          variantNameList.add (variant. variant_name)
       }
    } 
    

    这是包含所有变体名称的列表。那你需要一个适配器

    // 为微调器创建适配器

    ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,  variantNameList);
    

    // 下拉布局样式 - 带有单选的列表视图

    buttondataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    

    // 将数据适配器附加到微调器

    spinner.setAdapter(dataAdapter);
    

    就是这样

    【讨论】:

    • 嗨@okan,我收到for循环错误。我没有任何名称为Variants 的数组。它显示错误说Cannot resolve symbol Variants。我可以使用mList.getProductName(); 访问产品名称。但不确定如何访问数组中的variants 对象。
    • 您必须从您的 mList 中获取变体。 mList.getVariants
    • 这是我一直在尝试的for (mList:mList){ for (variant : mList.getVariants()){ variantNameList.add (variant.variant_name); } } 但它不获取变量对象。不知道我做错了什么
    • 有一个适配器,其中包含您的 String ArrayList 作为variantNames。并且有一个使用此列表的适配器。首先,您必须将您的列表设置到您的微调器适配器中,然后您必须将您的适配器设置到您的微调器。就这样。我认为你必须在没有你的项目的情况下制作微调器。学习并应用到您的项目中
    • 您尝试调试它吗?确保您有来自远程的 json 响应。您可以通过调试确定它或将您的 jsonResponse 写入 LogCat 并检查它
    猜你喜欢
    • 2018-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多