【问题标题】:Loading Images into Recycler View Using Picasso. Recycler View Not Displaying使用 Picasso 将图像加载到 Recycler 视图中。回收站视图不显示
【发布时间】:2019-05-19 14:46:53
【问题描述】:

我有一个应用程序可以解析 JSON 数据并将其显示到回收站视图中。回收器视图中的每个项目都是 Reps 类的对象,并包含在卡片布局中。当我只尝试解析字符串变量时,代码工作正常。

当我尝试将图像 URL 解析到 ImageView 中时,回收器视图不显示并且活动为空白。我正在使用 Picasso 将图像加载到我的适配器类中的 onBinfViewHolder 方法中。这是相关代码

代表:

public class Reps {
private String officeName;
private String officialName;
private String party;
private String photoUrl;

//continue to develop this with other values such as phone, photo, address etc.


public Reps(String officeName, String officialName, String party, String photoUrl) {
    this.officeName = officeName;
    this.officialName = officialName;
    this.party = party;
    this.photoUrl = photoUrl;
}



public Reps(String officeName, String officialName, String party) {
    this.officeName = officeName;
    this.officialName = officialName;
    this.party = party;
}

public Reps(String officeName) {
    this.officeName = officeName;
}

public Reps(String name, String party) {
    this.officialName = name;
    this.party = party;
}


public String getOfficeName() {
    return officeName;
}

public void setOfficeName(String officeName) {
    this.officeName = officeName;
}

public String getOfficialName() {
    return officialName;
}

public void setOfficialName(String officialName) {
    this.officialName = officialName;
}

public String getParty() {
    return party;
}

public void setParty(String party) {
    this.party = party;
}

public String getPhotoUrl() {
    return photoUrl;
}

public void setPhotoUrl(String photoUrl) {
    this.photoUrl = photoUrl;
}

}

RepRvAdapter:

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

private Context context;
private List<Reps> repsList;
RequestOptions option;

public RepRvAdapter() {

}

public RepRvAdapter(List<Reps> repList, Context applicationContext) {
    this.repsList = repList;
    this.context = applicationContext;

}


@NonNull
@Override
public RepRvAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view;
    LayoutInflater mInflater = LayoutInflater.from(context);
    view = mInflater.inflate(R.layout.card, viewGroup, false);         //Inflate view to card.xml
    return new MyViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull RepRvAdapter.MyViewHolder myViewHolder, int i) {
    myViewHolder.officeName.setText(repsList.get(i).getOfficeName());               //Display these three elements in the card view
    myViewHolder.officialName.setText(repsList.get(i).getOfficialName());
    myViewHolder.party.setText(repsList.get(i).getParty());
    //load image into card view
    Picasso.get()
            .load(repsList.get(i).getPhotoUrl())
            .centerCrop()
            .transform(new CircleTransform(50, 0))
            .fit()
            .into(myViewHolder.photoUrl);
}

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

public static class MyViewHolder extends RecyclerView.ViewHolder {
    //Variables
    TextView officeName, officialName, party;         //Only the Referendum title and type will be in the recycler view
    ImageView photoUrl;
    public MyViewHolder(View itemView){
        super(itemView);
        officeName = itemView.findViewById(R.id.office_name);
        officialName = itemView.findViewById(R.id.official_name);
        party = itemView.findViewById(R.id.party);
        photoUrl = itemView.findViewById(R.id.photo_url);
    }
}

}

解析JSON数据的方法:

 //fetch json data from Civic API
private void getData(){
    final ProgressDialog progressDialog = new ProgressDialog(this);
    progressDialog.setMessage("Loading...");
    progressDialog.show();

    StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            progressDialog.dismiss();
            try{
                JSONObject jsonObject = new JSONObject(response);
                //first loop through offices array. Retrieve officeName value
                JSONArray officesArray = jsonObject.getJSONArray("offices");        //One array for offices
                JSONArray officialsArray = jsonObject.getJSONArray("officials");    //one array for officials
                for (int i = 0; i < officesArray.length(); i++){
                    JSONObject jsonOffices = officesArray.getJSONObject(i);
                    JSONObject jsonOfficials = officialsArray.getJSONObject(i);
                    Reps reps = new Reps (jsonOfficials.getString("name"),
                            jsonOfficials.getString("party"),
                            //jsonOfficials.getString("photoUrl")
                            jsonOffices.getString("name"));
                    repList.add(reps);
                }
                adapter = new RepRvAdapter(repList, getApplicationContext());
                myrv.setAdapter(adapter);
            }catch (JSONException e){
                e.printStackTrace();
            }
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e("Volley", error.toString());
            progressDialog.dismiss();
        }
    });
    RequestQueue requestQueue = Volley.newRequestQueue(this);
    requestQueue.add(stringRequest);
}

