两种不同的要求,两种不同的呼叫和一个回收站

时间:2018-08-26 21:30:23

标签: android android-recyclerview retrofit2 recycler-adapter

我正在尝试这样做。

please click here for checking the image

我正在消耗来自同一API的两个不同的请求资源,并且在MainActivity中进行了两个不同的调用。但是,我无法在一个RecyclerView视图上显示来自两个JSON的内容。

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 :(得分:0)

问题陈述

  

问题出在这一行。 Stand s = dataset_stand.get(position); ,如果使用下面的代码对其进行注释,该方法无需使用第二个JSON或第二个请求即可。

是的,这是预期的。为什么?因为您是在将数据插入adicionarListaPartidos(ArrayList<Partido> listaPartidos)数组适配器类中的ArrayList之后通知RecyclerView重绘/刷新ArrayAdapter容器内的组件之后在RecyclerView内调用RecycelrView内的RecyclerView.Adapter#notifyDataSetChanged()方法。

现在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

您的standingsRespuestaCall.enqueue()列表将为空(列表的大小为0),直到您从活动中的obtenerDatos()方法获得数据/响应为止。

请记住,翻新的Call#enque()方法是异步的。这意味着在您的情况下,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 } 完成时,它的操作按照您的代码通知数据集已更改。如下所示。

standingsRespuestaCall.enqueue()

侧面说明::您的代码有问题。您正在使用多个请求来填充单个RecyclerView容器。如果Sub FastDelete() Dim rng As Range, rngData As Range, rngVisible As Range Const CRITERIA$ = "SOME_VALUE" Set rng = Range("A1").CurrentRegion '//Whole table With rng '//Table without header Set rngData = .Offset(1).Resize(.Rows.Count - 1) End With '// Filter by column "A" rng.AutoFilter Field:=1, Criteria1:=CRITERIA On Error Resume Next '//In case if no values filtered Set rngVisible = rng.SpecialCells(xlCellTypeVisible) If Err = 0 Then rngVisible.EntireColumn.Delete End If On Error GoTo 0 End Sub 无法从服务器获得响应,您的RecyclerView将无法显示记录。

PS::请正确检查我在答案中提到的方法名称,并相应地更改代码。不要与方法名称混淆。