具有已排序领域结果的领域适配器行为不正确

时间:2017-06-25 19:06:51

标签: android android-recyclerview realm recycler-adapter realm-list

我最近遇到了一个问题。问题是当使用排序的RealmResults作为RealmRecyclerViewAdapter的源时, 如果添加了2个以上的项目,则添加的第一个项目会覆盖部分先前(中间项目)。  我知道这听起来很模糊,我很困惑,试图理解它好几天,但还没有找到解决方案,甚至没有解释。

初始化代码

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ...
        mAttachmentDataSource = realm.where(Attachment.class).equalTo("parentId", presenter.getId()).findAllSorted("order", Sort.DESCENDING);
        mAttachmentAdapter = new AttachmentAdapter(getActivity(), mAttachmentDataSource);
        mAttachmentListManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.HORIZONTAL, false);
        mAttachmentListView.setLayoutManager(mAttachmentListManager);
        mAttachmentListView.setAdapter(mAttachmentAdapter);
    ...
}

适配器代码:

public class AttachmentAdapter extends RealmRecyclerViewAdapter<Attachment, AttachmentAdapter.ViewHolder> {
    private Context mContext;
    public boolean mReadOnly;
    private int limit;

    public void setLimit(int limit) {
        this.limit = limit;
    }

    public AttachmentAdapter(Context context, @NonNull OrderedRealmCollection<Attachment> attachments) {
        super(attachments, true);
        initialize(context, false);
    }

    public AttachmentAdapter(Context context, @NonNull OrderedRealmCollection<Attachment> attachments, boolean readonly) {
        super(attachments, true);
        initialize(context, readonly);
    }

    private void initialize(Context context, boolean readonly) {
        setHasStableIds(true);
        mContext = context;
        mReadOnly = readonly;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context context = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        // Inflate the custom layout
        View contactView = inflater.inflate(R.layout.item_attachment, parent, false);

        // Return a new holder instance
        return new ViewHolder(contactView);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        if (getData() == null) return;
        holder.mThumbFileIconImageView.setVisibility(View.GONE);
        if (position == 0 && !mReadOnly) {
            holder.mRemoveIconView.setVisibility(View.GONE);

            holder.mThumbnailView.setBackground(ActivityCompat.getDrawable(mContext,
                    R.drawable.dashed_accented_no_border));

            RxUtils.clicks(holder.mThumbnailView)
                    .subscribe(v -> openAttachmentSelection());

            holder.itemView.setVisibility(limit == getItemCount() - 1 ? View.GONE : View.VISIBLE);
        } else {
            Attachment model = getData().get(position);
            long id = model.getId();
            holder.initialize(id, model.getParentId());
            holder.mRemoveIconView.setVisibility(mReadOnly ? View.GONE : View.VISIBLE);
            holder.mRemoveIconView.setTag(id);
            MediaType mediaType = MediaType.parse(model.getMimeType());
            String path = model.getAbsoluteFilePath();
            if (mediaType != null && mediaType.is(MediaType.ANY_IMAGE_TYPE)) {
                if (path != null) {
                    Glide.with(mContext)
                            .fromString()
                            .load(path)
                            .listener(new RequestListener<String, GlideDrawable>() {
                                @Override
                                public boolean onException(Exception e, String s, Target<GlideDrawable> target, boolean b) {
                                    holder.mProgressBar.setVisibility(View.GONE);
                                    return false;
                                }

                                @Override
                                public boolean onResourceReady(GlideDrawable glideDrawable, String s, Target<GlideDrawable> target, boolean b, boolean b1) {
                                    holder.mProgressBar.setVisibility(View.VISIBLE);
                                    return false;
                                }
                            })
                            .centerCrop()
                            .crossFade()
                            .thumbnail(0.1f)
                            .into(holder.mThumbnailView);
                } else if (model.data != null) {
                    Glide.with(mContext)
                            .fromBytes()
                            .load(model.data)
                            .listener(new RequestListener<byte[], GlideDrawable>() {
                                @Override
                                public boolean onException(Exception e, byte[] bytes, Target<GlideDrawable> target, boolean b) {
                                    holder.mProgressBar.setVisibility(View.GONE);
                                    return false;
                                }

                                @Override
                                public boolean onResourceReady(GlideDrawable glideDrawable, byte[] bytes, Target<GlideDrawable> target, boolean b, boolean b1) {
                                    holder.mProgressBar.setVisibility(View.VISIBLE);
                                    return false;
                                }
                            })
                            .centerCrop()
                            .crossFade()
                            .thumbnail(0.1f)
                            .into(holder.mThumbnailView);
                }
            } else {
                int icon = AttachmentUtils.getAttachmentIcon(mediaType);
                holder.mThumbFileIconImageView.setVisibility(View.VISIBLE);
                holder.mThumbFileIconImageView.setImageResource(icon);
            }

            holder.mOverlayView.setVisibility(View.INVISIBLE);
            holder.mThumbnailView.setOnClickListener(e -> holder.openGallery(mContext));
            holder.mRemoveIconView.setOnClickListener(e -> holder.remove());
        }
    }

    @Override
    public int getItemCount() {
        return getData().size();
    }

