2017-02-09 1 views
0

Новичок здесь - Как практика, я использую google places, чтобы найти nearby ресторанов и получить их данные. Я также пользуюсь google place details, чтобы узнать больше о конкретном ресторане. Я использую Retrofit для анализа данных.Как передать данные из двух модифицированных запросов в один адаптер recyclerview

Проблема: У меня есть три ArrayList, restaurantName, restaurantAddress и restaurantPhoneNum. Я не могу передать все три 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); 
    } 
} 

}

+0

Два способа: 1.Если вы хотите обновить свой адаптер в двух итерациях (рано готовый к взаимодействию с списком пользователей), тогда сохраните общий объект для подачи адаптера из обоих вызовов. 2. Если вы хотите показать полную информацию после обоих вызовов, выполните вызовы в синхронном порядке и подайте всю информацию в один объект и передайте ее адаптеру для рисования. ... я надеюсь, что это имеет смысл для вас :) – harneev

ответ

1

Хорошо, сначала совет, попробуй подумать об этом немного по своему усмотрению. Я знаю, что вы знаете, как это решить :).

Ваш вопрос остается неясным:

  • вы хотите обновить адаптер после того, как оба запроса выполняются
  • вы будете обновлять адаптер после каждого запроса

Я полагаю, что вы хотите реализовать это в первую очередь. У вас должна быть логика, которая выполняет requestOne, выполняет requestTwo, и когда оба запроса успешно, обновите адаптер. Вы можете сделать это с помощью некоторых глобальных флагов arePlacesLoaded и areDetailsLoaded и иметь третий метод, который получает результат запроса и проверяет эти флаги.

Ручной способ (псевдо)

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 оператора, где реализация занимает несколько строк только (имея в виду, что Модифицированная перемещается где-то в ядре приложения) Вот мраморная схема этого оператор: zipWith marble

Итак, запросите один, а затем запросите два. Вы предоставите функцию, которая собирается объединить данные в какой-то лучший объект под названием «Отель», и вы будете комбинировать адаптер с массивом объектов отеля.

Смежные вопросы