Search code examples
javaandroidjsonretrofit2

Android Java - Parse Array Entry of JSON into Recycler View


I am trying to parse a Block of JSON into a RecyclerView. So far I was able to achieve this with a quite flat JSON Structure. But now I have an Array-Entry in my JSON File where I always want to get the first Entry. The JSON looks like this:

[    
    {
        "MatchID": 60989,
        "Team1": {
            "TeamName": "FC Bayern München",
            "TeamIconUrl": "https://i.imgur.com/jJEsJrj.png"
        },
        "Team2": {
            "TeamName": "VfL Wolfsburg",
            "TeamIconUrl": "https://i.imgur.com/ucqKV4B.png"
        },
        "MatchResults": [
            {
                "PointsTeam1": 4,
                "PointsTeam2": 0,
                "ResultOrderID": 1
            },
            {
                "PointsTeam1": 1,
                "PointsTeam2": 0,
                "ResultOrderID": 2
            }
        ]
    },
    {
        "MatchID": 60990,
        "Team1": {
            "TeamName": "VfL Bochum",
            "TeamIconUrl": "https://i.imgur.com/5jy3Gfr.png"
        },
        "Team2": {
            "TeamName": "1. FC Union Berlin",
            "TeamIconUrl": "https://upload.wikimedia.org/wikipedia/commons/4/44/1._FC_Union_Berlin_Logo.svg"
        },
        "MatchResults": [
            {
                "PointsTeam1": 0,
                "PointsTeam2": 1,
                "ResultOrderID": 1
            },
            {
                "PointsTeam1": 0,
                "PointsTeam2": 1,
                "ResultOrderID": 2
            }
        ]
    }
]

My Activity fetches this JSON from an API using Retrofit2

    private void parseJson() {
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://www.openligadb.de/api/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        RequestInterface request = retrofit.create(RequestInterface.class);
        Call<List<Match>> call=request.getMatchJson();
        call.enqueue(new Callback<List<Match>>() {
            @Override
            public void onResponse(Call<List<Match>> call, Response<List<Match>> response) {
                if (response.isSuccessful() && response.body() != null) {
                    matchList = new ArrayList<>(response.body());
                    matchAdapter = new MatchAdapter(matchList, ActivityMatch.this);
                    mRecyclerView.setAdapter(matchAdapter);
                }
            }

            @Override
            public void onFailure(Call<List<Match>> call, Throwable t) {
                Log.println(Log.ERROR, "FAILED", String.valueOf(t));
                Toast.makeText(ActivityMatch.this, "Oops! Somehting went wrong!", Toast.LENGTH_SHORT).show();
            }
        });
    }

My MatchAdapter is then parsing this Data for the View. Here I want to display whatever is the first in MatchResults then using PointsTeam1 and PointsTeam2 to display something like "4 : 0"

Now in my ModelClass accessing direct Values like the TeamName and TeamIconUrl worked but I am struggeling to get to the first entry of the Array and am really stuck on even how to properly approach this issue.

The Adapter Class:

public class MatchAdapter extends RecyclerView.Adapter<MatchAdapter.MatchHolder>{

    private ArrayList<Match> matchList;
    private Context context;

    public MatchAdapter(ArrayList<Match> matchList, Context context) {
        this.context = context;
        this.matchList = matchList;
    }

    @NonNull
    @Override
    public MatchAdapter.MatchHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.match_list_row_layout, viewGroup, false);
        return new MatchHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MatchAdapter.MatchHolder holder, int position) {
        holder.tvTeam1name.setText(matchList.get(position).Team1.TeamName);
        holder.tvTeam2name.setText(matchList.get(position).Team2.TeamName);
        Glide.with(context).load(matchList.get(position).Team1.TeamIconUrl).into(holder.ivTeam1Logo);
        Glide.with(context).load(matchList.get(position).Team2.TeamIconUrl).into(holder.ivTeam2Logo);
        //This is not working
        holder.tvResult.setText(matchList.get(position).MatchResults.PointsTeam1 + " : " + matchList.get(position).MatchResults.PointsTeam2);
    }

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

    public class MatchHolder extends RecyclerView.ViewHolder {
        private TextView tvTeam1name, tvTeam2name, tvResult;
        private ImageView ivTeam1Logo, ivTeam2Logo;

        public MatchHolder(@NonNull View itemView) {
            super(itemView);
            tvTeam1name = itemView.findViewById(R.id.tv_team1name);
            tvTeam2name = itemView.findViewById(R.id.tv_team2name);
            tvResult = itemView.findViewById(R.id.tv_result);
            ivTeam1Logo = itemView.findViewById(R.id.iv_team1logo);
            ivTeam2Logo = itemView.findViewById(R.id.iv_team2logo);
        }
    }
}

My ModelClass (Left out Getters/Setters for Readability)

package de.eahjena.app.wi.fussball;

public class Match {
    Team Team1;
    Team Team2;
    MatchResults MatchResults;

    public Match(Team Team1, Team Team2, MatchResults MatchResults) {
        this.Team1 = Team1;
        this.Team2 = Team2;
        this.MatchResults = MatchResults;
    }

}

class Team {
    String TeamName;
    String TeamIconUrl;

    public Team (String TeamName, String TeamIconUrl) {
        this.TeamName = TeamName;
        this.TeamIconUrl = TeamIconUrl;
    }
}

class MatchResults {
    String PointsTeam1;
    String PointsTeam2;

    public MatchResults(String PointsTeam1, String PointsTeam2) {
        this.PointsTeam1 = PointsTeam1;
        this.PointsTeam2 = PointsTeam2;
    }
}

Solution

  • As per the question you are suppose to use List<MatchResults> MatchResults since the API response contains a list of match results.

    Further to use the first position from the matchResults array you cna use it like this in your adapter :

    matchList.get(position).MatchResults.get(0).PointsTeam1