Где манипулировать данными в Recyclerview Adapter (Android) - PullRequest
1 голос
/ 17 апреля 2019

Моя дата и время в настоящее время хранятся как метка времени UNIX. Я хочу отобразить это как ч: мм в моем Recyclerview.

Где я должен преобразовать метку времени UNIX в обычное время в RecyclerView Adapter / Viewholder (с точки зрения наилучшей производительности)?

Должен ли я сделать это в getItemViewType(int position) функции RecyclerView.Adapter, onBindViewHolder или bind класса ViewHolder?

Редактировать: Мой код

public class ChatListAdapter extends RecyclerView.Adapter {


    private final LayoutInflater mInflater;
    private List<Chat> mChats;
    private final String ownerMe = "OWNER_ME";
    private static final int VIEW_TYPE_MESSAGE_ME = 1;
    private static final int VIEW_TYPE_MESSAGE_ME_CORNER = 2;
    private static final int VIEW_TYPE_MESSAGE_BF = 3;
    private static final int VIEW_TYPE_MESSAGE_BF_CORNER = 4;

    ChatListAdapter(Context context) {mInflater = LayoutInflater.from(context);}

    @Override
    public int getItemViewType(int position) {
        Chat chat = mChats.get(position);

        if(chat.getUser().equals(ownerMe)) {
            if(position == mChats.size()-1) {
                return VIEW_TYPE_MESSAGE_ME_CORNER;
            }
            if(chat.getUser().equals(mChats.get(position+1).getUser())) {
                return VIEW_TYPE_MESSAGE_ME;
            } else {
                return VIEW_TYPE_MESSAGE_ME_CORNER;
            }
        } else {
            if(position == mChats.size()-1) {
                return VIEW_TYPE_MESSAGE_BF_CORNER;
            }
            if(chat.getUser().equals(mChats.get(position+1).getUser())) {
                return VIEW_TYPE_MESSAGE_BF;
            } else {
                return VIEW_TYPE_MESSAGE_BF_CORNER;
            }
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;

        if(viewType == VIEW_TYPE_MESSAGE_ME || viewType == VIEW_TYPE_MESSAGE_ME_CORNER) {
            view = mInflater.inflate(R.layout.recyclerview_item_right, parent, false);
            return new MeMessageHolder(view);
        } else if (viewType == VIEW_TYPE_MESSAGE_BF || viewType == VIEW_TYPE_MESSAGE_BF_CORNER) {
            view = mInflater.inflate(R.layout.recyclerview_item_left, parent, false);
            return new BfMessageHolder(view);
        }
        return null;

    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (mChats != null) {
            Chat current = mChats.get(position);
            long unixTime= current.getUnixTime();
            Date time = new java.util.Date(unixTime*1000L);
            SimpleDateFormat sdf = new java.text.SimpleDateFormat("h:mm a");
            String formattedTime = sdf.format(time);

            switch (holder.getItemViewType()) {
                case VIEW_TYPE_MESSAGE_ME:
                    ((MeMessageHolder) holder).bind(current, formattedTime, false);
                    break;
                case VIEW_TYPE_MESSAGE_ME_CORNER:
                    ((MeMessageHolder) holder).bind(current, formattedTime, true);
                    break;
                case VIEW_TYPE_MESSAGE_BF:
                    ((BfMessageHolder) holder).bind(current, formattedTime, false);
                    break;
                case VIEW_TYPE_MESSAGE_BF_CORNER:
                    ((BfMessageHolder) holder).bind(current, formattedTime, true);
                    break;
            }
        }
    }

    class MeMessageHolder extends RecyclerView.ViewHolder {
        private final TextView chatItemView;
        private final ImageView cornerRightIImageView;
        private final ConstraintLayout constraintLayout;
        private final TextView timeItemView;


        private MeMessageHolder(View itemView) {
            super(itemView);
            chatItemView = itemView.findViewById(R.id.textView);
            cornerRightIImageView = itemView.findViewById(R.id.corner_view_right);
            constraintLayout = itemView.findViewById(R.id.chat_bubble_id);
            timeItemView = itemView.findViewById(R.id.text_message_time);

        }

        void bind(Chat chat, String formattedTime, boolean isCorner) {
            chatItemView.setText(chat.getMessage());
            timeItemView.setText(formattedTime);
            if(isCorner) {
                constraintLayout.setBackgroundResource(R.drawable.chat_bubble_v2);
            } else {
                cornerRightIImageView.setVisibility(View.INVISIBLE);
            }
        }
    }

    class BfMessageHolder extends RecyclerView.ViewHolder {
        private final TextView chatItemView;
        private final ImageView cornerLeftImageView;
        private final ConstraintLayout constraintLayout;
        private final TextView timeItemView;

        private BfMessageHolder(View itemView) {
            super(itemView);
            chatItemView = itemView.findViewById(R.id.textView);
            cornerLeftImageView = itemView.findViewById(R.id.corner_view_left);
            constraintLayout = itemView.findViewById(R.id.chat_bubble_id);
            timeItemView = itemView.findViewById(R.id.text_message_time);
        }

        void bind(Chat chat, String formattedTime, boolean isCorner) {
            chatItemView.setText(chat.getMessage());
            timeItemView.setText(formattedTime);
            if(isCorner) {
                constraintLayout.setBackgroundResource(R.drawable.chat_bubble_v3);
            } else {
                cornerLeftImageView.setVisibility(View.INVISIBLE);
            }
        }
    }

    void setChats(List<Chat> chats) {
        mChats = chats;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        if(mChats!=null)
            return mChats.size();
        else return 0;
    }
}

Это правильный метод? Я отформатировал дату в onBindViewHolder методе

Ответы [ 5 ]

1 голос
/ 17 апреля 2019

Это похоже на бизнес-логику. Поэтому я рекомендую перенести конвертацию метки времени в UNIX, например, в модель.

class Chat {

