RecyclerView — разная разметка — android recyclerview

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд
Загрузка...

Вопрос:


Смотрел, я смотрел в сторону RecyclerView и наконец решил кинуть ListView и на тебе!

В «плохом прошлом» мой ListView использовался для двух разметок. Сейчас я повторил это, но что-то упустил. Суть в следующем: разметки две, одна для правого сообщения (своего), другая для левого сообщения (чужого). Так вот, левые сообщения как и было размещены верно. Правые же «переехали» и теперь все слева. А веды правые должны быть справа! Причём, сообщения у меня оформлены по-разному и все выглядит как положено, но все слева!

Вот мой код адаптера. Первый код для RecyclerView 🙂

public class RVAdapter extends RecyclerView.Adapter<MainActivity.RVAdapter.AdapterHolder> {

    public class AdapterHolder extends RecyclerView.ViewHolder {

        TextView tv_full_author, tv_circle_author, tv_client, tv_text, tv_data;

        AdapterHolder(View itemView) {
            super(itemView);
            tv_full_author = (TextView)itemView.findViewById(R.id.full_nick);
            tv_circle_author = (TextView)itemView.findViewById(R.id.first_char_nick);
            tv_client = (TextView)itemView.findViewById(R.id.reply_marker);
            tv_text = (TextView)itemView.findViewById(R.id.message);
            tv_data = (TextView)itemView.findViewById(R.id.time);
    }
}
    ArrayList<HashMap<String, String>> adapterList;
    int type;

    RVAdapter(ArrayList<HashMap<String, String>> dat){
        adapterList = dat;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public AdapterHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(((i==0)? R.layout.item_right: R.layout.item_left), null);
        AdapterHolder pvh = new AdapterHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(AdapterHolder holder, int i) {
        HashMap<String,String> fast_parse = adapterList.get(i);
        String author_str = fast_parse.get("author");
        String client_str = fast_parse.get("client");
        String text_str = fast_parse.get("text");
        String data_str = fast_parse.get("data");
        holder.tv_full_author.setText(author_str);
        holder.tv_circle_author.setText(author_str.substring(0,1));
        if(!client_str.equals("0"))
        {
            holder.tv_client.setVisibility(View.VISIBLE);
            holder.tv_client.setText(client_str+",");

            if(client_str.equals(nick)&&(getItemViewType(i)==1))
            {
                holder.tv_client.setTextColor(Color.parseColor("#A40dff"));
            }
            else{
                holder.tv_client.setTextColor(Color.BLACK);
            }
        }
        else{
            holder.tv_client.setText("");
            holder.tv_client.setVisibility(View.GONE);
        }
        holder.tv_text.setText(text_str);
        holder.tv_data.setText(data_str);

    }

    @Override
    public int getItemViewType(int position)
    {
        if (adapterList.get(position).get("author").equals(nick))
        return 0;
        else
        return 1;
            }

        public int getItemViewTypeCount(){
            return 2;
        }

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

Есть подозрения, что в onCreateViewHolder() я как то неправильно создаю view, хотя и учитываю getItemViewType()

Автор вопроса: Flippy

Kirill Stoianov

Для реализации двух разных типов элементов списка нужно:

  • два ViewHolder‘а
  • переопределить метод getItemViewType
  • переопределить метод onCreateViewHolder
  • добавить switch в onBindViewHolder для того что бы различать разные ViewHolder

Реализация:

  • создаем ViewHolder‘ы

    public class ViewHolder1 extends RecyclerView.ViewHolder {
    
        private TextView label1, label2;
    
        public ViewHolder1(View v) {
            super(v);
            label1 = (TextView) v.findViewById(R.id.text1);
            label2 = (TextView) v.findViewById(R.id.text2);
        }
    }
    
    public class ViewHolder2 extends RecyclerView.ViewHolder {
    
        private ImageView ivExample;
    
        public ViewHolder2(View v) {
            super(v);
            ivExample = (ImageView) v.findViewById(R.id.ivExample);
         }
     }
    
  • Переопределяем метод getItemViewType:

      @Override
      public int getItemViewType(int position) {
          if (items.get(position) instanceof User) {
              return USER;
          } else if (items.get(position) instanceof String) {
              return IMAGE;
          }
          return -1;
      }
    
  • переопределяем метод onCreateViewHolder:

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
    
      RecyclerView.ViewHolder viewHolder;
      LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
    
      switch (viewType) {
          case USER:
              View v1 = inflater.inflate(R.layout.layout_viewholder1, viewGroup, false);
              viewHolder = new ViewHolder1(v1);
              break;
          case IMAGE:
              View v2 = inflater.inflate(R.layout.layout_viewholder2, viewGroup, false);
              viewHolder = new ViewHolder2(v2);
              break;
          default:
              View v = inflater.inflate(android.R.layout.simple_list_item_1, viewGroup, false);
              viewHolder = new RecyclerViewSimpleTextViewHolder(v);
              break;
      }
      return viewHolder;
     }
    
