繁体   English   中英

如何将数据从两个改造请求传递到单个recyclerview适配器

[英]How to pass data from two retrofit requests to a single recyclerview adapter

这里的新手-作为练习,我正在使用google places搜索nearby餐馆并获取其详细信息。 我还使用google place details来获取有关特定餐厅的更多信息。 我正在使用Retrofit解析数据。

问题 :我有三个ArrayListrestaurantNamerestaurantAddressrestaurantPhoneNum 我无法将所有三个ArrayLists传递到我的recyclerview适配器中。

获取附近餐厅的方法:

private void getNearbySearchUrl(final double latitude, final double longitude, final String nearbyPlace){

    MapInterface retrofit = new Retrofit.Builder()
            .baseUrl("https://maps.googleapis.com/maps/api/place/nearbysearch/")
            .addConverterFactory(GsonConverterFactory.create())
            .build().create(MapInterface.class);

    Call<Result> call = retrofit.getResults("65.9667,-18.5333", PROXIMITY_RADIUS, "restaurant", placesKey);

    call.enqueue(new Callback<Result>() {
        @Override
        public void onResponse(Call<Result> call, Response<Result> response) {
            ArrayList<String> restaurantName = new ArrayList<>();
            ArrayList<String> restaurantAddress = new ArrayList<>();
            GetNearbyPlaces b = new GetNearbyPlaces();

            for(int i = 0; i <= response.body().getResults().size() - 1 ; i++) {
                restaurantName.add(response.body().getResults().get(i).getName());
                restaurantAddress.add(response.body().getResults().get(i).getVicinity());

                //get telephone number through this method
                getPlaceDetailsUrl(response.body().getResults().get(i).getPlaceId());

            }

            Collections.reverse(restaurantName);
            Collections.reverse(restaurantAddress);

            adapter = new RestaurantListAdapter(restaurantName, restaurantAddress,
                    response.body().getResults().size());
            mRecyclerView.setAdapter(adapter);
        }
        @Override
        public void onFailure(Call<Result> call, Throwable t) {
            Log.d("Matt", "fail");
        }
    });
}

获取有关餐厅方法的更多信息:

public String getPlaceDetailsUrl(final String placeId) {
    final String mPlace = placeId;

    MapInterface retrofit = new Retrofit.Builder()
            .baseUrl("https://maps.googleapis.com/maps/api/place/details/")
            .addConverterFactory(GsonConverterFactory.create())
            .build().create(MapInterface.class);

    Call<Result> call = retrofit.getPlaceDetails(placeId, placesKey);

    call.enqueue(new Callback<Result>() {
        @Override
        public void onResponse(Call<Result> response) {
            ArrayList<String> restaurantPhoneNum = new ArrayList<>();
            if (response.body().getResult().getFormattedPhoneNumber() == null ){
                return;
            }
            restaurantPhoneNum.add(response.body().getResult().getFormattedPhoneNumber());

        }

        @Override
        public void onFailure(Call<Result> call, Throwable t) {
            return;
        }
    });
}

适配器:

public class RestaurantListAdapter extends RecyclerView.Adapter<RestaurantListAdapter.RestaurantListHolder> {
    ArrayList<String> restaurantName = new ArrayList<>();
    ArrayList<String> restaurantAddress = new ArrayList<>();
    ArrayList<String> restaurantPhoneNum = new ArrayList<>();

private int restaurantCount;

public RestaurantListAdapter(ArrayList<String> resName, ArrayList<String> resAddress,
                             int resCount){
    restaurantName = resName;
    restaurantAddress = resAddress;
    restaurantCount = resCount;
}

public RestaurantListAdapter(ArrayList<String> resPhoneNum){
    restaurantPhoneNum = resPhoneNum;
}



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

@Override
public void onBindViewHolder(RestaurantListHolder holder, int position) {
    Log.d("Matt1", String.valueOf(position) + " size:" + String.valueOf(restaurantName.size()) + restaurantName.toString());
    holder.bindView(position);
}



@Override
public int getItemCount() {
    return restaurantCount;
}

public class RestaurantListHolder extends RecyclerView.ViewHolder{
    public TextView mRestaurantName;
    public TextView mAddress;
    public TextView mPhone;
    public TextView mDistance;
    public ImageView mRestaurantPic;

    public RestaurantListHolder(View itemView) {
        super(itemView);
        mRestaurantName = (TextView) itemView.findViewById(R.id.tvRestaurantName);
        mAddress = (TextView) itemView.findViewById(R.id.tvAddress);
        mPhone = (TextView) itemView.findViewById(R.id.tvPhone);
    }
    public void bindView(int arrayNum){
        mRestaurantName.setText(restaurantName.get(arrayNum));
        mAddress.setText(restaurantAddress.get(arrayNum));
        mPhone.setText("123 123 123 123 ");
        mRestaurantPic.setImageResource(R.drawable.rzkibble_chinese);
    }
}

}

好吧,第一条建议,尝试自己考虑一下。 我知道您知道如何解决这个问题:)。

您的问题尚不清楚:

  • 您要在两个请求都执行后更新适配器
  • 您将在每次请求后更新适配器

我想您想以第一种方式实现它。 您需要具有执行requestOne,执行requestTwo的逻辑,并且当两个请求都成功时 ,更新适配器。 您可以使用一些全局标志arePlacesLoadedareDetailsLoaded来实现此目的 ,并使用第三个方法来接收请求结果并检查这些标志。

手动方式(伪)

boolean arePlacesLoaded;
boolean areDetailsLoaded;

void loadPlaces(){
    if(success){
        arePlacesLoaded = true;
        savePlaces(places)
        updateAdapter()
    }
}

void loadDetails(){
    if(success){
        areDetailsLoaded = true;
        saveDetails(details)
        updateAdapter()
    }
}

void updateAdaper(){
    if(arePlacesLoaded && areDetailsLoaded){
        adaper.onDataChange(places, details);
    }
}

您可以使用一些队列来放置请求,一旦请求被执行且队列为空->更新适配器。

另一个更好的方法是使用RxJava及其zipWith运算符,该实现仅用几行代码(请记住,改造已移至应用程序的某个位置)这是该运算符的大理石图: 拉链配大理石

因此,请求一个执行,然后请求两个。 您将提供一个函数,该函数将数据合并到一个更好的对象中,称为Hotel,并将适配器与Hotel对象数组一起提供给适配器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM