Два разных запроса, два разных Calls и One Recycler - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь это сделать ..

please click here for checking the image.

Я использую два разных ресурса запросов из одного и того же API и в MainActivity выполняю два разныхзвонки.Но я не могу показать содержимое, которое мне нужно из обоих JSON, в одном представлении RecyclerView.

MainActivity.java

public class MainActivity extends AppCompatActivity {
    private Retrofit retrofit;
    private static final String TAG = "Football";
    private RecyclerView recyclerView;
    private ListaPartidosAdapter listaPartidosAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = (RecyclerView)findViewById(R.id.recyclerView);
        listaPartidosAdapter = new ListaPartidosAdapter(this);
        recyclerView.setAdapter(listaPartidosAdapter);
        recyclerView.setHasFixedSize(true);
        final LinearLayoutManager layoutManager = new LinearLayoutManager(this, VERTICAL, true);
        recyclerView.setLayoutManager(layoutManager);

        retrofit = new Retrofit.Builder()
                .baseUrl("http://api.football-data.org/v2/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        obtenerDatos();
    }

    private void obtenerDatos() {

        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String todayDate=df.format(calendar.getTime());
        calendar.add(Calendar.DATE,3);
        String endDate = df.format(calendar.getTime());

        Log.i(TAG, "todayDate : " + todayDate);
        Log.i(TAG, "endDate : " + endDate);

        footballdataService service = retrofit.create(footballdataService.class);
        Call<PartidosRespuesta> partidosRespuestaCall = service.obtenerlistaPartidos(todayDate,endDate);
        Call<StandingsRespuesta> standingsRespuestaCall = service.obtenerStandings();

        partidosRespuestaCall.enqueue(new Callback<PartidosRespuesta>() {
            @Override
            public void onResponse(Call<PartidosRespuesta> call, Response<PartidosRespuesta> response) {
                if(response.isSuccessful()) {
                    PartidosRespuesta partidosRespuesta = response.body();
                    List<Partido> listaPartidos = partidosRespuesta.getMatches();
                    listaPartidosAdapter.adicionarListaPartidos((ArrayList<Partido>) listaPartidos);

                }
                else {
                    Log.e(TAG, "onResponse: " + response.errorBody());
                }
            }

            @Override
            public void onFailure(Call<PartidosRespuesta> call, Throwable t) {
                Log.e(TAG, "onFailure: " + t.getMessage());
            }
        });


        standingsRespuestaCall.enqueue(new Callback<StandingsRespuesta>() {
            @Override
            public void onResponse(Call<StandingsRespuesta> call, Response<StandingsRespuesta> response) {
                if(response.isSuccessful()) {
                    StandingsRespuesta standingsRespuesta = response.body();
                    List<Stand> listaStands = standingsRespuesta.getStandings();
                    listaPartidosAdapter.adicionarListaStands((ArrayList<Stand>) listaStands);
                }
            }

            @Override
            public void onFailure(Call<StandingsRespuesta> call, Throwable t) {

            }
        });
    }
}

Как я уже говорил, каждый запросимеет другую очередь вызова.Я не знаю, является ли это правильным способом, но думаю, что да, потому что каждый звонок имеет свой собственный сервис.

ListaPartidosAdapter.java

public class ListaPartidosAdapter extends RecyclerView.Adapter<ListaPartidosAdapter.ViewHolder> {

    private static final String TAG = "Football_Adapter";
    private ArrayList<Partido> dataset;
    private ArrayList<Stand> dataset_stand;
    private Context context;

    public ListaPartidosAdapter(Context context) {
        this.context = context;
        this.dataset = new ArrayList<Partido>();
        this.dataset_stand = new ArrayList<Stand>();
    }