   private Long unixTime;

   // another code

   public Long getUnixTime() {
      return unixTime;
   }

   public String convertedUnixTimeToString(String format) {
      // Also need to add some format validation     
      if(format == null) {
         // do some action, like trowing exception, or setting default value in format
      } 

      Date time = new java.util.Date(unixTime*1000L);
      SimpleDateFormat sdf = new java.text.SimpleDateFormat(format);

      return sdf.format(time);
   }

}

Я рекомендую использовать JodaTime для форматирования даты и времени. Очень полезная вещь.

А потом просто измените свой код


public class ChatListAdapter extends RecyclerView.Adapter {


    private final LayoutInflater mInflater;
    private List<Chat> mChats;
    private final String ownerMe = "OWNER_ME";
    private static final int VIEW_TYPE_MESSAGE_ME = 1;
    private static final int VIEW_TYPE_MESSAGE_ME_CORNER = 2;
    private static final int VIEW_TYPE_MESSAGE_BF = 3;
    private static final int VIEW_TYPE_MESSAGE_BF_CORNER = 4;

    ChatListAdapter(Context context) {mInflater = LayoutInflater.from(context);}

    @Override
    public int getItemViewType(int position) {
        Chat chat = mChats.get(position);

        if(chat.getUser().equals(ownerMe)) {
            if(position == mChats.size()-1) {
                return VIEW_TYPE_MESSAGE_ME_CORNER;
            }
            if(chat.getUser().equals(mChats.get(position+1).getUser())) {
                return VIEW_TYPE_MESSAGE_ME;
            } else {
                return VIEW_TYPE_MESSAGE_ME_CORNER;
            }
        } else {
            if(position == mChats.size()-1) {
                return VIEW_TYPE_MESSAGE_BF_CORNER;
            }
            if(chat.getUser().equals(mChats.get(position+1).getUser())) {
                return VIEW_TYPE_MESSAGE_BF;
            } else {
                return VIEW_TYPE_MESSAGE_BF_CORNER;
            }
        }
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view;

        if(viewType == VIEW_TYPE_MESSAGE_ME || viewType == VIEW_TYPE_MESSAGE_ME_CORNER) {
            view = mInflater.inflate(R.layout.recyclerview_item_right, parent, false);
            return new MeMessageHolder(view);
        } else if (viewType == VIEW_TYPE_MESSAGE_BF || viewType == VIEW_TYPE_MESSAGE_BF_CORNER) {
            view = mInflater.inflate(R.layout.recyclerview_item_left, parent, false);
            return new BfMessageHolder(view);
        }
        return null;

    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (mChats != null) {
            Chat current = mChats.get(position);

            switch (holder.getItemViewType()) {
                case VIEW_TYPE_MESSAGE_ME:
                    ((MeMessageHolder) holder).bind(current, false);
                    break;
                case VIEW_TYPE_MESSAGE_ME_CORNER:
                    ((MeMessageHolder) holder).bind(current, true);
                    break;
                case VIEW_TYPE_MESSAGE_BF:
                    ((BfMessageHolder) holder).bind(current, false);
                    break;
                case VIEW_TYPE_MESSAGE_BF_CORNER:
                    ((BfMessageHolder) holder).bind(current, true);
                    break;
            }
        }
    }