    public void openAttachmentSelection() {
        new MaterialDialog.Builder(mContext)
                .title(mContext.getText(R.string.selectAttachment))
                .backgroundColorRes(R.color.white)
                .contentColorRes(R.color.black)
                .titleColorRes(R.color.black)
                .items(R.array.select_attachment_types)
                .itemsCallbackSingleChoice(-1, (dialog, view, which, text) -> {
                    switch (which) {
                        case 0:
                            CameraUtils.returnPicture((AppCompatActivity) mContext);
                            break;
                        case 1:
                            getAttachmentImageFile();
                            break;
                        case 2:
                            getAttachmentFile();
                            break;
                    }

                    return true;
                })
                .show();
    }

    private void getAttachmentImageFile() {
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.MEDIA_CONTENT_CONTROL) == PackageManager.PERMISSION_GRANTED) {

            Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI);
            intent.setType("image/*");
            intent.putExtra("return-data", true);
            ((AppCompatActivity) mContext).startActivityForResult(intent, RequestCodes.REQUEST_IMAGE_SELECT);

            return;
        }

        ActivityCompat.requestPermissions(((AppCompatActivity) mContext),
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                RequestCodes.REQUEST_PERMISSION_IMAGE
        );
    }

    private void getAttachmentFile() {
        // Create the ACTION_GET_CONTENT Intent
        Intent getContentIntent = FileUtils.createGetContentIntent();
        Intent intent = Intent.createChooser(getContentIntent, mContext.getString(R.string.attachment_list_select_file));
        ((AppCompatActivity) mContext).startActivityForResult(intent, RequestCodes.RESULT_FILE_SELECTED);
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        private AttachmentPresenter presenter;
        @BindView(R.id.item_attachment_thumbnail_overlay)
        AppCompatImageView mOverlayView;
        @BindView(R.id.item_attachment_thumbnail_layout)
        FrameLayout mFrameLayout;
        @BindView(R.id.item_attachment_thumbnail)
        AppCompatImageView mThumbnailView;
        @BindView(R.id.item_attachment_close_button)
        AppCompatImageView mRemoveIconView;
        @BindView(R.id.item_attachment_thumbnail_file_icon)
        AppCompatImageView mThumbFileIconImageView;
        @BindView(R.id.item_attachment_progress_bar)
        ProgressBar mProgressBar;

        public ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }

        public void initialize(long id, long parentId) {
            if(this.presenter == null) this.presenter = new AttachmentPresenter();
            this.presenter.initialize(id, parentId);
        }

        public void openGallery(Context mContext) {
            AppCompatActivity activity = ((AppCompatActivity) mContext);
            Attachment attachment = this.presenter.getAttachment();
            ;

            if (attachment == null || activity == null) return;

            FragmentTransaction fragmentTransaction = activity.getSupportFragmentManager().beginTransaction();
            Fragment fragment = activity.getSupportFragmentManager().findFragmentByTag(AttachmentDialogFragment.FRAGMENT_TAG);

            if (fragment != null) {
                fragmentTransaction.remove(fragment);
            }

            fragmentTransaction.addToBackStack(null);

            // Create and show the dialog.
            AttachmentDialogFragment newFragment = AttachmentDialogFragment.newInstance(
                    attachment.getParentId(),
                    attachment.getId()
            );

            newFragment.show(fragmentTransaction, AttachmentDialogFragment.FRAGMENT_TAG);
        }

        public void remove() {
            this.presenter.remove();
            this.presenter.unbind();
            this.presenter = null;
        }
    }
}

如何添加附件:

@Override
public void addAttachment(Bitmap image) {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    File file = ImageUtils.saveToFile(image, "attachment_" + mId + "_" + timeStamp, context);
    Realm realm =  Realm.getDefaultInstance();
    String mimeType = FileUtils.getMimeType(file);

    realm.executeTransactionAsync(t -> {
        long id = getId();
        Attachment attachment = Attachment.create(t, Opportunity.class, id);
        attachment.setAbsoluteFilePath(file.getAbsolutePath());
        attachment.setMimeType(mimeType);
        t.copyToRealmOrUpdate(attachment);
    });

    realm.close();
}

@Override
public void addAttachment(Uri uri) {
    File file;
    String absolutePath = null;
    String mimeType = FileUtils.getMimeType(context, uri);
    String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);

    try {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        file = File.createTempFile(
                "attachment_" + mId + "_" + timeStamp ,  /* prefix */
                "." + extension,         /* suffix */
                context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)      /* directory */
        );
        File tempFile = new File(ImageUtils.getPath(uri, context));
        GeneralUtils.copy(tempFile, file);
        absolutePath = file.getAbsolutePath();
    } catch (IOException e) {
        e.printStackTrace();
    }

    Realm realm =  Realm.getDefaultInstance();
    final String path = absolutePath;
    realm.executeTransactionAsync(t -> {
        long id = getId();
        Attachment attachment = Attachment.create(t, Opportunity.class, id);
        attachment.setAbsoluteFilePath(path);
        attachment.setMimeType(mimeType);
        t.copyToRealmOrUpdate(attachment);
        for (Attachment a:t.where(Opportunity.class).findFirst().getAttachments()
             ) {
            a.setCreatedAt(new Date());
        }
    });

    realm.close();
}

我遇到的奇怪行为是:

将一张可爱的猫咪图片作为附件添加后:

enter image description here

添加另一个后(注意第一个被推到右边,添加的一个是按钮之前):

enter image description here

添加另一张图片后,第一张图片替换了前一张图片

enter image description here

起初我以为它的回收不正确,但无法确定究竟发生了什么。 奇怪的是 - 如果我根本不使用排序而只使用 .findAll()而不是 .findAllSorted(“order”,Sort.DESCENDING)一切正常,但添加的图像不会放在别人面前(这是我的目标)。

0 个答案:

没有答案