2016-04-25 3 views
0

У меня проблема с моим recyclerview. Когда я прокручиваю вниз, все в порядке, но когда я перехожу назад к вершине, меняет образ, который я устанавливаю на изображения. Вот мой код адаптера:RecyclerView itemView, который можно изменить при прокрутке вверх

@Override 
    public FeedsHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_item, parent, false); 

     final FeedsHolder holder = new FeedsHolder(view); 

     //Query 

     QueryOptions options = new QueryOptions(); 

     options.setRelated(Arrays.asList("usersThatLike")); 

     BackendlessDataQuery query = new BackendlessDataQuery(); 

     query.setQueryOptions(options); 

     Backendless.Data.of(Feeds.class).find(query, new AsyncCallback<BackendlessCollection<Feeds>>() { 

      @Override 

      public void handleResponse(BackendlessCollection<Feeds> response) { 
       String userId = Backendless.UserService.CurrentUser().getObjectId(); 
       for (Feeds feed : response.getData()) { 
        feed = list.get(holder.getAdapterPosition()); 

        List<BackendlessUser> likedUsers = feed.getUsersThatLike(); 
        for (BackendlessUser user : likedUsers) 
         if (user.getObjectId().equals(userId)) { 
    //** GOOGLE MATERIAL ICON WITH FILLED HEART 
          setBackground(holder.like, ContextCompat.getDrawable(context, R.drawable.ic_favorite_black_24dp)); 
         } else if (!user.getObjectId().equals(userId)) { 
    //** GOOGLE MATERIAL ICON WITH EMPTY HEART 
          setBackground(holder.like, ContextCompat.getDrawable(context, R.drawable.ic_favorite_border_black_24dp)); 
         } 
       } 

      } 

      @Override 

      public void handleFault(BackendlessFault backendlessFault) { 

      } 

     }); 
     return holder; 
    } 

И чем я установить изображение по умолчанию holder.like ImageView в onBindViewHolder:

@Override 
    public void onBindViewHolder(final FeedsHolder holder, final int position) { 
     holder.like.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_favorite_border_black_24dp)); 
    } 

И я думаю, что это проблема ...

Но я не знаю, как это решить, потому что без этой строки кода мои другие строки recyclerview будут иметь разные образы: у некоторых будет наполненное сердце, а у некоторых будет пустое.

Так что, пожалуйста, помогите мне найти решение.

EDIT: Проводка мой код адаптера

public class FeedAdapter extends RecyclerView.Adapter<FeedAdapter.FeedsHolder> { 

    private List<Feeds> list; 
    private Context context; 
    private static List<Long> selectedIds; 
    List<BackendlessUser> backendlessUserList; 
    private List<Comments> cake = new ArrayList<>(); 
    private static String TAG = "MainActivity"; 

    public FeedAdapter(Context context, List<Feeds> list) { 
     this.context = context; 
     this.list = list; 

    } 

    @Override 
    public FeedsHolder onCreateViewHolder(ViewGroup parent, final int viewType) { 
     View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_item, parent, false); 

     final FeedsHolder holder = new FeedsHolder(view); 

     //Query 

     QueryOptions options = new QueryOptions(); 

     options.setRelated(Arrays.asList("usersThatLike")); 

     BackendlessDataQuery query = new BackendlessDataQuery(); 

     query.setQueryOptions(options); 