    @Override
    public ListaPartidosAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_partidos, parent, false);
        return new ViewHolder(view);
    }


    @Override
    public void onBindViewHolder(ListaPartidosAdapter.ViewHolder holder, int position) {
        Partido p = dataset.get(position);
        String status = p.getStatus();

        if (status.equals("SCHEDULED")){
            String status_ = "SCH";
            holder.status.setText(status_);
        }
        holder.utcDate.setText(p.getUtcDate());


        Partido.EquipoCasa homeTeam = p.getHomeTeam();
        String id_homeTeam = homeTeam.getId();

        holder.homeTeam.setText(homeTeam.getName());

        Partido.EquipoVisita awayTeam = p.getAwayTeam();
        holder.awayTeam.setText(awayTeam.getName());

        Stand s = dataset_stand.get(position);
        Stand.Table table = (Stand.Table) s.getTable();
        Stand.Table.Equipo team = (Stand.Table.Equipo) table.getEquipo();
        String id_equipo = team.getId();
        holder.homeTeam.setText(team.getName());


        if(id_homeTeam.equals(id_equipo)){
            Glide.with(context)
                .load(team.getCrestUrl())
                .centerCrop()
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(holder.team);
            //holder.team.setImageDrawable(team.getCrestUrl());
        }


    }

    @Override
    public int getItemCount() {
        return dataset.size()+dataset_stand.size();
    }


    public void adicionarListaPartidos(ArrayList<Partido> listaPartidos){
        dataset.addAll(listaPartidos);
        notifyDataSetChanged();
    }


    public void adicionarListaStands(ArrayList<Stand> listaStands){
        dataset_stand.addAll(listaStands);
        notifyDataSetChanged();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private TextView status;
        private TextView utcDate;
        private TextView homeTeam;
        private TextView awayTeam;
        public ImageView team;


        public ViewHolder(View itemView) {
            super(itemView);

            status = (TextView) itemView.findViewById(R.id.status);
            utcDate = (TextView) itemView.findViewById(R.id.utcDate);
            homeTeam = (TextView) itemView.findViewById(R.id.homeTeam);
            awayTeam = (TextView) itemView.findViewById(R.id.awayTeam);
            team = (ImageView) itemView.findViewById(R.id.team);
        }
    }
}

проблема заключается в этой линии. Stand s = dataset_stand.get (position); , если комментарий с кодом ниже, Работает без использования второго JSON или второго запроса , но, как я показал на изображении, я хочуобъединить два разных запроса в одном представлении RecyclerView.

1 Ответ

0 голосов
/ 28 августа 2018

Постановка проблемы

Проблема заключается в этой строке. Stand s = dataset_stand.get (position); , если это комментарий с кодом ниже, Работает без использования второго JSON или второго запроса.

Да, ожидается.Зачем?Потому что вы вызываете метод RecyclerView.Adapter#notifyDataSetChanged() внутри adicionarListaPartidos(ArrayList<Partido> listaPartidos) после вставки данных в ArrayList в RecyclerView классе адаптера массива, который сообщает ArrayAdapter о перерисовке / обновлении компонентов внутри RecyclerView контейнера.

Теперь RecycelrView начинает связывание компонента в методе onBindViewHolder(ListaPartidosAdapter.ViewHolder holder, int position).Итак, что здесь происходит?

 @Override
public void onBindViewHolder(ListaPartidosAdapter.ViewHolder holder, int position) {
    Partido p = dataset.get(position);
    String status = p.getStatus();

    if (status.equals("SCHEDULED")){
        String status_ = "SCH";
        holder.status.setText(status_);
    }
    holder.utcDate.setText(p.getUtcDate());


    Partido.EquipoCasa homeTeam = p.getHomeTeam();

    // other code

    Stand s = dataset_stand.get(position);  // <====== the problem 

    // other code

}

Ваш список dataset_stand будет пустым (размер списка равен 0), пока вы не получите данные / ответ от метода standingsRespuestaCall.enqueue() в своей деятельности.

Имейте в виду, что метод Retrofit Call#enque() является асинхронным.Это означает, что в вашем случае метод obtenerDatos() выполняется сверху вниз за один удар.Вы получите данные только тогда, когда Retrofit вернет успешный ответ методом onResponse().

Самый простой способ решить эту проблему - закомментировать метод notifyDataSetChanged() внутри adicionarListaPartidos(ArrayList<Partido> listaPartidos).Как показано ниже

public void adicionarListaPartidos(ArrayList<Partido> listaPartidos){
   dataset.addAll(listaPartidos);
  //  notifyDataSetChanged();   // <======  just COMMENT OUT this line
}

Это предотвратит вызов onBindViewHolder().Когда второй запрос standingsRespuestaCall.enqueue() завершает свою работу, ваш код уведомляет об изменении набора данных.Как показано ниже.

public void adicionarListaStands(ArrayList<Stand> listaStands){
   dataset_stand.addAll(listaStands);
   notifyDataSetChanged();    // <==== DO NOT remove this
}

Примечание: Ваш код проблематичен.Вы используете несколько запросов для заполнения одного контейнера RecyclerView.Ваш RecyclerView не сможет отобразить запись, если standingsRespuestaCall.enqueue() не получит ответ от сервера.

PS: Пожалуйста, проверьте имена методов, которые я упоминал в своем ответе, и измените код соответствующим образом.Не путайте с именами методов.

...