我创建了一个标准的回收器视图适配器,但它有一个奇怪的问题,某些视图将随机更改其可见性或大小,
好的,我随机地说,很明显是我改变了这些视图的大小和/或可见性,所以让我们举一个简单的例子,如果我改变了位置0的可见性,使其消失,因为我的对象没有文本在里面,当适配器被称为位置0时,确实会消失,但是如果我向下滚动,视图变为可见,就会发生类似的事情在我的文本视图中,如果少于10个字符,应该是x大小,否则应该是y大小,第一次加载时大小是正确的,但是向下滚动和向后滚动大小会改变,我知道在幕后视图是加载和回收的(因此命名为回收视图),但是我认为传入onbindViewHolder(final myViewHolder holder,final int position)的位置总是正确的,因为它来自主列表,如果有人能在这里帮我,我会很感激,因为现在我在挠头,我在因为担心没有包含足够的适配器类,所以要发布我的整个适配器类,但通常我认为它的onBindViewHolder是主要的罪魁祸首,它包含了很多主要的任意代码,如前所述,一切工作到一定程度,但我有奇怪的错误,当上下滚动时,随着视图的变化,我相信我正在做的一切我应该是一切显示正确的数据只是不总是正确的大小或可见性,将感谢任何帮助
public class LiveMessageAdapter extends
RecyclerView.Adapter<LiveMessageAdapter.MyViewHolder> {
private static final int VIEW_TYPE_MESSAGE_SENT = 1;
private static final int VIEW_TYPE_MESSAGE_RECEIVED = 2;
private ArrayList<DatabaseMessage> messageList;
private FrameLayout fade;
private ImageView holderImage;
private MessageListActivity.OnItemTouchListener onItemTouchListener;
private Context context;
private String userId;
private Date dateCheck;
private SparseBooleanArray selectedItems;
public class MyViewHolder extends RecyclerView.ViewHolder {
public EmojiTextView message_text;
public TextView time_stamp;
public ImageView holderImage;
public ConstraintLayout holder;
public View sentReceived;
public View fade;
public ProgressBar progressBar;
public ShapeOfView shapeOfView;
public ConstraintLayout dateHolder;
public TextView bigDateText;
public MyViewHolder(View view) {
super(view);
message_text = view.findViewById(R.id.text_message_body);
time_stamp = view.findViewById(R.id.text_message_time);
fade = view.findViewById(R.id.fade);
progressBar = view.findViewById(R.id.progress);
holderImage = view.findViewById(R.id.image_view);
shapeOfView = view.findViewById(R.id.image_view_holder);
holder = view.findViewById(R.id.holder);
sentReceived = view.findViewById(R.id.send_received);
dateHolder = view.findViewById(R.id.date_holder);
bigDateText = view.findViewById(R.id.big_date_text);
Linkify.addLinks(message_text, Linkify.ALL);
holder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemTouchListener.onCardClick(v, getPosition());
}
});
holder.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
onItemTouchListener.onCardLongClick(v, getPosition());
return false;
}
});
}
}
public LiveMessageAdapter(ArrayList<DatabaseMessage> messageList,
Context context,
MessageListActivity.OnItemTouchListener onItemTouchListener,
SparseBooleanArray selectedItems, String userId) {
this.messageList = messageList;
this.onItemTouchListener = onItemTouchListener;
this.context = context;
this.selectedItems = selectedItems;
this.userId = userId;
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView;
if (viewType == VIEW_TYPE_MESSAGE_RECEIVED) {
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.received_message_holder, parent, false);
return new MyViewHolder(itemView);
} else {
itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.sent_message_holder, parent, false);
return new MyViewHolder(itemView);
}
}
@Override
public int getItemViewType(int position) {
DatabaseMessage message = messageList.get(position);
if (message.getSenderId().equals(userId)) {
// If the current user is the sender of the message
return VIEW_TYPE_MESSAGE_SENT;
} else {
// If some other user sent the message
return VIEW_TYPE_MESSAGE_RECEIVED;
}
}
public void toggleSelection(int pos) {
if (selectedItems.get(pos, false)) {
selectedItems.delete(pos);
//view.setBackgroundColor(Color.WHITE);
} else {
selectedItems.put(pos, true);
//view.setBackgroundColor(Color.BLUE);
}
notifyItemChanged(pos);
}
public void clearSelections() {
selectedItems.clear();
notifyDataSetChanged();
}
public int getSelectedItemCount() {
return selectedItems.size();
}
public ArrayList<DatabaseMessage> getSelectedItems() {
ArrayList<DatabaseMessage> items = new ArrayList<>(selectedItems.size());
for (int i = 0; i < selectedItems.size(); i++) {
items.add(messageList.get(selectedItems.keyAt(i)));
}
return items;
}
public void refreshMyList(ArrayList<DatabaseMessage> list) {
this.messageList.clear();
this.messageList.addAll(list);
this.notifyDataSetChanged();
}
public ArrayList<DatabaseMessage> getList() {
return messageList;
}
@Override
public void onBindViewHolder(final MyViewHolder holder, final int position) {
final DatabaseMessage userMessage = messageList.get(position);
if (dateCheck == null){
//first load show date
dateCheck = userMessage.getTime_stamp();
holder.dateHolder.setVisibility(View.VISIBLE);
holder.bigDateText.setText(getTextDateHolder(dateCheck.getTime()));
}else{
//get time and date from message
Calendar messageTime = Calendar.getInstance();
messageTime.setTimeInMillis(userMessage.getTime_stamp().getTime());
// get time and from date check
Calendar dateCheckTime = Calendar.getInstance();
dateCheckTime.setTimeInMillis(dateCheck.getTime());
//check if they are the same
if (dateCheckTime.get(Calendar.DATE) == messageTime.get(Calendar.DATE)
&& ((dateCheckTime.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
&& ((dateCheckTime.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))) {
//make sure this is gone if they are the same
holder.dateHolder.setVisibility(View.GONE);
}else{
//set date holder visible and set the text
holder.dateHolder.setVisibility(View.VISIBLE);
holder.bigDateText.setText(getTextDateHolder(dateCheck.getTime()));
//set date check to most recent checked time
dateCheck = userMessage.getTime_stamp();
}
//check whether to show the message time
if (dateCheckTime.get(Calendar.DATE) == messageTime.get(Calendar.DATE)
&& ((dateCheckTime.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
&& ((dateCheckTime.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))
&& (dateCheckTime.get(Calendar.HOUR) == messageTime.get(Calendar.HOUR))
&& dateCheckTime.get(Calendar.MINUTE) == messageTime.get(Calendar.MINUTE)) {
//make sure this is gone if they are the same
holder.time_stamp.setVisibility(View.GONE);
}else{
//set date holder visible and set the text
holder.time_stamp.setVisibility(View.VISIBLE);
holder.time_stamp.setText(getSmsTodayYestFromMilli(userMessage.getTime_stamp().getTime()));
}
}
holder.message_text.setText(userMessage.getMessage());
if (userMessage.getData_type().equals(Constants.DATA_TYPE_IMAGE)) {
holder.shapeOfView.setVisibility(View.VISIBLE);
Glide.with(context)
.load(userMessage.getData_url())
.apply(new RequestOptions()
.dontAnimate().placeholder(R.drawable.placeholder).centerCrop())
.listener(new RequestListener<Drawable>() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
holder.progressBar.setVisibility(View.INVISIBLE);
return false;
}
})
.into(holder.holderImage);
} else {
holder.shapeOfView.setVisibility(View.GONE);
}
if (userMessage.getMessage().length() < 1) {
holder.message_text.setVisibility(View.GONE);
} else if (userMessage.getMessage().length() >= 1 && userMessage.getMessage().length() < 10) {
holder.message_text.setTextSize(22f);
} else {
holder.message_text.setTextSize(14f);
}
switch (userMessage.getSent_received()) {
case 0:
holder.sentReceived.setBackground(context.getResources().getDrawable(R.drawable.circle_white));
break;
case 1:
holder.sentReceived.setBackground(context.getResources().getDrawable(R.drawable.circle_grey));
break;
case 2:
holder.sentReceived.setBackground(context.getResources().getDrawable(R.drawable.circle_blue));
break;
}
final EmojiInformation emojiInformation = EmojiUtils.emojiInformation(userMessage.getMessage());
final int res;
if (emojiInformation.emojis.size() > 0){
if (emojiInformation.isOnlyEmojis && emojiInformation.emojis.size() == 1) {
res = R.dimen.emoji_size_single_emoji;
} else if (emojiInformation.isOnlyEmojis && emojiInformation.emojis.size() > 1) {
res = R.dimen.emoji_size_only_emojis;
} else {
res = R.dimen.emoji_size_default;
}
holder.message_text.setEmojiSizeRes(res, false);
}
if (selectedItems.get(position, false)) {
holder.fade.setVisibility(View.VISIBLE);
} else {
holder.fade.setVisibility(View.INVISIBLE);
}
}
@Override
public int getItemCount() {
return messageList.size();
}
private String getSmsTodayYestFromMilli(long msgTimeMillis) {
Calendar messageTime = Calendar.getInstance();
messageTime.setTimeInMillis(msgTimeMillis);
// get Currunt time
Calendar now = Calendar.getInstance();
final String strTimeFormate = "h:mm aa";
final String strDateFormate = "dd/MM/yyyy h:mm aa";
if (now.get(Calendar.DATE) == messageTime.get(Calendar.DATE)
&&
((now.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
&&
((now.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))
) {
return DateFormat.format(strTimeFormate, messageTime).toString();
} else if (
((now.get(Calendar.DATE) - messageTime.get(Calendar.DATE)) == 1)
&&
((now.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
&&
((now.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))
) {
return "yesterday at " + DateFormat.format(strTimeFormate, messageTime);
} else {
return "date : " + DateFormat.format(strDateFormate, messageTime);
}
}
private String getTextDateHolder(long msgTimeMillis) {
Calendar messageTime = Calendar.getInstance();
messageTime.setTimeInMillis(msgTimeMillis);
// get Currunt time
Calendar now = Calendar.getInstance();
final String strDateFormate = "dd/MM/yyyy";
if (now.get(Calendar.DATE) == messageTime.get(Calendar.DATE)
&& ((now.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
&& ((now.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))
) {
return "TODAY";
} else if (
((now.get(Calendar.DATE) - messageTime.get(Calendar.DATE)) == 1)
&& ((now.get(Calendar.MONTH) == messageTime.get(Calendar.MONTH)))
&& ((now.get(Calendar.YEAR) == messageTime.get(Calendar.YEAR)))
) {
return "YESTERDAY";
} else {
return "" + DateFormat.format(strDateFormate, messageTime);
}
}
}
两张截图首先是初始加载
上下滚动后的第二秒