我有一个recyclelerview,onClick展开项目以显示描述。
它可以正常展开和折叠,但是当我使用展开的项目滚动时,展开的一些新项目会被展开......
例如,我有一个包含50个项目的回收者视图。我扩展了第一个项目和向下滚动,每个项目都有一个扩展项目。
public class NotificationsExpandAdapter extends RecyclerView.Adapter<NotificationsExpandAdapter.NotificationsViewHolder> {
private ListItemClickListener mOnClickListener;
private ArrayList<SchoolNotification> mNotifications;
private HashMap<String, String> typeNotifications;
public interface ListItemClickListener {
void onListItemClick(SchoolNotification notification);
}
public NotificationsExpandAdapter(ArrayList<SchoolNotification> notifications, Resources resources) {
mNotifications = notifications;
typeNotifications = eventsType(resources);
}
public NotificationsExpandAdapter(ArrayList<SchoolNotification> notifications, Resources resources, ListItemClickListener listener) {
mNotifications = notifications;
mOnClickListener = listener;
typeNotifications = eventsType(resources);
}
@Override
public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.notification_list_item_expand;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
NotificationsViewHolder viewHolder = new NotificationsViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
holder.mNotificationDate.setText(formatDateDayMonth(mNotifications.get(position).getDate()));
holder.mNotificationType.setText(typeNotifications.get(mNotifications.get(position).getType()));
holder.mNotificationTitle.setText(mNotifications.get(position).getTitle());
holder.mNotificationDescription.setText(mNotifications.get(position).getDescription());
if (mNotifications.get(position).getSubject().getName() != null) {
holder.mNotificationSubject.setText(mNotifications.get(position).getSubject().getName());
}
}
public SchoolNotification getItem(Integer position){
return mNotifications.get(position);
}
@Override
public int getItemCount() {
return mNotifications.size();
}
class NotificationsViewHolder extends RecyclerView.ViewHolder
implements OnClickListener {
TextView listItemNumberView;
TextView mNotificationDate;
TextView mNotificationType;
TextView mNotificationSubject;
TextView mNotificationTitle;
TextView mNotificationDescription;
public NotificationsViewHolder(View itemView) {
super(itemView);
mNotificationDate = (TextView) itemView.findViewById(R.id.tv_notif_date);
mNotificationType = (TextView) itemView.findViewById(R.id.tv_notif_type);
mNotificationSubject = (TextView) itemView.findViewById(R.id.tv_notif_subject);
mNotificationTitle = (TextView) itemView.findViewById(R.id.tv_notif_tittle);
mNotificationDescription = (TextView) itemView.findViewById(R.id.tv_notif_description);
mNotificationDescription.setVisibility(View.GONE);
itemView.setOnClickListener(this);
}
void bind(int listIndex) {
listItemNumberView.setText(String.valueOf(listIndex));
}
@Override
public void onClick(View v) {
if(mNotificationDescription.isShown()){
Utils.slide_up(v.getContext(), mNotificationDescription);
mNotificationDescription.setVisibility(View.GONE);
}
else{
mNotificationDescription.setVisibility(View.VISIBLE);
Utils.slide_down(v.getContext(), mNotificationDescription);
}
// mNotificationDescription.setVisibility(mNotificationDescription.isShown() ? View.GONE : View.VISIBLE);
// if (mOnClickListener != null){
// int clickedPosition = getAdapterPosition();
// mOnClickListener.onListItemClick(mNotifications.get(clickedPosition));
// }
}
}
}
答案 0 :(得分:1)
ViewHolders被重用以提高列表的性能,因此他们会记住它们的状态。这就是为什么有些项目会展开的原因:他们重复使用ViewHolders,它们之前已经扩展过了。为了避免这个问题,你以某种方式记住哪些项目被扩展(例如,保存它们在ArrayList中的位置)并执行onBindViewHolder检查:如果项目被扩展(这样的位置存在于ArryaList中) - 展开它如果它没有 - 崩溃它。
答案 1 :(得分:0)
解。
在适配器类中添加了一个hashmap,在holder类中添加了id
public class NotificationsExpandAdapter extends RecyclerView.Adapter<NotificationsExpandAdapter.NotificationsViewHolder> {
private ListItemClickListener mOnClickListener;
private ArrayList<SchoolNotification> mNotifications;
private HashMap<String, String> typeNotifications;
private HashMap<Long, Boolean> expandedNotifications = new HashMap<>();
public interface ListItemClickListener {
void onListItemClick(SchoolNotification notification);
}
public NotificationsExpandAdapter(ArrayList<SchoolNotification> notifications, Resources resources) {
mNotifications = notifications;
typeNotifications = eventsType(resources);
}
public NotificationsExpandAdapter(ArrayList<SchoolNotification> notifications, Resources resources, ListItemClickListener listener) {
mNotifications = notifications;
mOnClickListener = listener;
typeNotifications = eventsType(resources);
}
@Override
public NotificationsViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
Context context = viewGroup.getContext();
int layoutIdForListItem = R.layout.notification_list_item_expand;
LayoutInflater inflater = LayoutInflater.from(context);
boolean shouldAttachToParentImmediately = false;
View view = inflater.inflate(layoutIdForListItem, viewGroup, shouldAttachToParentImmediately);
NotificationsViewHolder viewHolder = new NotificationsViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(NotificationsViewHolder holder, int position) {
holder.id = mNotifications.get(position).getId();
holder.mNotificationDate.setText(formatDateDayMonth(mNotifications.get(position).getDate()));
holder.mNotificationType.setText(typeNotifications.get(mNotifications.get(position).getType()));
holder.mNotificationTitle.setText(mNotifications.get(position).getTitle());
holder.mNotificationDescription.setText(mNotifications.get(position).getDescription());
if (mNotifications.get(position).getSubject().getName() != null) {
holder.mNotificationSubject.setText(mNotifications.get(position).getSubject().getName());
}
if (expandedNotifications.containsKey(holder.id))
holder.mNotificationDescription.setVisibility(View.VISIBLE);
else
holder.mNotificationDescription.setVisibility(View.GONE);
}
public SchoolNotification getItem(Integer position){
return mNotifications.get(position);
}
@Override
public int getItemCount() {
return mNotifications.size();
}
class NotificationsViewHolder extends RecyclerView.ViewHolder
implements OnClickListener {
TextView listItemNumberView;
TextView mNotificationDate;
TextView mNotificationType;
TextView mNotificationSubject;
TextView mNotificationTitle;
TextView mNotificationDescription;
Long id;
public NotificationsViewHolder(View itemView) {
super(itemView);
mNotificationDate = (TextView) itemView.findViewById(R.id.tv_notif_date);
mNotificationType = (TextView) itemView.findViewById(R.id.tv_notif_type);
mNotificationSubject = (TextView) itemView.findViewById(R.id.tv_notif_subject);
mNotificationTitle = (TextView) itemView.findViewById(R.id.tv_notif_tittle);
mNotificationDescription = (TextView) itemView.findViewById(R.id.tv_notif_description);
mNotificationDescription.setVisibility(View.GONE);
itemView.setOnClickListener(this);
}
void bind(int listIndex) {
listItemNumberView.setText(String.valueOf(listIndex));
}
@Override
public void onClick(View v) {
if(mNotificationDescription.isShown()){
Utils.slide_up(v.getContext(), mNotificationDescription);
mNotificationDescription.setVisibility(View.GONE);
expandedNotifications.remove(id);
}
else{
mNotificationDescription.setVisibility(View.VISIBLE);
Utils.slide_down(v.getContext(), mNotificationDescription);
expandedNotifications.put(id, true);
}
}
}
}