Android Studio: Parsing Multiple Nested JSON arrays
I am working on a project that parses JSON data from the Google Civic API and displays it to the user. First, the data will be displayed in a recycler view, showing the office name, candidate photo, candidate name and candidate party for each person participating in the election. According to the JSON response, the minimum amount of people that can participate in the election is 2 and the maximum is four. Here is what the layout looks like.
A list of elections will be shown in the recycler view with a brief glimpse of the candidate information. Once the user clicks on a particular election, they will be directed to another activity that shows the full details of the contest.
My first question is how can structure my class. Do I create an object for each candidate, or do I create an object for the entire election. Here is my current implementation for the Elects class.
package com.example.gabe.politicianspulse;
public class Elects {
private String officeName;
private String officeType;
private String officeLevel;
private String districtName;
private String candidateName1;
private String candidateName2;
private String candidateName3;
private String candidateName4;
private String candidateParty1;
private String candidateParty2;
private String candidateParty3;
private String candidateParty4;
private String candidateURL1;
private String candidateURL2;
private String candidateURL3;
private String candidateURL4;
private String photoUrl1;
private String photoUrl2;
private String photoUrl3;
private String photoUrl4;
//constructor with all data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4,
String photoUrl1, String photoUrl2, String photoUrl3, String photoUrl4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
this.photoUrl3 = photoUrl3;
this.photoUrl4 = photoUrl4;
}
//constructor with 1 candidate
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1, String photoUrl1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
this.photoUrl1 = photoUrl1;
}
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
}
//constructor with 2 candidates
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateParty1, String candidateParty2, String candidateURL1, String candidateURL2, String photoUrl1, String photoUrl2) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
}
//Constructor with no photo data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
}
Here is a snippet from the JSON response from my url request
{
"contests": [
{
"type": "General",
"office": "US House - District 31",
"level": [
"country"
],
"roles": [
"legislatorLowerBody"
],
"district": {
"name": "California's 31st congressional district",
"scope": "congressional",
"id": "ocd-division/country:us/state:ca/cd:31"
},
"candidates": [
{
"name": "Pete Aguilar",
"party": "Democratic",
"candidateUrl": "http://www.peteaguilar.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PeteAguilarforCongress"
},
{
"type": "Twitter",
"id": "https://twitter.com/aguilarpete"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCIXCmfuRWrbgdTw257_lxJQ"
}
]
},
{
"name": "Paul Chabot",
"party": "Republican",
"candidateUrl": "http://www.paulchabot.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PaulChabotCalifornia"
},
{
"type": "Twitter",
"id": "https://twitter.com/DrPaulChabot"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/Voteforaveteran"
}
]
}
]
},
{
"type": "General",
"office": "Governor",
"level": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
],
"district": {
"name": "California",
"scope": "statewide",
"id": "ocd-division/country:us/state:ca"
},
"candidates": [
{
"name": "Edmund G. "Jerry" Brown",
"party": "Democratic",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/jerrybrown"
},
{
"type": "Twitter",
"id": "https://twitter.com/JerryBrownGov"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/+JerryBrown"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/JerryBrown2010"
}
]
},
{
"name": "Neel Kashkari",
"party": "Republican",
"candidateUrl": "http://www.neelkashkari.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/neelkashkari"
},
{
"type": "Twitter",
"id": "https://twitter.com/neelkashkari"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/111272745095197246971"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCGhIiUj05N8mlUNeiKbYfsA"
}
]
}
]
}
Right now, my parsing method only creates an object for a single candidate because I'm not sure how to parse data for all candidates, but before solving this problem, I would like to tackle the immediate issue. When the activity tries to run, an empty activity is displayed with nothing populating the recycler view. The log cat points to my getData() function saying there is no value for "district". The district and candidate JSON arrays are nested arrays within the "contests" array. Could this be why the value for district is not found? How can I navigate through the district and candidates JSON arrays?
getData():
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);
//Three arrays for each JSON array
JSONArray contestsArray = jsonObject.getJSONArray("contests");
JSONArray districtArray = jsonObject.getJSONArray("district");
JSONArray candidatesArray = jsonObject.getJSONArray("candidates");
for (int i = 0; i < contestsArray.length(); i++) {
JSONObject jsonContests = contestsArray.getJSONObject(i);
JSONObject jsonDistrict = districtArray.getJSONObject(i);
JSONObject jsonCandidates = candidatesArray.getJSONObject(i);
if(jsonCandidates.has("photoUrl")){ //Create case for no PhotoUrl
Elects x = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"),
jsonCandidates.getString("photoUrl"));
electsList.add(x);
} else{
Elects a = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"));
electsList.add(a);
}
}
adapter = new ElectsRvAdapter(getApplicationContext(), electsList);
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);
}
}
Logcat Error:
Other relevant code:
ElectsRvAdapter: Recycler view adapter for the Elect class
public class ElectsRvAdapter extends
RecyclerView.Adapter<ElectsRvAdapter.MyViewHolder> {
private Context context;
private List<Elects> electsList;
public ElectsRvAdapter(){
}
public ElectsRvAdapter(Context context, List<Elects> electsList){
this.context = context;
this.electsList = electsList;
}
@NonNull
@Override
public ElectsRvAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v;
LayoutInflater mInflater = LayoutInflater.from(context);
v = mInflater.inflate(R.layout.election_card, viewGroup, false);
final MyViewHolder viewHolder = new MyViewHolder(v);
viewHolder.electionContainer.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
Intent i = new Intent(context, SingleElection.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("office", electsList.get(viewHolder.getAdapterPosition()).getOfficeName());
i.putExtra("type", electsList.get(viewHolder.getAdapterPosition()).getOfficeType());
i.putExtra("level", electsList.get(viewHolder.getAdapterPosition()).getOfficeLevel());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getDistrictName());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName1());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName2());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName3());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName4());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty1());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty2());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty3());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty4());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL1());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL2());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL3());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL4());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl1());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl2());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl3());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl4());
context.startActivity(i);
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ElectsRvAdapter.MyViewHolder myViewHolder, int i) {
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName4.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty4.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
}
@Override
public int getItemCount() {
return electsList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
TextView officeName, candidateName1, candidateName2, candidateName3,
candidateName4, candidateParty1, candidateParty2,
candidateParty3, candidateParty4;
ImageView photoUrl1, photoUrl2, photoUrl3, photoUrl4;
LinearLayout electionContainer;
public MyViewHolder(View itemView){
super(itemView);
officeName = itemView.findViewById(R.id.office_name);
candidateName1 = itemView.findViewById(R.id.candidate_name1);
candidateName2 = itemView.findViewById(R.id.candidate_name2);
candidateName3 = itemView.findViewById(R.id.candidate_name3);
candidateName4 = itemView.findViewById(R.id.candidate_name4);
candidateParty1 = itemView.findViewById(R.id.candidate_party1);
candidateParty2 = itemView.findViewById(R.id.candidate_party2);
candidateParty3 = itemView.findViewById(R.id.candidate_party3);
candidateParty4 = itemView.findViewById(R.id.candidate_party4);
photoUrl1 = itemView.findViewById(R.id.photo_url1);
photoUrl2 = itemView.findViewById(R.id.photo_url2);
photoUrl3 = itemView.findViewById(R.id.photo_url3);
photoUrl4 = itemView.findViewById(R.id.photo_url4);
electionContainer = itemView.findViewById(R.id.elections_container);
}
}
}
SingleElection: Activity that displays more detailed information about the election
public class SingleElection extends AppCompatActivity {
private List<Elects> electsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_election);
electsList = new ArrayList<>();
//recieve data
String name = getIntent().getExtras().getString("office");
String type = getIntent().getExtras().getString("type");
String level = getIntent().getExtras().getString("level");
String dName = getIntent().getExtras().getString("name");
String cName1 = getIntent().getExtras().getString("name");
String cName2 = getIntent().getExtras().getString("name");
String cName3 = getIntent().getExtras().getString("name");
String cName4 = getIntent().getExtras().getString("name");
String cParty1 = getIntent().getExtras().getString("party");
String cParty2 = getIntent().getExtras().getString("party");
String cParty3 = getIntent().getExtras().getString("party");
String cParty4 = getIntent().getExtras().getString("party");
String cUrl1 = getIntent().getExtras().getString("candidateUrl");
String cUrl2 = getIntent().getExtras().getString("candidateUrl");
String cUrl3 = getIntent().getExtras().getString("candidateUrl");
String cUrl4 = getIntent().getExtras().getString("candidateUrl");
String photoUrl1 = getIntent().getExtras().getString("photoUrl");
String photoUrl2 = getIntent().getExtras().getString("photoUrl");
String photoUrl3 = getIntent().getExtras().getString("photoUrl");
String photoUrl4 = getIntent().getExtras().getString("photoUrl");
//Initialize Views
TextView nameTv = findViewById(R.id.office);
TextView typeTv = findViewById(R.id.type);
TextView levelTv = findViewById(R.id.level);
TextView dNameTv = findViewById(R.id.district_name);
TextView cNameTv1 = findViewById(R.id.c_name1);
TextView cNameTv2 = findViewById(R.id.c_name2);
TextView cNameTv3 = findViewById(R.id.c_name3);
TextView cNameTv4 = findViewById(R.id.c_name4);
TextView cPartyTv1 = findViewById(R.id.c_party1);
TextView cPartyTv2 = findViewById(R.id.c_party2);
TextView cPartyTv3 = findViewById(R.id.c_party3);
TextView cPartyTv4 = findViewById(R.id.c_party4);
TextView cUrlTv1 = findViewById(R.id.c_url1);
TextView cUrlTv2 = findViewById(R.id.c_url2);
TextView cUrlTv3 = findViewById(R.id.c_url3);
TextView cUrlTv4 = findViewById(R.id.c_url4);
ImageView photoUrlTv1 = findViewById(R.id.photo1);
ImageView photoUrlTv2 = findViewById(R.id.photo2);
ImageView photoUrlTv3 = findViewById(R.id.photo3);
ImageView photoUrlTv4 = findViewById(R.id.photo4);
//set string values to each view
nameTv.setText(name);
typeTv.setText(type);
levelTv.setText(level);
dNameTv.setText(dName);
cNameTv1.setText(name);
cNameTv2.setText(name);
cNameTv3.setText(name);
cNameTv4.setText(name);
cPartyTv1.setText(name);
cPartyTv2.setText(name);
cPartyTv3.setText(name);
cPartyTv4.setText(name);
cUrlTv1.setText(name);
cUrlTv2.setText(name);
cUrlTv3.setText(name);
cUrlTv4.setText(name);
//set image
Picasso.get()
.load(photoUrl1)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv1);
Picasso.get()
.load(photoUrl2)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv2);
Picasso.get()
.load(photoUrl3)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv3);
Picasso.get()
.load(photoUrl4)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv4);
}
}
To sum up:
- How can I alter rmy getData() function to properly iterate through nested JSON arrays.
- How should I structure my Elects class to receive the JSON data in the easiest, most efficient way?
Thanks Much! If you need any more code, let me know.
java arrays json android-recyclerview
add a comment |
I am working on a project that parses JSON data from the Google Civic API and displays it to the user. First, the data will be displayed in a recycler view, showing the office name, candidate photo, candidate name and candidate party for each person participating in the election. According to the JSON response, the minimum amount of people that can participate in the election is 2 and the maximum is four. Here is what the layout looks like.
A list of elections will be shown in the recycler view with a brief glimpse of the candidate information. Once the user clicks on a particular election, they will be directed to another activity that shows the full details of the contest.
My first question is how can structure my class. Do I create an object for each candidate, or do I create an object for the entire election. Here is my current implementation for the Elects class.
package com.example.gabe.politicianspulse;
public class Elects {
private String officeName;
private String officeType;
private String officeLevel;
private String districtName;
private String candidateName1;
private String candidateName2;
private String candidateName3;
private String candidateName4;
private String candidateParty1;
private String candidateParty2;
private String candidateParty3;
private String candidateParty4;
private String candidateURL1;
private String candidateURL2;
private String candidateURL3;
private String candidateURL4;
private String photoUrl1;
private String photoUrl2;
private String photoUrl3;
private String photoUrl4;
//constructor with all data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4,
String photoUrl1, String photoUrl2, String photoUrl3, String photoUrl4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
this.photoUrl3 = photoUrl3;
this.photoUrl4 = photoUrl4;
}
//constructor with 1 candidate
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1, String photoUrl1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
this.photoUrl1 = photoUrl1;
}
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
}
//constructor with 2 candidates
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateParty1, String candidateParty2, String candidateURL1, String candidateURL2, String photoUrl1, String photoUrl2) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
}
//Constructor with no photo data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
}
Here is a snippet from the JSON response from my url request
{
"contests": [
{
"type": "General",
"office": "US House - District 31",
"level": [
"country"
],
"roles": [
"legislatorLowerBody"
],
"district": {
"name": "California's 31st congressional district",
"scope": "congressional",
"id": "ocd-division/country:us/state:ca/cd:31"
},
"candidates": [
{
"name": "Pete Aguilar",
"party": "Democratic",
"candidateUrl": "http://www.peteaguilar.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PeteAguilarforCongress"
},
{
"type": "Twitter",
"id": "https://twitter.com/aguilarpete"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCIXCmfuRWrbgdTw257_lxJQ"
}
]
},
{
"name": "Paul Chabot",
"party": "Republican",
"candidateUrl": "http://www.paulchabot.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PaulChabotCalifornia"
},
{
"type": "Twitter",
"id": "https://twitter.com/DrPaulChabot"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/Voteforaveteran"
}
]
}
]
},
{
"type": "General",
"office": "Governor",
"level": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
],
"district": {
"name": "California",
"scope": "statewide",
"id": "ocd-division/country:us/state:ca"
},
"candidates": [
{
"name": "Edmund G. "Jerry" Brown",
"party": "Democratic",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/jerrybrown"
},
{
"type": "Twitter",
"id": "https://twitter.com/JerryBrownGov"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/+JerryBrown"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/JerryBrown2010"
}
]
},
{
"name": "Neel Kashkari",
"party": "Republican",
"candidateUrl": "http://www.neelkashkari.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/neelkashkari"
},
{
"type": "Twitter",
"id": "https://twitter.com/neelkashkari"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/111272745095197246971"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCGhIiUj05N8mlUNeiKbYfsA"
}
]
}
]
}
Right now, my parsing method only creates an object for a single candidate because I'm not sure how to parse data for all candidates, but before solving this problem, I would like to tackle the immediate issue. When the activity tries to run, an empty activity is displayed with nothing populating the recycler view. The log cat points to my getData() function saying there is no value for "district". The district and candidate JSON arrays are nested arrays within the "contests" array. Could this be why the value for district is not found? How can I navigate through the district and candidates JSON arrays?
getData():
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);
//Three arrays for each JSON array
JSONArray contestsArray = jsonObject.getJSONArray("contests");
JSONArray districtArray = jsonObject.getJSONArray("district");
JSONArray candidatesArray = jsonObject.getJSONArray("candidates");
for (int i = 0; i < contestsArray.length(); i++) {
JSONObject jsonContests = contestsArray.getJSONObject(i);
JSONObject jsonDistrict = districtArray.getJSONObject(i);
JSONObject jsonCandidates = candidatesArray.getJSONObject(i);
if(jsonCandidates.has("photoUrl")){ //Create case for no PhotoUrl
Elects x = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"),
jsonCandidates.getString("photoUrl"));
electsList.add(x);
} else{
Elects a = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"));
electsList.add(a);
}
}
adapter = new ElectsRvAdapter(getApplicationContext(), electsList);
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);
}
}
Logcat Error:
Other relevant code:
ElectsRvAdapter: Recycler view adapter for the Elect class
public class ElectsRvAdapter extends
RecyclerView.Adapter<ElectsRvAdapter.MyViewHolder> {
private Context context;
private List<Elects> electsList;
public ElectsRvAdapter(){
}
public ElectsRvAdapter(Context context, List<Elects> electsList){
this.context = context;
this.electsList = electsList;
}
@NonNull
@Override
public ElectsRvAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v;
LayoutInflater mInflater = LayoutInflater.from(context);
v = mInflater.inflate(R.layout.election_card, viewGroup, false);
final MyViewHolder viewHolder = new MyViewHolder(v);
viewHolder.electionContainer.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
Intent i = new Intent(context, SingleElection.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("office", electsList.get(viewHolder.getAdapterPosition()).getOfficeName());
i.putExtra("type", electsList.get(viewHolder.getAdapterPosition()).getOfficeType());
i.putExtra("level", electsList.get(viewHolder.getAdapterPosition()).getOfficeLevel());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getDistrictName());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName1());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName2());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName3());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName4());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty1());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty2());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty3());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty4());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL1());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL2());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL3());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL4());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl1());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl2());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl3());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl4());
context.startActivity(i);
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ElectsRvAdapter.MyViewHolder myViewHolder, int i) {
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName4.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty4.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
}
@Override
public int getItemCount() {
return electsList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
TextView officeName, candidateName1, candidateName2, candidateName3,
candidateName4, candidateParty1, candidateParty2,
candidateParty3, candidateParty4;
ImageView photoUrl1, photoUrl2, photoUrl3, photoUrl4;
LinearLayout electionContainer;
public MyViewHolder(View itemView){
super(itemView);
officeName = itemView.findViewById(R.id.office_name);
candidateName1 = itemView.findViewById(R.id.candidate_name1);
candidateName2 = itemView.findViewById(R.id.candidate_name2);
candidateName3 = itemView.findViewById(R.id.candidate_name3);
candidateName4 = itemView.findViewById(R.id.candidate_name4);
candidateParty1 = itemView.findViewById(R.id.candidate_party1);
candidateParty2 = itemView.findViewById(R.id.candidate_party2);
candidateParty3 = itemView.findViewById(R.id.candidate_party3);
candidateParty4 = itemView.findViewById(R.id.candidate_party4);
photoUrl1 = itemView.findViewById(R.id.photo_url1);
photoUrl2 = itemView.findViewById(R.id.photo_url2);
photoUrl3 = itemView.findViewById(R.id.photo_url3);
photoUrl4 = itemView.findViewById(R.id.photo_url4);
electionContainer = itemView.findViewById(R.id.elections_container);
}
}
}
SingleElection: Activity that displays more detailed information about the election
public class SingleElection extends AppCompatActivity {
private List<Elects> electsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_election);
electsList = new ArrayList<>();
//recieve data
String name = getIntent().getExtras().getString("office");
String type = getIntent().getExtras().getString("type");
String level = getIntent().getExtras().getString("level");
String dName = getIntent().getExtras().getString("name");
String cName1 = getIntent().getExtras().getString("name");
String cName2 = getIntent().getExtras().getString("name");
String cName3 = getIntent().getExtras().getString("name");
String cName4 = getIntent().getExtras().getString("name");
String cParty1 = getIntent().getExtras().getString("party");
String cParty2 = getIntent().getExtras().getString("party");
String cParty3 = getIntent().getExtras().getString("party");
String cParty4 = getIntent().getExtras().getString("party");
String cUrl1 = getIntent().getExtras().getString("candidateUrl");
String cUrl2 = getIntent().getExtras().getString("candidateUrl");
String cUrl3 = getIntent().getExtras().getString("candidateUrl");
String cUrl4 = getIntent().getExtras().getString("candidateUrl");
String photoUrl1 = getIntent().getExtras().getString("photoUrl");
String photoUrl2 = getIntent().getExtras().getString("photoUrl");
String photoUrl3 = getIntent().getExtras().getString("photoUrl");
String photoUrl4 = getIntent().getExtras().getString("photoUrl");
//Initialize Views
TextView nameTv = findViewById(R.id.office);
TextView typeTv = findViewById(R.id.type);
TextView levelTv = findViewById(R.id.level);
TextView dNameTv = findViewById(R.id.district_name);
TextView cNameTv1 = findViewById(R.id.c_name1);
TextView cNameTv2 = findViewById(R.id.c_name2);
TextView cNameTv3 = findViewById(R.id.c_name3);
TextView cNameTv4 = findViewById(R.id.c_name4);
TextView cPartyTv1 = findViewById(R.id.c_party1);
TextView cPartyTv2 = findViewById(R.id.c_party2);
TextView cPartyTv3 = findViewById(R.id.c_party3);
TextView cPartyTv4 = findViewById(R.id.c_party4);
TextView cUrlTv1 = findViewById(R.id.c_url1);
TextView cUrlTv2 = findViewById(R.id.c_url2);
TextView cUrlTv3 = findViewById(R.id.c_url3);
TextView cUrlTv4 = findViewById(R.id.c_url4);
ImageView photoUrlTv1 = findViewById(R.id.photo1);
ImageView photoUrlTv2 = findViewById(R.id.photo2);
ImageView photoUrlTv3 = findViewById(R.id.photo3);
ImageView photoUrlTv4 = findViewById(R.id.photo4);
//set string values to each view
nameTv.setText(name);
typeTv.setText(type);
levelTv.setText(level);
dNameTv.setText(dName);
cNameTv1.setText(name);
cNameTv2.setText(name);
cNameTv3.setText(name);
cNameTv4.setText(name);
cPartyTv1.setText(name);
cPartyTv2.setText(name);
cPartyTv3.setText(name);
cPartyTv4.setText(name);
cUrlTv1.setText(name);
cUrlTv2.setText(name);
cUrlTv3.setText(name);
cUrlTv4.setText(name);
//set image
Picasso.get()
.load(photoUrl1)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv1);
Picasso.get()
.load(photoUrl2)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv2);
Picasso.get()
.load(photoUrl3)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv3);
Picasso.get()
.load(photoUrl4)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv4);
}
}
To sum up:
- How can I alter rmy getData() function to properly iterate through nested JSON arrays.
- How should I structure my Elects class to receive the JSON data in the easiest, most efficient way?
Thanks Much! If you need any more code, let me know.
java arrays json android-recyclerview
add a comment |
I am working on a project that parses JSON data from the Google Civic API and displays it to the user. First, the data will be displayed in a recycler view, showing the office name, candidate photo, candidate name and candidate party for each person participating in the election. According to the JSON response, the minimum amount of people that can participate in the election is 2 and the maximum is four. Here is what the layout looks like.
A list of elections will be shown in the recycler view with a brief glimpse of the candidate information. Once the user clicks on a particular election, they will be directed to another activity that shows the full details of the contest.
My first question is how can structure my class. Do I create an object for each candidate, or do I create an object for the entire election. Here is my current implementation for the Elects class.
package com.example.gabe.politicianspulse;
public class Elects {
private String officeName;
private String officeType;
private String officeLevel;
private String districtName;
private String candidateName1;
private String candidateName2;
private String candidateName3;
private String candidateName4;
private String candidateParty1;
private String candidateParty2;
private String candidateParty3;
private String candidateParty4;
private String candidateURL1;
private String candidateURL2;
private String candidateURL3;
private String candidateURL4;
private String photoUrl1;
private String photoUrl2;
private String photoUrl3;
private String photoUrl4;
//constructor with all data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4,
String photoUrl1, String photoUrl2, String photoUrl3, String photoUrl4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
this.photoUrl3 = photoUrl3;
this.photoUrl4 = photoUrl4;
}
//constructor with 1 candidate
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1, String photoUrl1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
this.photoUrl1 = photoUrl1;
}
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
}
//constructor with 2 candidates
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateParty1, String candidateParty2, String candidateURL1, String candidateURL2, String photoUrl1, String photoUrl2) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
}
//Constructor with no photo data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
}
Here is a snippet from the JSON response from my url request
{
"contests": [
{
"type": "General",
"office": "US House - District 31",
"level": [
"country"
],
"roles": [
"legislatorLowerBody"
],
"district": {
"name": "California's 31st congressional district",
"scope": "congressional",
"id": "ocd-division/country:us/state:ca/cd:31"
},
"candidates": [
{
"name": "Pete Aguilar",
"party": "Democratic",
"candidateUrl": "http://www.peteaguilar.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PeteAguilarforCongress"
},
{
"type": "Twitter",
"id": "https://twitter.com/aguilarpete"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCIXCmfuRWrbgdTw257_lxJQ"
}
]
},
{
"name": "Paul Chabot",
"party": "Republican",
"candidateUrl": "http://www.paulchabot.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PaulChabotCalifornia"
},
{
"type": "Twitter",
"id": "https://twitter.com/DrPaulChabot"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/Voteforaveteran"
}
]
}
]
},
{
"type": "General",
"office": "Governor",
"level": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
],
"district": {
"name": "California",
"scope": "statewide",
"id": "ocd-division/country:us/state:ca"
},
"candidates": [
{
"name": "Edmund G. "Jerry" Brown",
"party": "Democratic",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/jerrybrown"
},
{
"type": "Twitter",
"id": "https://twitter.com/JerryBrownGov"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/+JerryBrown"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/JerryBrown2010"
}
]
},
{
"name": "Neel Kashkari",
"party": "Republican",
"candidateUrl": "http://www.neelkashkari.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/neelkashkari"
},
{
"type": "Twitter",
"id": "https://twitter.com/neelkashkari"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/111272745095197246971"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCGhIiUj05N8mlUNeiKbYfsA"
}
]
}
]
}
Right now, my parsing method only creates an object for a single candidate because I'm not sure how to parse data for all candidates, but before solving this problem, I would like to tackle the immediate issue. When the activity tries to run, an empty activity is displayed with nothing populating the recycler view. The log cat points to my getData() function saying there is no value for "district". The district and candidate JSON arrays are nested arrays within the "contests" array. Could this be why the value for district is not found? How can I navigate through the district and candidates JSON arrays?
getData():
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);
//Three arrays for each JSON array
JSONArray contestsArray = jsonObject.getJSONArray("contests");
JSONArray districtArray = jsonObject.getJSONArray("district");
JSONArray candidatesArray = jsonObject.getJSONArray("candidates");
for (int i = 0; i < contestsArray.length(); i++) {
JSONObject jsonContests = contestsArray.getJSONObject(i);
JSONObject jsonDistrict = districtArray.getJSONObject(i);
JSONObject jsonCandidates = candidatesArray.getJSONObject(i);
if(jsonCandidates.has("photoUrl")){ //Create case for no PhotoUrl
Elects x = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"),
jsonCandidates.getString("photoUrl"));
electsList.add(x);
} else{
Elects a = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"));
electsList.add(a);
}
}
adapter = new ElectsRvAdapter(getApplicationContext(), electsList);
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);
}
}
Logcat Error:
Other relevant code:
ElectsRvAdapter: Recycler view adapter for the Elect class
public class ElectsRvAdapter extends
RecyclerView.Adapter<ElectsRvAdapter.MyViewHolder> {
private Context context;
private List<Elects> electsList;
public ElectsRvAdapter(){
}
public ElectsRvAdapter(Context context, List<Elects> electsList){
this.context = context;
this.electsList = electsList;
}
@NonNull
@Override
public ElectsRvAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v;
LayoutInflater mInflater = LayoutInflater.from(context);
v = mInflater.inflate(R.layout.election_card, viewGroup, false);
final MyViewHolder viewHolder = new MyViewHolder(v);
viewHolder.electionContainer.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
Intent i = new Intent(context, SingleElection.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("office", electsList.get(viewHolder.getAdapterPosition()).getOfficeName());
i.putExtra("type", electsList.get(viewHolder.getAdapterPosition()).getOfficeType());
i.putExtra("level", electsList.get(viewHolder.getAdapterPosition()).getOfficeLevel());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getDistrictName());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName1());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName2());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName3());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName4());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty1());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty2());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty3());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty4());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL1());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL2());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL3());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL4());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl1());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl2());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl3());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl4());
context.startActivity(i);
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ElectsRvAdapter.MyViewHolder myViewHolder, int i) {
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName4.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty4.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
}
@Override
public int getItemCount() {
return electsList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
TextView officeName, candidateName1, candidateName2, candidateName3,
candidateName4, candidateParty1, candidateParty2,
candidateParty3, candidateParty4;
ImageView photoUrl1, photoUrl2, photoUrl3, photoUrl4;
LinearLayout electionContainer;
public MyViewHolder(View itemView){
super(itemView);
officeName = itemView.findViewById(R.id.office_name);
candidateName1 = itemView.findViewById(R.id.candidate_name1);
candidateName2 = itemView.findViewById(R.id.candidate_name2);
candidateName3 = itemView.findViewById(R.id.candidate_name3);
candidateName4 = itemView.findViewById(R.id.candidate_name4);
candidateParty1 = itemView.findViewById(R.id.candidate_party1);
candidateParty2 = itemView.findViewById(R.id.candidate_party2);
candidateParty3 = itemView.findViewById(R.id.candidate_party3);
candidateParty4 = itemView.findViewById(R.id.candidate_party4);
photoUrl1 = itemView.findViewById(R.id.photo_url1);
photoUrl2 = itemView.findViewById(R.id.photo_url2);
photoUrl3 = itemView.findViewById(R.id.photo_url3);
photoUrl4 = itemView.findViewById(R.id.photo_url4);
electionContainer = itemView.findViewById(R.id.elections_container);
}
}
}
SingleElection: Activity that displays more detailed information about the election
public class SingleElection extends AppCompatActivity {
private List<Elects> electsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_election);
electsList = new ArrayList<>();
//recieve data
String name = getIntent().getExtras().getString("office");
String type = getIntent().getExtras().getString("type");
String level = getIntent().getExtras().getString("level");
String dName = getIntent().getExtras().getString("name");
String cName1 = getIntent().getExtras().getString("name");
String cName2 = getIntent().getExtras().getString("name");
String cName3 = getIntent().getExtras().getString("name");
String cName4 = getIntent().getExtras().getString("name");
String cParty1 = getIntent().getExtras().getString("party");
String cParty2 = getIntent().getExtras().getString("party");
String cParty3 = getIntent().getExtras().getString("party");
String cParty4 = getIntent().getExtras().getString("party");
String cUrl1 = getIntent().getExtras().getString("candidateUrl");
String cUrl2 = getIntent().getExtras().getString("candidateUrl");
String cUrl3 = getIntent().getExtras().getString("candidateUrl");
String cUrl4 = getIntent().getExtras().getString("candidateUrl");
String photoUrl1 = getIntent().getExtras().getString("photoUrl");
String photoUrl2 = getIntent().getExtras().getString("photoUrl");
String photoUrl3 = getIntent().getExtras().getString("photoUrl");
String photoUrl4 = getIntent().getExtras().getString("photoUrl");
//Initialize Views
TextView nameTv = findViewById(R.id.office);
TextView typeTv = findViewById(R.id.type);
TextView levelTv = findViewById(R.id.level);
TextView dNameTv = findViewById(R.id.district_name);
TextView cNameTv1 = findViewById(R.id.c_name1);
TextView cNameTv2 = findViewById(R.id.c_name2);
TextView cNameTv3 = findViewById(R.id.c_name3);
TextView cNameTv4 = findViewById(R.id.c_name4);
TextView cPartyTv1 = findViewById(R.id.c_party1);
TextView cPartyTv2 = findViewById(R.id.c_party2);
TextView cPartyTv3 = findViewById(R.id.c_party3);
TextView cPartyTv4 = findViewById(R.id.c_party4);
TextView cUrlTv1 = findViewById(R.id.c_url1);
TextView cUrlTv2 = findViewById(R.id.c_url2);
TextView cUrlTv3 = findViewById(R.id.c_url3);
TextView cUrlTv4 = findViewById(R.id.c_url4);
ImageView photoUrlTv1 = findViewById(R.id.photo1);
ImageView photoUrlTv2 = findViewById(R.id.photo2);
ImageView photoUrlTv3 = findViewById(R.id.photo3);
ImageView photoUrlTv4 = findViewById(R.id.photo4);
//set string values to each view
nameTv.setText(name);
typeTv.setText(type);
levelTv.setText(level);
dNameTv.setText(dName);
cNameTv1.setText(name);
cNameTv2.setText(name);
cNameTv3.setText(name);
cNameTv4.setText(name);
cPartyTv1.setText(name);
cPartyTv2.setText(name);
cPartyTv3.setText(name);
cPartyTv4.setText(name);
cUrlTv1.setText(name);
cUrlTv2.setText(name);
cUrlTv3.setText(name);
cUrlTv4.setText(name);
//set image
Picasso.get()
.load(photoUrl1)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv1);
Picasso.get()
.load(photoUrl2)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv2);
Picasso.get()
.load(photoUrl3)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv3);
Picasso.get()
.load(photoUrl4)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv4);
}
}
To sum up:
- How can I alter rmy getData() function to properly iterate through nested JSON arrays.
- How should I structure my Elects class to receive the JSON data in the easiest, most efficient way?
Thanks Much! If you need any more code, let me know.
java arrays json android-recyclerview
I am working on a project that parses JSON data from the Google Civic API and displays it to the user. First, the data will be displayed in a recycler view, showing the office name, candidate photo, candidate name and candidate party for each person participating in the election. According to the JSON response, the minimum amount of people that can participate in the election is 2 and the maximum is four. Here is what the layout looks like.
A list of elections will be shown in the recycler view with a brief glimpse of the candidate information. Once the user clicks on a particular election, they will be directed to another activity that shows the full details of the contest.
My first question is how can structure my class. Do I create an object for each candidate, or do I create an object for the entire election. Here is my current implementation for the Elects class.
package com.example.gabe.politicianspulse;
public class Elects {
private String officeName;
private String officeType;
private String officeLevel;
private String districtName;
private String candidateName1;
private String candidateName2;
private String candidateName3;
private String candidateName4;
private String candidateParty1;
private String candidateParty2;
private String candidateParty3;
private String candidateParty4;
private String candidateURL1;
private String candidateURL2;
private String candidateURL3;
private String candidateURL4;
private String photoUrl1;
private String photoUrl2;
private String photoUrl3;
private String photoUrl4;
//constructor with all data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4,
String photoUrl1, String photoUrl2, String photoUrl3, String photoUrl4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
this.photoUrl3 = photoUrl3;
this.photoUrl4 = photoUrl4;
}
//constructor with 1 candidate
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1, String photoUrl1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
this.photoUrl1 = photoUrl1;
}
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateParty1, String candidateURL1) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateParty1 = candidateParty1;
this.candidateURL1 = candidateURL1;
}
//constructor with 2 candidates
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateParty1, String candidateParty2, String candidateURL1, String candidateURL2, String photoUrl1, String photoUrl2) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.photoUrl1 = photoUrl1;
this.photoUrl2 = photoUrl2;
}
//Constructor with no photo data
public Elects(String officeName, String officeType, String officeLevel, String districtName, String candidateName1, String candidateName2,
String candidateName3, String candidateName4, String candidateParty1, String candidateParty2, String candidateParty3,
String candidateParty4, String candidateURL1, String candidateURL2, String candidateURL3, String candidateURL4) {
this.officeName = officeName;
this.officeType = officeType;
this.officeLevel = officeLevel;
this.districtName = districtName;
this.candidateName1 = candidateName1;
this.candidateName2 = candidateName2;
this.candidateName3 = candidateName3;
this.candidateName4 = candidateName4;
this.candidateParty1 = candidateParty1;
this.candidateParty2 = candidateParty2;
this.candidateParty3 = candidateParty3;
this.candidateParty4 = candidateParty4;
this.candidateURL1 = candidateURL1;
this.candidateURL2 = candidateURL2;
this.candidateURL3 = candidateURL3;
this.candidateURL4 = candidateURL4;
}
Here is a snippet from the JSON response from my url request
{
"contests": [
{
"type": "General",
"office": "US House - District 31",
"level": [
"country"
],
"roles": [
"legislatorLowerBody"
],
"district": {
"name": "California's 31st congressional district",
"scope": "congressional",
"id": "ocd-division/country:us/state:ca/cd:31"
},
"candidates": [
{
"name": "Pete Aguilar",
"party": "Democratic",
"candidateUrl": "http://www.peteaguilar.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PeteAguilarforCongress"
},
{
"type": "Twitter",
"id": "https://twitter.com/aguilarpete"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCIXCmfuRWrbgdTw257_lxJQ"
}
]
},
{
"name": "Paul Chabot",
"party": "Republican",
"candidateUrl": "http://www.paulchabot.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PaulChabotCalifornia"
},
{
"type": "Twitter",
"id": "https://twitter.com/DrPaulChabot"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/Voteforaveteran"
}
]
}
]
},
{
"type": "General",
"office": "Governor",
"level": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
],
"district": {
"name": "California",
"scope": "statewide",
"id": "ocd-division/country:us/state:ca"
},
"candidates": [
{
"name": "Edmund G. "Jerry" Brown",
"party": "Democratic",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/jerrybrown"
},
{
"type": "Twitter",
"id": "https://twitter.com/JerryBrownGov"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/+JerryBrown"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/JerryBrown2010"
}
]
},
{
"name": "Neel Kashkari",
"party": "Republican",
"candidateUrl": "http://www.neelkashkari.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/neelkashkari"
},
{
"type": "Twitter",
"id": "https://twitter.com/neelkashkari"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/111272745095197246971"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCGhIiUj05N8mlUNeiKbYfsA"
}
]
}
]
}
Right now, my parsing method only creates an object for a single candidate because I'm not sure how to parse data for all candidates, but before solving this problem, I would like to tackle the immediate issue. When the activity tries to run, an empty activity is displayed with nothing populating the recycler view. The log cat points to my getData() function saying there is no value for "district". The district and candidate JSON arrays are nested arrays within the "contests" array. Could this be why the value for district is not found? How can I navigate through the district and candidates JSON arrays?
getData():
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);
//Three arrays for each JSON array
JSONArray contestsArray = jsonObject.getJSONArray("contests");
JSONArray districtArray = jsonObject.getJSONArray("district");
JSONArray candidatesArray = jsonObject.getJSONArray("candidates");
for (int i = 0; i < contestsArray.length(); i++) {
JSONObject jsonContests = contestsArray.getJSONObject(i);
JSONObject jsonDistrict = districtArray.getJSONObject(i);
JSONObject jsonCandidates = candidatesArray.getJSONObject(i);
if(jsonCandidates.has("photoUrl")){ //Create case for no PhotoUrl
Elects x = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"),
jsonCandidates.getString("photoUrl"));
electsList.add(x);
} else{
Elects a = new Elects(jsonContests.getString("office"),
jsonContests.getString("type"),
jsonContests.getString("level"),
jsonDistrict.getString("name"),
jsonCandidates.getString("name"),
jsonCandidates.getString("party"),
jsonCandidates.getString("candidateUrl"));
electsList.add(a);
}
}
adapter = new ElectsRvAdapter(getApplicationContext(), electsList);
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);
}
}
Logcat Error:
Other relevant code:
ElectsRvAdapter: Recycler view adapter for the Elect class
public class ElectsRvAdapter extends
RecyclerView.Adapter<ElectsRvAdapter.MyViewHolder> {
private Context context;
private List<Elects> electsList;
public ElectsRvAdapter(){
}
public ElectsRvAdapter(Context context, List<Elects> electsList){
this.context = context;
this.electsList = electsList;
}
@NonNull
@Override
public ElectsRvAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View v;
LayoutInflater mInflater = LayoutInflater.from(context);
v = mInflater.inflate(R.layout.election_card, viewGroup, false);
final MyViewHolder viewHolder = new MyViewHolder(v);
viewHolder.electionContainer.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
Intent i = new Intent(context, SingleElection.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("office", electsList.get(viewHolder.getAdapterPosition()).getOfficeName());
i.putExtra("type", electsList.get(viewHolder.getAdapterPosition()).getOfficeType());
i.putExtra("level", electsList.get(viewHolder.getAdapterPosition()).getOfficeLevel());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getDistrictName());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName1());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName2());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName3());
i.putExtra("name", electsList.get(viewHolder.getAdapterPosition()).getCandidateName4());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty1());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty2());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty3());
i.putExtra("party", electsList.get(viewHolder.getAdapterPosition()).getCandidateParty4());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL1());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL2());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL3());
i.putExtra("candidateUrl", electsList.get(viewHolder.getAdapterPosition()).getCandidateURL4());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl1());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl2());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl3());
i.putExtra("photoUrl", electsList.get(viewHolder.getAdapterPosition()).getPhotoUrl4());
context.startActivity(i);
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(@NonNull ElectsRvAdapter.MyViewHolder myViewHolder, int i) {
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateName4.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty1.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty2.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty3.setText(electsList.get(i).getOfficeName());
myViewHolder.candidateParty4.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
myViewHolder.officeName.setText(electsList.get(i).getOfficeName());
}
@Override
public int getItemCount() {
return electsList.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
TextView officeName, candidateName1, candidateName2, candidateName3,
candidateName4, candidateParty1, candidateParty2,
candidateParty3, candidateParty4;
ImageView photoUrl1, photoUrl2, photoUrl3, photoUrl4;
LinearLayout electionContainer;
public MyViewHolder(View itemView){
super(itemView);
officeName = itemView.findViewById(R.id.office_name);
candidateName1 = itemView.findViewById(R.id.candidate_name1);
candidateName2 = itemView.findViewById(R.id.candidate_name2);
candidateName3 = itemView.findViewById(R.id.candidate_name3);
candidateName4 = itemView.findViewById(R.id.candidate_name4);
candidateParty1 = itemView.findViewById(R.id.candidate_party1);
candidateParty2 = itemView.findViewById(R.id.candidate_party2);
candidateParty3 = itemView.findViewById(R.id.candidate_party3);
candidateParty4 = itemView.findViewById(R.id.candidate_party4);
photoUrl1 = itemView.findViewById(R.id.photo_url1);
photoUrl2 = itemView.findViewById(R.id.photo_url2);
photoUrl3 = itemView.findViewById(R.id.photo_url3);
photoUrl4 = itemView.findViewById(R.id.photo_url4);
electionContainer = itemView.findViewById(R.id.elections_container);
}
}
}
SingleElection: Activity that displays more detailed information about the election
public class SingleElection extends AppCompatActivity {
private List<Elects> electsList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_election);
electsList = new ArrayList<>();
//recieve data
String name = getIntent().getExtras().getString("office");
String type = getIntent().getExtras().getString("type");
String level = getIntent().getExtras().getString("level");
String dName = getIntent().getExtras().getString("name");
String cName1 = getIntent().getExtras().getString("name");
String cName2 = getIntent().getExtras().getString("name");
String cName3 = getIntent().getExtras().getString("name");
String cName4 = getIntent().getExtras().getString("name");
String cParty1 = getIntent().getExtras().getString("party");
String cParty2 = getIntent().getExtras().getString("party");
String cParty3 = getIntent().getExtras().getString("party");
String cParty4 = getIntent().getExtras().getString("party");
String cUrl1 = getIntent().getExtras().getString("candidateUrl");
String cUrl2 = getIntent().getExtras().getString("candidateUrl");
String cUrl3 = getIntent().getExtras().getString("candidateUrl");
String cUrl4 = getIntent().getExtras().getString("candidateUrl");
String photoUrl1 = getIntent().getExtras().getString("photoUrl");
String photoUrl2 = getIntent().getExtras().getString("photoUrl");
String photoUrl3 = getIntent().getExtras().getString("photoUrl");
String photoUrl4 = getIntent().getExtras().getString("photoUrl");
//Initialize Views
TextView nameTv = findViewById(R.id.office);
TextView typeTv = findViewById(R.id.type);
TextView levelTv = findViewById(R.id.level);
TextView dNameTv = findViewById(R.id.district_name);
TextView cNameTv1 = findViewById(R.id.c_name1);
TextView cNameTv2 = findViewById(R.id.c_name2);
TextView cNameTv3 = findViewById(R.id.c_name3);
TextView cNameTv4 = findViewById(R.id.c_name4);
TextView cPartyTv1 = findViewById(R.id.c_party1);
TextView cPartyTv2 = findViewById(R.id.c_party2);
TextView cPartyTv3 = findViewById(R.id.c_party3);
TextView cPartyTv4 = findViewById(R.id.c_party4);
TextView cUrlTv1 = findViewById(R.id.c_url1);
TextView cUrlTv2 = findViewById(R.id.c_url2);
TextView cUrlTv3 = findViewById(R.id.c_url3);
TextView cUrlTv4 = findViewById(R.id.c_url4);
ImageView photoUrlTv1 = findViewById(R.id.photo1);
ImageView photoUrlTv2 = findViewById(R.id.photo2);
ImageView photoUrlTv3 = findViewById(R.id.photo3);
ImageView photoUrlTv4 = findViewById(R.id.photo4);
//set string values to each view
nameTv.setText(name);
typeTv.setText(type);
levelTv.setText(level);
dNameTv.setText(dName);
cNameTv1.setText(name);
cNameTv2.setText(name);
cNameTv3.setText(name);
cNameTv4.setText(name);
cPartyTv1.setText(name);
cPartyTv2.setText(name);
cPartyTv3.setText(name);
cPartyTv4.setText(name);
cUrlTv1.setText(name);
cUrlTv2.setText(name);
cUrlTv3.setText(name);
cUrlTv4.setText(name);
//set image
Picasso.get()
.load(photoUrl1)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv1);
Picasso.get()
.load(photoUrl2)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv2);
Picasso.get()
.load(photoUrl3)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv3);
Picasso.get()
.load(photoUrl4)
.centerCrop()
.transform(new CircleTransform(50, 0))
.fit()
.into(photoUrlTv4);
}
}
To sum up:
- How can I alter rmy getData() function to properly iterate through nested JSON arrays.
- How should I structure my Elects class to receive the JSON data in the easiest, most efficient way?
Thanks Much! If you need any more code, let me know.
{
"contests": [
{
"type": "General",
"office": "US House - District 31",
"level": [
"country"
],
"roles": [
"legislatorLowerBody"
],
"district": {
"name": "California's 31st congressional district",
"scope": "congressional",
"id": "ocd-division/country:us/state:ca/cd:31"
},
"candidates": [
{
"name": "Pete Aguilar",
"party": "Democratic",
"candidateUrl": "http://www.peteaguilar.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PeteAguilarforCongress"
},
{
"type": "Twitter",
"id": "https://twitter.com/aguilarpete"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCIXCmfuRWrbgdTw257_lxJQ"
}
]
},
{
"name": "Paul Chabot",
"party": "Republican",
"candidateUrl": "http://www.paulchabot.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PaulChabotCalifornia"
},
{
"type": "Twitter",
"id": "https://twitter.com/DrPaulChabot"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/Voteforaveteran"
}
]
}
]
},
{
"type": "General",
"office": "Governor",
"level": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
],
"district": {
"name": "California",
"scope": "statewide",
"id": "ocd-division/country:us/state:ca"
},
"candidates": [
{
"name": "Edmund G. "Jerry" Brown",
"party": "Democratic",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/jerrybrown"
},
{
"type": "Twitter",
"id": "https://twitter.com/JerryBrownGov"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/+JerryBrown"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/JerryBrown2010"
}
]
},
{
"name": "Neel Kashkari",
"party": "Republican",
"candidateUrl": "http://www.neelkashkari.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/neelkashkari"
},
{
"type": "Twitter",
"id": "https://twitter.com/neelkashkari"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/111272745095197246971"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCGhIiUj05N8mlUNeiKbYfsA"
}
]
}
]
}
{
"contests": [
{
"type": "General",
"office": "US House - District 31",
"level": [
"country"
],
"roles": [
"legislatorLowerBody"
],
"district": {
"name": "California's 31st congressional district",
"scope": "congressional",
"id": "ocd-division/country:us/state:ca/cd:31"
},
"candidates": [
{
"name": "Pete Aguilar",
"party": "Democratic",
"candidateUrl": "http://www.peteaguilar.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PeteAguilarforCongress"
},
{
"type": "Twitter",
"id": "https://twitter.com/aguilarpete"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCIXCmfuRWrbgdTw257_lxJQ"
}
]
},
{
"name": "Paul Chabot",
"party": "Republican",
"candidateUrl": "http://www.paulchabot.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/PaulChabotCalifornia"
},
{
"type": "Twitter",
"id": "https://twitter.com/DrPaulChabot"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/Voteforaveteran"
}
]
}
]
},
{
"type": "General",
"office": "Governor",
"level": [
"administrativeArea1"
],
"roles": [
"headOfGovernment"
],
"district": {
"name": "California",
"scope": "statewide",
"id": "ocd-division/country:us/state:ca"
},
"candidates": [
{
"name": "Edmund G. "Jerry" Brown",
"party": "Democratic",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/jerrybrown"
},
{
"type": "Twitter",
"id": "https://twitter.com/JerryBrownGov"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/+JerryBrown"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/user/JerryBrown2010"
}
]
},
{
"name": "Neel Kashkari",
"party": "Republican",
"candidateUrl": "http://www.neelkashkari.com/",
"channels": [
{
"type": "Facebook",
"id": "https://www.facebook.com/neelkashkari"
},
{
"type": "Twitter",
"id": "https://twitter.com/neelkashkari"
},
{
"type": "GooglePlus",
"id": "https://plus.google.com/111272745095197246971"
},
{
"type": "YouTube",
"id": "https://www.youtube.com/channel/UCGhIiUj05N8mlUNeiKbYfsA"
}
]
}
]
}
java arrays json android-recyclerview
java arrays json android-recyclerview
edited Jan 3 at 7:34
Markus Kauppinen
2,2103825
2,2103825
asked Jan 3 at 6:58
GabrielGabriel
619
619
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
First of all you are missing two closing parenthesis in the JSON you posted.
Now parsing the given JSON,
JSONObject jsonObject = new JSONObject(response);
//Only one array needed for contests
JSONArray contestsArray = jsonObject.getJSONArray("contests");
for(int i=0;i<=contestsArray.length();i++)
{
JSONObject ContestObject=new JSONObject();
//getting data of first contest object
ContestObject=contestsArray.getJSONObject(i);
String ContestType=ContestObject.getString("type");
//Eg:- ContestType will have value "general" in the first iteration
JSONObject DistrictObject=ContestObject.getJSONObject("district");
//access data inside District Object using this object
JSONArray candidates=ContestObject.getJSONArray("candidates");
//loop through this array for all candidates data in the current contest Object
//here parse data of each contest object
}
This is just the logic for parsing. You can create lists or add the data wherever you want from according to your needs. Hope it helps.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54017656%2fandroid-studio-parsing-multiple-nested-json-arrays%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
First of all you are missing two closing parenthesis in the JSON you posted.
Now parsing the given JSON,
JSONObject jsonObject = new JSONObject(response);
//Only one array needed for contests
JSONArray contestsArray = jsonObject.getJSONArray("contests");
for(int i=0;i<=contestsArray.length();i++)
{
JSONObject ContestObject=new JSONObject();
//getting data of first contest object
ContestObject=contestsArray.getJSONObject(i);
String ContestType=ContestObject.getString("type");
//Eg:- ContestType will have value "general" in the first iteration
JSONObject DistrictObject=ContestObject.getJSONObject("district");
//access data inside District Object using this object
JSONArray candidates=ContestObject.getJSONArray("candidates");
//loop through this array for all candidates data in the current contest Object
//here parse data of each contest object
}
This is just the logic for parsing. You can create lists or add the data wherever you want from according to your needs. Hope it helps.
add a comment |
First of all you are missing two closing parenthesis in the JSON you posted.
Now parsing the given JSON,
JSONObject jsonObject = new JSONObject(response);
//Only one array needed for contests
JSONArray contestsArray = jsonObject.getJSONArray("contests");
for(int i=0;i<=contestsArray.length();i++)
{
JSONObject ContestObject=new JSONObject();
//getting data of first contest object
ContestObject=contestsArray.getJSONObject(i);
String ContestType=ContestObject.getString("type");
//Eg:- ContestType will have value "general" in the first iteration
JSONObject DistrictObject=ContestObject.getJSONObject("district");
//access data inside District Object using this object
JSONArray candidates=ContestObject.getJSONArray("candidates");
//loop through this array for all candidates data in the current contest Object
//here parse data of each contest object
}
This is just the logic for parsing. You can create lists or add the data wherever you want from according to your needs. Hope it helps.
add a comment |
First of all you are missing two closing parenthesis in the JSON you posted.
Now parsing the given JSON,
JSONObject jsonObject = new JSONObject(response);
//Only one array needed for contests
JSONArray contestsArray = jsonObject.getJSONArray("contests");
for(int i=0;i<=contestsArray.length();i++)
{
JSONObject ContestObject=new JSONObject();
//getting data of first contest object
ContestObject=contestsArray.getJSONObject(i);
String ContestType=ContestObject.getString("type");
//Eg:- ContestType will have value "general" in the first iteration
JSONObject DistrictObject=ContestObject.getJSONObject("district");
//access data inside District Object using this object
JSONArray candidates=ContestObject.getJSONArray("candidates");
//loop through this array for all candidates data in the current contest Object
//here parse data of each contest object
}
This is just the logic for parsing. You can create lists or add the data wherever you want from according to your needs. Hope it helps.
First of all you are missing two closing parenthesis in the JSON you posted.
Now parsing the given JSON,
JSONObject jsonObject = new JSONObject(response);
//Only one array needed for contests
JSONArray contestsArray = jsonObject.getJSONArray("contests");
for(int i=0;i<=contestsArray.length();i++)
{
JSONObject ContestObject=new JSONObject();
//getting data of first contest object
ContestObject=contestsArray.getJSONObject(i);
String ContestType=ContestObject.getString("type");
//Eg:- ContestType will have value "general" in the first iteration
JSONObject DistrictObject=ContestObject.getJSONObject("district");
//access data inside District Object using this object
JSONArray candidates=ContestObject.getJSONArray("candidates");
//loop through this array for all candidates data in the current contest Object
//here parse data of each contest object
}
This is just the logic for parsing. You can create lists or add the data wherever you want from according to your needs. Hope it helps.
answered Jan 7 at 12:58
Nabil Mohammed NalakathNabil Mohammed Nalakath
382416
382416
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54017656%2fandroid-studio-parsing-multiple-nested-json-arrays%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown