recyclerview项在tile上显示错误信息

iibxawm4  于 2021-06-26  发布在  Java
关注(0)|答案(0)|浏览(263)

我有一个 RecyclerView 具有动态的瓷砖数量。数据从服务器加载并显示在这些磁贴中。滑动用于将图像加载到这些瓦片上的化身中。问题是,每当我刷新列表或向其中添加更多项目时,它有时会为磁贴加载错误的图像。
例如,磁贴1上的一个用户将具有空白的化身,下一磁贴上的相同用户将具有不同的化身(另一用户的)。如果我刷新列表,它可能会变得正确,甚至更混乱(某个用户的第三个随机化身出现)。


我在工作中做错了什么 Adapter ? 下面是共享代码。

public class BookingAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
{
    private final Context context;
    private final Util util;
    private final List<Booking> bookings;

    private static final int TYPE_BOOKING = 0;
    private static final int TYPE_LOADING = 1;
    private OnLoadMoreListener loadMoreListener;
    private boolean isMoreDataAvailable = true, isLoading = false;

    public BookingAdapter(Context context, List<Booking> bookings)
    {
        this.context = context;
        this.bookings = bookings;
        util = new Util();
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType)
    {
        if(viewType == TYPE_BOOKING)
        {
            return new BookingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_booking, parent, false));
        }
        else
        {
            return new LoadingViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.listitem_load, parent, false));
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position)
    {
        if (position >= getItemCount() - 1 && isMoreDataAvailable && !isLoading && loadMoreListener != null)
        {
            isLoading = true;
            loadMoreListener.onLoadMore();
        }

        if (getItemViewType(position) == TYPE_BOOKING)
        {
            ((BookingViewHolder) holder).bindData(bookings.get(position));
        }
    }

    @Override
    public long getItemId(int position)
    {
        return position;
    }

    @Override
    public int getItemViewType(int position)
    {
        if (bookings.get(position).getCreatedAt().equalsIgnoreCase("loading"))
        {
            return TYPE_LOADING;
        }
        else
        {
            return TYPE_BOOKING;
        }
    }

    @Override
    public int getItemCount()
    {
        return bookings != null ? bookings.size() : 0;
    }

    public class BookingViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener
    {
        private final CircularImageView avatar;
        private final ImageView paymentStatusIcon;
        private final TextView name;
        private final TextView charges;
        private final TextView timeSlot;
        private final TextView status;
        private final TextView cancel;
        private final TextView dayOfWeek;
        private final TextView dayOfMonth;
        private final TextView month;

        private Booking currentBooking = null;
        private Appointment activeAppointment = null;

        public BookingViewHolder(@NonNull View itemView)
        {
            super(itemView);

            avatar = itemView.findViewById(R.id.avatar);
            paymentStatusIcon = itemView.findViewById(R.id.paymentStatusIcon);
            name = itemView.findViewById(R.id.name);
            charges = itemView.findViewById(R.id.charges);
            timeSlot = itemView.findViewById(R.id.timeslot);
            status = itemView.findViewById(R.id.type);
            cancel = itemView.findViewById(R.id.cancel);
            dayOfWeek = itemView.findViewById(R.id.dayOfWeek);
            dayOfMonth = itemView.findViewById(R.id.dayOfMonth);
            month = itemView.findViewById(R.id.month);

            cancel.setOnClickListener(this);
            itemView.setOnClickListener(this);
        }

        void bindData(Booking booking)
        {
            this.currentBooking = booking;
            String statusBooking = currentBooking.getStatus();

            switch (statusBooking)
            {
                case Constants.JOB_STATUS_VISIT_PENDING:
                case Constants.JOB_STATUS_CANCELLED:
                case Constants.JOB_STATUS_OFFER_PENDING:
                case Constants.JOB_STATUS_PENDING_CLIENT_APPROVAL:
                    this.activeAppointment = booking.getVisitAppointment();
                    break;

                case Constants.JOB_STATUS_SCHEDULED:
                case Constants.JOB_STATUS_IN_PROGRESS:
                case Constants.JOB_STATUS_COMPLETED:
                    this.activeAppointment = booking.getServiceAppointment();
                    break;

                default:
                    this.activeAppointment = new Appointment();
                    break;
            }

            if(activeAppointment.getAppointmentType().equalsIgnoreCase(Constants.APPOINTMENT_TYPE_SERVICE) && activeAppointment.getStatus().equalsIgnoreCase(Constants.JOB_STATUS_COMPLETED))
            {
                paymentStatusIcon.setVisibility(View.VISIBLE);

                if(activeAppointment.getPaymentStatus().equalsIgnoreCase(Constants.PAYMENT_STATUS_PAID))
                {
                    paymentStatusIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.vector_cash_check));
                }
                else if(activeAppointment.getPaymentStatus().equalsIgnoreCase(Constants.PAYMENT_STATUS_DECLINED))
                {
                    paymentStatusIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.vector_cash_remove));
                }
                else
                {
                    paymentStatusIcon.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.vector_cash));
                    paymentStatusIcon.setImageTintList(ColorStateList.valueOf(ContextCompat.getColor(context, R.color.quantum_amber800)));
                }
            }
            else
            {
                paymentStatusIcon.setVisibility(View.GONE);
            }

            if (statusBooking.equalsIgnoreCase(Constants.JOB_STATUS_UNASSIGNED) || statusBooking.equalsIgnoreCase(Constants.JOB_STATUS_PENDING))
            {
                avatar.setBackground(ContextCompat.getDrawable(context, R.drawable.vector_portrait_placeholder));
                name.setText(context.getString(R.string.not_assigned_yet));
                status.setText(booking.getStatus());
                timeSlot.setVisibility(View.GONE);

                String[] bookingDateSplit = booking.getVisitDate().split("-");
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.YEAR, Integer.parseInt(bookingDateSplit[0]));
                calendar.set(Calendar.MONTH, (Integer.parseInt(bookingDateSplit[1]) - 1));
                calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(bookingDateSplit[2]));

                dayOfWeek.setText(util.getDayNameFromInt(calendar.get(Calendar.DAY_OF_WEEK)));
                dayOfMonth.setText(bookingDateSplit[2]);
                month.setText(util.getMonthShortNameFromInt(calendar.get(Calendar.MONTH)));
            }
            else
            {
                User consumer = booking.getConsumer();

                if (consumer.getAvatar() != null && consumer.getAvatar().length() > 0)
                {
                    Glide.with(context).load(consumer.getAvatar()).circleCrop().placeholder(R.drawable.vector_portrait_placeholder).into(avatar);
                } else
                {
                    avatar.setBackground(util.getTextDrawable(context, consumer.getFirstName()));
                }

                name.setText(String.format(Locale.getDefault(), "%d - %s %s", booking.getOrderId(), consumer.getFirstName(), consumer.getLastName()));
                status.setText(booking.getStatus());
                charges.setText(activeAppointment.getAppointmentType().equalsIgnoreCase(Constants.APPOINTMENT_TYPE_VISIT) ? booking.getVisitCharges() : booking.getBaseRate());
                timeSlot.setText(activeAppointment.getSlotTitle());

                String[] appointmentDateSplit = activeAppointment.getDate().split("-");
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.YEAR, Integer.parseInt(appointmentDateSplit[0]));
                calendar.set(Calendar.MONTH, (Integer.parseInt(appointmentDateSplit[1]) - 1));
                calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(appointmentDateSplit[2]));
                dayOfWeek.setText(util.getDayNameFromInt(calendar.get(Calendar.DAY_OF_WEEK)));
                dayOfMonth.setText(appointmentDateSplit[2]);
                month.setText(util.getMonthShortNameFromInt(calendar.get(Calendar.MONTH)));
            }

            if(booking.getStatus().equalsIgnoreCase(Constants.JOB_STATUS_SCHEDULED)
                    || booking.getStatus().equalsIgnoreCase(Constants.JOB_STATUS_IN_PROGRESS)
                    || booking.getStatus().equalsIgnoreCase(Constants.JOB_STATUS_COMPLETED)
                    || booking.getStatus().equalsIgnoreCase(Constants.JOB_STATUS_CANCELLED))
            {
                cancel.setVisibility(View.GONE);
            }
            else
            {
                cancel.setVisibility(View.VISIBLE);
            }
        }

        @Override
        public void onClick(View view)
        {
            Booking clickedBooking = bookings.get(getAdapterPosition());

            if (view.getId() == R.id.cancel)
            {
                new MaterialDialog.Builder(context)
                        .title(R.string.cancel_booking)
                        .content(R.string.are_you_sure_cancel_booking)
                        .positiveText(R.string.cancel_booking)
                        .positiveColor(ContextCompat.getColor(context, R.color.quantum_googred500))
                        .onPositive((dialog, which) -> cancelOrder(util.getToken(context), clickedBooking.getOrderId(), getAdapterPosition()))
                        .negativeText(R.string.dismiss)
                        .show();
            } else
            {
                if (bookings.get(getAdapterPosition()).getStatus().equalsIgnoreCase(Constants.JOB_STATUS_UNASSIGNED) || bookings.get(getAdapterPosition()).getStatus().equalsIgnoreCase(Constants.JOB_STATUS_PENDING))
                {
                    Toasty.info(context, R.string.no_booking_details_yet).show();
                } else
                {
                    context.startActivity(new Intent(context, BookingDetailsActivity.class)
                            .putExtra(Constants.ATTACHED_BOOKING, bookings.get(getAdapterPosition())));
                }
            }
        }
    }

    public class LoadingViewHolder extends RecyclerView.ViewHolder
    {
        LoadingViewHolder(View itemView)
        {
            super(itemView);
        }
    }

    public void setMoreDataAvailable(boolean moreDataAvailable)
    {
        isMoreDataAvailable = moreDataAvailable;
    }

    /* notifyDataSetChanged is a final method so we can't override it
       call adapter.notifyDataChanged() after updating the list */

    public void notifyDataChanged()
    {
        notifyDataSetChanged();
        isLoading = false;
    }

    public interface OnLoadMoreListener
    {
        void onLoadMore();
    }

    public void setLoadMoreListener(OnLoadMoreListener loadMoreListener)
    {
        this.loadMoreListener = loadMoreListener;
    }

    private void cancelOrder(String authorization, long bookingId, int position)
    {
        APIClient.getClient().cancelOrder(authorization, FSSApplication.companyToken, new RequestCancelOrder(bookingId)).enqueue(new Callback<ResponseGenericString>()
        {
            @Override
            public void onResponse(Call<ResponseGenericString> call, Response<ResponseGenericString> response)
            {
                if (response.isSuccessful())
                {
                    if (response.body().getStatus())
                    {
                        Toasty.success(context, response.body().getMessage()).show();
                        bookings.remove(position);
                        notifyDataChanged();
                    } else
                    {
                        Toasty.error(context, response.body().getMessage()).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<ResponseGenericString> call, Throwable t)
            {
                Toasty.error(context, t.getMessage()).show();
            }
        });
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题