     Backendless.Data.of(Feeds.class).find(query, new AsyncCallback<BackendlessCollection<Feeds>>() { 

      @Override 

      public void handleResponse(BackendlessCollection<Feeds> response) { 
       myFeeds = response; 
       String userId = Backendless.UserService.CurrentUser().getObjectId(); 
       for (Feeds feed : response.getData()) { 
        feed = list.get(holder.getAdapterPosition()); 

        List<BackendlessUser> likedUsers = feed.getUsersThatLike(); 
        backendlessUserList = likedUsers; 
        for (BackendlessUser user : likedUsers) 
         if (user.getObjectId().equals(userId)) { 
          setBackground(holder.like, ContextCompat.getDrawable(context, R.drawable.ic_favorite_black_24dp)); 
         } else if (!user.getObjectId().equals(userId)) { 
          setBackground(holder.like, ContextCompat.getDrawable(context, R.drawable.ic_favorite_border_black_24dp)); 
         } 
       } 

      } 

      @Override 

      public void handleFault(BackendlessFault backendlessFault) { 

      } 

     }); 
     return holder; 
    } 

    @Override 
    public void onBindViewHolder(final FeedsHolder holder, final int position) { 
     //Starting Feeds 
     final Feeds feeds = list.get(position); 

     holder.like.setBackground(ContextCompat.getDrawable(context, R.drawable.ic_favorite_border_black_24dp)); 

     //Name 
     holder.name.setText(feeds.getOwner()); 

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

    public class FeedsHolder extends RecyclerView.ViewHolder { 
     //Setup Views 
     CardView card; 
     TextView name; 

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

      //Assign views by ID 
      card = (CardView) itemView.findViewById(R.id.cv); 
      name = (TextView) itemView.findViewById(R.id.commenter); 
     } 
    } 
} 
+0

Вы не должны запрашивать бэкэнд внутри onCreateViewHolder, а не на внешнюю сторону и передавать ответ адаптеру через конструктор или сеттер, опять же, проверьте мой пример, довольно strightforward –

+0

Я хотел запросить данные без привязки в onCreateViewholder, чтобы он не будет обновляться каждый раз, когда список прокручивается вверх/вниз (я знаю, как работает RecyclerView ... Просто попробовал здесь немного удачи). Если я помещаю код запроса в onBindViewHolder, чем обратное рисование, это пустое сердце для всех строк, и оно обновляется через 3/4 секунды, когда вы продолжаете просмотр строки (требуется время для запроса данных). Поэтому я хотел сделать его прочным, чтобы он не обновлялся каждый раз, когда вы прокручивали вверх/вниз ... – Asama

+0

«Я хотел запросить данные без привязки в onCreateViewholder, чтобы он не обновлялся каждый раз, когда список прокручивается вверх/вниз «.. Я думаю, вы ошибаетесь, вам не нужно вызывать бэкэнд внутри onCreateViewholder. Вызовите его снаружи и сохраните ответ в переменной внутри адаптера (пивоваренные заводы в моем примере). Затем обновите представления, используя onBindViewHolder. –

ответ

0

Вы должны держать состояние клетки (например, какое изображение должно быть показано) где-то. Один из вариантов - иметь список с одинаковым размером вашего источника данных и хранить значение, указывающее, будет ли элемент в этой позиции иметь пустое сердце, полное сердце или ничего, и, наконец, проверить это значение в onBindViewHolder и обновите представление должным образом.

EDIT: Вот пример:

public class BreweryRecyclerViewAdapter 
     extends RecyclerView.Adapter<BreweryRecyclerViewAdapter.BreweryRecyclerViewViewHolder> 
     implements View.OnClickListener { 

    private static List<Long> selectedIds; 

    private Context context; 
    private List<Brewery> breweries; 
    private View.OnClickListener clickListener; 

    public BreweryRecyclerViewAdapter(Context context) { 
     clearBreweries(); 
     this.context = context; 
    } 

    public BreweryRecyclerViewAdapter(List<Brewery> breweries) { 
     setBreweries(breweries); 
    } 

    public List<Brewery> getBreweries() { 
     return breweries; 
    } 

    public void setBreweries(List<Brewery> breweries) { 
     this.breweries = breweries; 
     selectedIds = new ArrayList<>(); 
    } 

    public void setClickListener(View.OnClickListener clickListener) { 
     this.clickListener = clickListener; 
    } 

    public void clearBreweries() { 
     this.breweries = Collections.emptyList(); 
     selectedIds = new ArrayList<>(); 
    } 

    @Override 
    public BreweryRecyclerViewViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     LayoutInflater layoutInflater = LayoutInflater.from(context); 
     View itemView = layoutInflater.inflate(R.layout.item_brewery, parent, false); 
     itemView.setOnClickListener(this); 
     return new BreweryRecyclerViewViewHolder(context, itemView); 
    } 

    @Override 
    public void onBindViewHolder(BreweryRecyclerViewViewHolder holder, int position) { 
     Brewery brewery = breweries.get(position); 
     if (selectedIds.contains(brewery.getId())) { 
      holder.openSecondaryLayoutVisibility(); 
     } else { 
      holder.closeSecondaryLayoutVisibility(); 
     } 
     holder.update(brewery); 
    } 

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

    @Override 
    public void onClick(View view) { 
     if (clickListener != null) { 
      clickListener.onClick(view); 
     } 
    } 

    public static class BreweryRecyclerViewViewHolder extends RecyclerView.ViewHolder { 

     @BindView(R.id.brewery_name) 
     TextView breweryName; 

     @BindView(R.id.brewery_distance) 
     TextView breweryDistance; 

     @BindView(R.id.brewery_duration) 
     TextView breweryDuration; 

     @BindView(R.id.brewery_time) 
     TextView breweryTime; 

     @BindView(R.id.brewery_is_happy_hour) 
     ImageView breweryIsHappyHour; 

     @BindView(R.id.secondary) 
     RelativeLayout secondaryLayout; 

     @BindView(R.id.brewery_description) 
     TextView breweryDescription; 

     private Context context; 
     private Brewery brewery; 

     public BreweryRecyclerViewViewHolder(Context context, View itemView) { 
      super(itemView); 
      ButterKnife.bind(this, itemView); 
      this.context = context; 
     } 

     public Brewery getBrewery() { 
      return brewery; 
     } 

     public void toggleSecondaryLayoutVisibility(Long id) { 
      if (secondaryLayout.getVisibility() != View.VISIBLE) { 
       openSecondaryLayoutVisibility(); 
       selectedIds.add(id); 
      } else { 
       closeSecondaryLayoutVisibility(); 
       selectedIds.remove(id); 
      } 
     } 

     public void openSecondaryLayoutVisibility() { 
      secondaryLayout.setVisibility(View.VISIBLE); 
     } 

     public void closeSecondaryLayoutVisibility() { 
      secondaryLayout.setVisibility(View.GONE); 
     } 

     @OnClick(R.id.view_route_button) 
     public void viewRouteButtonClicked(Button button) { 
      String latitude = brewery.getLocation().getLatitude().toString(); 
      String longitude = brewery.getLocation().getLongitude().toString(); 
      Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(
        String.format("http://maps.google.com/maps?daddr=%s,%s", latitude, longitude))); 
      context.startActivity(intent); 
     } 

     public void update(Brewery brewery) { 
      breweryName.setText(brewery.getName()); 
      if (brewery.getDistanceHumanReadable() == null) { 
       breweryDistance.setVisibility(View.GONE); 
      } else { 
       breweryDistance.setText(String.format("%s | ", brewery.getDistanceHumanReadable())); 
       breweryDistance.setVisibility(View.VISIBLE); 
      } 
      if (brewery.getDurationHumanReadable() == null) { 
       breweryDuration.setVisibility(View.GONE); 
      } else { 
       breweryDuration.setText(String.format("%s | ", brewery.getDurationHumanReadable())); 
       breweryDuration.setVisibility(View.VISIBLE); 
      } 
      breweryTime.setText(String.format("%shs a %shs", brewery.getOpen(), brewery.getClose())); 
      breweryIsHappyHour.setVisibility(brewery.isHappyHour() ? View.VISIBLE : View.GONE); 
      breweryDescription.setText(brewery.getDescription()); 

      this.brewery = brewery; 
     } 

    } 

} 

положить внимание на onBindViewHolder и в toggleSecondaryLayoutVisibility, чтобы увидеть использование selectedIds, чтобы сохранить состояние клеток.

:
+0

Можете ли вы привести пример кода для сохранения состояния ячейки? – Asama

+0

уверен, дайте мне несколько минут. –

+0

Спасибо за ваш пример кода. Что такое SecondLayout в вашем примере? Кажется, трудно понять, поскольку есть так много функций, которых у меня нет в моем адаптере. Можете ли вы предоставить свою электронную почту, чтобы я мог отправить вам полный код, чтобы вы могли лучше понять его? – Asama

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