  • определяем какой тип элемента списка к нам попал:

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
      switch (viewHolder.getItemViewType()) {
          case USER:
              ViewHolder1 vh1 = (ViewHolder1) viewHolder;
              configureViewHolder1(vh1, position);
              break;
          case IMAGE:
              ViewHolder2 vh2 = (ViewHolder2) viewHolder;
              configureViewHolder2(vh2, position);
              break;
          default:
              RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder;
              configureDefaultViewHolder(vh, position);
              break;
      }
    }
    

Попробуйте добавить себе такую реализацию, должно все получиться!

Источник

Вам также может быть интересно:

Drag and Drop UWP — c# xaml mvvm
Вопрос: Нужно иметь возможность добавлять изображения в приложение путем перетаскивания из файловой системы У Grid включил AllowDrop. Но как добавить перетаскиваемые изображения в коллекцию? Т.к. те ...
Растягивание Высоты , Резина — html css html5
Вопрос: Здравствуйте! Реализовал резиновый дизайн. Растягивается ширина, но длина по % не растягивается. Возможно ли это реализовать? Или так и задумано, растягивание только на ширину ...
Jquery position().left Как быть на мобильниках? — javascript jquery css
Вопрос: На мобильных устройствах, если зумишь экран, position всегда разный. $('g').position().left Как сделать так, чтобы он не менял свои значения? Автор вопроса: ...
Jquery position().left Как быть на мобильниках? — javascript jquery css
Вопрос: На мобильных устройствах, если зумишь экран, position всегда разный. $('g').position().left Как сделать так, чтобы он не менял свои значения? Автор вопроса: ...
requestAnimation и очередность отрисовки — javascript canvas
Вопрос: Здравствуйте! Реализовал 2D игру и в Edge работает все плавно и круто, но в Firefox'e подвисает, сказали, что нужно сделать, чтобы раз-два момент и все ...
Контекстное/всплывающее меню в Android — java android popup
Вопрос: Есть ли техническая возможность сделать приложение, добавляющее свое контекстное или всплывающее меню в любом месте системы? Хочу, чтобы при выделении любого текста появлялась дополнительная кнопка ...
Контекстное/всплывающее меню в Android — java android popup
Вопрос: Есть ли техническая возможность сделать приложение, добавляющее свое контекстное или всплывающее меню в любом месте системы? Хочу, чтобы при выделении любого текста появлялась дополнительная кнопка ...
Завершить службы циклом — c# windows-service
Вопрос: Можно ли остановить службы циклом? У меня есть список служб, занёс их в List List<string> name = new List<string> { "AdobeARMservice", "RemoteRegistry", "TermService", "Messenger", "SSDPSRV", ...
Завершить службы циклом — c# windows-service
Вопрос: Можно ли остановить службы циклом? У меня есть список служб, занёс их в List List<string> name = new List<string> { "AdobeARMservice", "RemoteRegistry", "TermService", "Messenger", "SSDPSRV", ...
RecyclerView — разная разметка — android recyclerview
Вопрос: Смотрел, я смотрел в сторону RecyclerView и наконец решил кинуть ListView и на тебе! В "плохом прошлом" мой ListView использовался для двух разметок. Сейчас я ...
Как правильно передать массив аргументом для пользовательской функции — php
Вопрос: Если не брать в функцию все это, тогда результат работает. А если вот так в функции все выполнять, тогда PHP ругается: «Invalid ...
Как правильно передать массив аргументом для пользовательской функции — php
Вопрос: Если не брать в функцию все это, тогда результат работает. А если вот так в функции все выполнять, тогда PHP ругается: «Invalid ...
ViewPager внутри ViewPager — такие матрешки работают? — android viewpager
Вопрос: Доброго времени суток. Назрела новая задача. Есть каталог мастеров. При выборе конкретного мастера открывается его страница (активити с ViewPager), и теперь мастеров можно перелистывать свайпом. ...
Почему id всегда 1 Yii2 — yii авторизация
Вопрос: Использую все как по документации. Для получения информации о пользователе использую $identity = $model->findOne(]); И каким бы не был email, id пользователя всегда ...
Механизм добавления новых настроек в админке wp и корректный рендеринг — php wordpress
Вопрос: Есть следующий код: $tabs = array( 'vk', 'facebook', 'instagram' ); $saved = false; if(isset($_POST) && $_POST == 'Y') { $plugin_source_tabs = $_POST; update_option('plugin_source_tabs', ...