现在,我将解析图像 URL 的代码行注释掉了。取消注释该行后,该活动将不再显示。如何让 Image url 被解析并显示在 ImageView 中?我认为这可能是 JSON 数据的问题。在 JSON 数组中,并未设置所有 photoUrl 字段。 API 可能不会为数组中的每个代表返回图像数据,而party、name 和 office 字段始终具有值。这可能是阻止回收站视图显示的原因吗?这是一段相关的 JSON 数据:

"officials": [
  {
   "name": "Donald J. Trump",
   "address": [
    {
     "line1": "The White House",
     "line2": "1600 Pennsylvania Avenue NW",
     "city": "Washington",
     "state": "DC",
     "zip": "20500"
    }
   ],
   "party": "Republican",
   "phones": [
    "(202) 456-1111"
   ],    
    "photoUrl":"https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/PE%20Color.jpg",
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+whitehouse"
    },
    {
     "type": "Facebook",
     "id": "whitehouse"
    },
    {
     "type": "Twitter",
     "id": "potus"
    },
    {
     "type": "YouTube",
     "id": "whitehouse"
    }
   ]
  },
  {
   "name": "Mike Pence",
   "address": [
    {
     "line1": "The White House",
     "line2": "1600 Pennsylvania Avenue NW",
     "city": "Washington",
     "state": "DC",
     "zip": "20500"
    }
   ],
   "party": "Republican",
   "phones": [
    "(202) 456-1111"
   ],
   "photoUrl":"https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/VPE%20Color.jpg",
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+whitehouse"
    },
    {
     "type": "Facebook",
     "id": "whitehouse"
    },
    {
     "type": "Twitter",
     "id": "VP"
    }
   ]
  },
  {
   "name": "Dianne Feinstein",
   "address": [
    {
     "line1": "331 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3841"
   ],
   "photoUrl": "http://bioguide.congress.gov/bioguide/photo/F/F000062.jpg",
   "channels": [
    {
     "type": "Facebook",
     "id": "SenatorFeinstein"
    },
    {
     "type": "Twitter",
     "id": "SenFeinstein"
    },
    {
     "type": "YouTube",
     "id": "SenatorFeinstein"
    }
   ]
  },
  {
   "name": "Kamala D. Harris",
   "address": [
    {
     "line1": "112 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3553"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "KamalaHarris"
    },
    {
     "type": "YouTube",
     "id": "UC0XBsJpPhOLg0k4x9ZwrWzw"
    }
   ]

如您所见,所有代表都有姓名、政党和办公室,但并非所有代表都有图片 URL。 logcat 会返回这个关于它的信息。

我愿意尝试不同的库。如果您需要查看更多代码,请告诉我。感谢您的帮助!

我在我的 jsonParse 方法中添加了以下条件来说明没有 photoUrl 字段的对象。

try{
                JSONObject jsonObject = new JSONObject(response);
                //first loop through offices array. Retrieve officeName value
                JSONArray officesArray = jsonObject.getJSONArray("offices");        //One array for offices
                JSONArray officialsArray = jsonObject.getJSONArray("officials");    //one array for officials
                for (int i = 0; i < officesArray.length(); i++){
                    JSONObject jsonOffices = officesArray.getJSONObject(i);
                    JSONObject jsonOfficials = officialsArray.getJSONObject(i);
                   if(jsonOfficials.has("photoUrl")){
                        Reps reps = new Reps (jsonOfficials.getString("name"),
                                jsonOfficials.getString("party"),
                                jsonOfficials.getString("photoUrl"),
                                jsonOffices.getString("name"));
                        repList.add(reps);
                    }else{
                       Reps reps = new Reps(jsonOfficials.getString("name"),
                               jsonOfficials.getString("party"),
                               jsonOffices.getString("name"));
                       repList.add(reps);
                   }
                }
                adapter = new RepRvAdapter(repList, getApplicationContext());
                myrv.setAdapter(adapter);

使用此代码,recycler 视图显示,但图像 URL 字符串显示在 officeName 文本视图中,而不是 ImageView 中的图像。

由于上次官方没有图片,所以他们的数据显示正确。

【问题讨论】:

  • 让你检查 logcat 是否有任何错误还有你在清单文件中添加了互联网权限
  • @Gabriel 在添加加载之前尝试解析你的 uri,使用 Uri.parse(repsList.get(i).getPhotoUrl())
  • @NileshRathod Internet 权限已关闭。 logcat 说 JSONException: No value for photoUrl

标签: android json parsing android-recyclerview picasso


【解决方案1】:

JSON 响应中有错误。试试这个

    [{
        "name": "Donald J. Trump",
        "address": [{
            "line1": "The White House",
            "line2": "1600 Pennsylvania Avenue NW",
            "city": "Washington",
            "state": "DC",
            "zip": "20500"
        }],
        "party": "Republican",
        "phones": [
            "(202) 456-1111"
        ],
        "photoUrl": "https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/PE%20Color.jpg",
        "channels": [{
                "type": "GooglePlus",
                "id": "+whitehouse"
            },
            {
                "type": "Facebook",
                "id": "whitehouse"
            },
            {
                "type": "Twitter",
                "id": "potus"
            },
            {
                "type": "YouTube",
                "id": "whitehouse"
            }
        ]
    },
{
   "name": "Mike Pence",
   "address": [
    {
     "line1": "The White House",
     "line2": "1600 Pennsylvania Avenue NW",
     "city": "Washington",
     "state": "DC",
     "zip": "20500"
    }
   ],
   "party": "Republican",
   "phones": [
    "(202) 456-1111"
   ],
   "photoUrl":"https://www.whitehouse.gov/sites/whitehouse.gov/files/images/45/VPE%20Color.jpg",
   "channels": [
    {
     "type": "GooglePlus",
     "id": "+whitehouse"
    },
    {
     "type": "Facebook",
     "id": "whitehouse"
    },
    {
     "type": "Twitter",
     "id": "VP"
    }
   ]
  },
  {
   "name": "Dianne Feinstein",
   "address": [
    {
     "line1": "331 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3841"
   ],
   "photoUrl": "http://bioguide.congress.gov/bioguide/photo/F/F000062.jpg",
   "channels": [
    {
     "type": "Facebook",
     "id": "SenatorFeinstein"
    },
    {
     "type": "Twitter",
     "id": "SenFeinstein"
    },
    {
     "type": "YouTube",
     "id": "SenatorFeinstein"
    }
   ]
  },
  {
   "name": "Kamala D. Harris",
   "address": [
    {
     "line1": "112 Hart Senate Office Building",
     "city": "Washington",
     "state": "DC",
     "zip": "20510"
    }
   ],
   "party": "Democratic",
   "phones": [
    "(202) 224-3553"
   ],
   "channels": [
    {
     "type": "Twitter",
     "id": "KamalaHarris"
    },
    {
     "type": "YouTube",
     "id": "UC0XBsJpPhOLg0k4x9ZwrWzw"
    }
]
}
]

【讨论】:

  • JSON 响应由 google civic API 生成。我认为当我将 JSON 代码复制到堆栈溢出时发生了错误。有一些格式问题,所以我不得不手动进行编辑。
【解决方案2】:

问题#1:发生 JSON 异常当您尝试解析“photoUrl”时,导致最后一个官员对象中不存在名为“photoUrl”的字段。

{
      "name": "Kamala D. Harris",
      "address": [
        {
          "line1": "112 Hart Senate Office Building",
          "city": "Washington",
          "state": "DC",
          "zip": "20510"
        }
      ],
      "party": "Democratic",
      "phones": [
        "(202) 224-3553"
      ],
      "channels": [
        {
          "type": "Twitter",
          "id": "KamalaHarris"
        },
        {
          "type": "YouTube",
          "id": "UC0XBsJpPhOLg0k4x9ZwrWzw"
        }
      ]
    }

解决方案#1:只需将代码放在如下条件中:

String photoUrl = "";
if (jsonOfficials.has("photoUrl")) {
   photoUrl = jsonOfficials.getString("photoUrl");
}

问题#2:请检查您的“Reps”类第一个构造函数。在这里,您将“photoUrl”字段作为第四个参数,但是当您创建“Reps”类的对象时,您将“photoUrl”字段作为第三个参数传递。

解决方案#2:

Reps reps = new Reps (jsonOfficials.getString("name"),
    jsonOfficials.getString("party"),
    jsonOffices.getString("name"),
    jsonOfficials.getString("photoUrl"));

【讨论】:

  • 我在哪里添加这个条件?是否在 for 循环中?
  • 我添加了条件,现在显示活动,但显示的是图像 url 字符串而不是图像。
  • @Gabriel 请检查您的“Reps”类第一个构造函数。在这里,您将“photoUrl”字段作为第四个参数,但是当您创建“Reps”类的对象时,您将“photoUrl”字段作为第三个参数传递。代表代表 = 新代表 (jsonOfficials.getString("name"), jsonOfficials.getString("party"), jsonOffices.getString("name"), jsonOfficials.getString("photoUrl")));
  • 感谢您的帮助!这可行,但现在只显示几张图片,而不是全部。
猜你喜欢
  • 2018-02-06
  • 1970-01-01
  • 2018-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-28
相关资源
最近更新 更多