我的日期时间当前存储为UNIX时间戳。我想在Recyclerview中将其显示为h:mm a。
在RecyclerView Adapter / Viewholder中,我应该在哪里将UNIX时间戳转换为正常时间(就最佳性能而言)?
我应该在getItemViewType(int position)
的{{1}}还是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;
}
}
方法
答案 0 :(得分:1)
这取决于您是要在recyclerview的不同项目上显示不同的日期,还是要在recyclerview的所有项目上显示相同的日期。 如果要对所有项目显示相同的日期,最好在适配器之外进行,然后将解析的日期传递给recyclerview适配器。 或者,如果要在每个项目上显示不同的日期,则应在onBindViewHolder中执行此操作,因为它可以访问项目位置。
请记住,getItemViewType用于从可用视图类型中获取视图类型。如果要放大多个视图,则使用此方法。考虑一个chatapp,其中view1将在左侧显示消息,而view2将在右侧显示消息;都在同一个回收站视图中。
onBindViewHolder方法仅执行通用绑定任务。绑定what:膨胀视图的项目和数据。
答案 1 :(得分:1)
似乎是业务逻辑。因此,例如,我建议您在Model中将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;
}
}
答案 2 :(得分:0)
您需要通过将时间戳乘以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
答案 3 :(得分:0)
您应该使用onBindViewHolder
方法更新UI更改。您可以在bind
中调用ViewHolder
的{{1}}方法。
示例:
onBindViewHolder
答案 4 :(得分:0)
只需将SimpleDateFormat
与yyyy-MM-dd
模式一起使用。
在SimpleDateFormat.format(millis)
的{{1}}方法中应用onBindViewHolder