    class MeMessageHolder extends RecyclerView.ViewHolder {
        private final TextView chatItemView;
        private final ImageView cornerRightIImageView;
        private final ConstraintLayout constraintLayout;
        private final TextView timeItemView;


        private MeMessageHolder(View itemView) {
            super(itemView);
            chatItemView = itemView.findViewById(R.id.textView);
            cornerRightIImageView = itemView.findViewById(R.id.corner_view_right);
            constraintLayout = itemView.findViewById(R.id.chat_bubble_id);
            timeItemView = itemView.findViewById(R.id.text_message_time);

        }

        void bind(Chat chat, boolean isCorner) {
            chatItemView.setText(chat.getMessage());
            timeItemView.setText(chat.convertedUnixTimeToString("h:mm a"));
            if(isCorner) {
                constraintLayout.setBackgroundResource(R.drawable.chat_bubble_v2);
            } else {
                cornerRightIImageView.setVisibility(View.INVISIBLE);
            }
        }
    }

    class BfMessageHolder extends RecyclerView.ViewHolder {
        private final TextView chatItemView;
        private final ImageView cornerLeftImageView;
        private final ConstraintLayout constraintLayout;
        private final TextView timeItemView;

        private BfMessageHolder(View itemView) {
            super(itemView);
            chatItemView = itemView.findViewById(R.id.textView);
            cornerLeftImageView = itemView.findViewById(R.id.corner_view_left);
            constraintLayout = itemView.findViewById(R.id.chat_bubble_id);
            timeItemView = itemView.findViewById(R.id.text_message_time);
        }

        void bind(Chat chat, boolean isCorner) {
            chatItemView.setText(chat.getMessage());
            timeItemView.setText(chat.convertedUnixTimeToString("h:mm a"));
            if(isCorner) {
                constraintLayout.setBackgroundResource(R.drawable.chat_bubble_v3);
            } else {
                cornerLeftImageView.setVisibility(View.INVISIBLE);
            }
        }
    }

    void setChats(List<Chat> chats) {
        mChats = chats;
        notifyDataSetChanged();
    }

    @Override
    public int getItemCount() {
        if(mChats!=null)
            return mChats.size();
        else return 0;
    }
}

1 голос
/ 17 апреля 2019

Зависит от того, хотите ли вы отображать разные даты для разных элементов обзора переработчика или одну и ту же дату для всех элементов просмотра переработчика.Если вы хотите показать одинаковую дату всем элементам, лучше сделать это за пределами адаптера, а затем передать проанализированную дату адаптеру в режиме просмотра.Или, если вы хотите показать разные даты для каждого элемента, вы должны сделать это внутри onBindViewHolder, поскольку у него есть доступ к позиции элемента.

Помните, что getItemViewType используется для получения типа представления из доступных.Это используется в случае, если вы раздуваете несколько просмотров.Подумайте о chatapp, где view1 будет отображать сообщение слева, а view2 будет отображать сообщение справа;все в одном и том же виде реселлера.

Метод onBindViewHolder просто выполняет общую задачу связывания.Связывает что: элемент завышенного представления и данные.

0 голосов
/ 17 апреля 2019

Просто используйте SimpleDateFormat с yyyy-MM-dd шаблоном.

Примените SimpleDateFormat.format(millis) в onBindViewHolder метод RecyclerView.

0 голосов
/ 17 апреля 2019

Вы должны обновлять изменения пользовательского интерфейса в методе onBindViewHolder. Вы можете вызвать bind метод ViewHolder в onBindViewHolder.

Пример:

public class SampleAdapter extends RecyclerView.Adapter<SampleAdapter.ViewHolder> {

  @NonNull
  @Override
  public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.sample_view, viewGroup, false);
    return new ViewHolder(view);
  }

  @Override
  public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
    viewHolder.bind(i);
  }

  public class ViewHolder extends RecyclerView.ViewHolder {

    public ViewHolder(@NonNull View itemView) {
      super(itemView);
    }

    void bind(int position) {
      // Do your data updates here.
    }
  }
}
0 голосов
/ 17 апреля 2019

Вам нужно преобразовать его в миллисекунды, умножив временную метку на 1000:

java.util.Date dateTime=new java.util.Date((long)timeStamp*1000);

, затем сначала нужно преобразовать метку времени UNIX в формат даты и времени

final long unixTime = 1372339860;
final String formattedDtm = Instant.ofEpochSecond(unixTime)
        .atZone(ZoneId.of("GMT-4"))
        .format(formatter);

System.out.println(formattedDtm);   // => '2013-06-27 09:31:00'

, затем вы хотитесохранить эти данные в значение поля RecyclerView, затем вы можете отформатировать их из этого формата времени, как h:mm

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...