private void trySlideAttachmentView(final ViewWrapper viewWrapper) { if (!(viewWrapper.attachment instanceof MediaPickerMessagePartData)) { return; } final View view = viewWrapper.view; final int xOffset = viewWrapper.prevLeft - view.getLeft(); final int yOffset = viewWrapper.prevTop - view.getTop(); final float scaleX = viewWrapper.prevWidth / (float) view.getWidth(); final float scaleY = viewWrapper.prevHeight / (float) view.getHeight(); if (xOffset == 0 && yOffset == 0 && scaleX == 1 && scaleY == 1) { // Layout hasn't changed return; } final AnimationSet animationSet = new AnimationSet(true /* shareInterpolator */); animationSet.addAnimation(new TranslateAnimation(xOffset, 0, yOffset, 0)); animationSet.addAnimation(new ScaleAnimation(scaleX, 1, scaleY, 1)); animationSet.setDuration(UiUtils.MEDIAPICKER_TRANSITION_DURATION); animationSet.setInterpolator(UiUtils.DEFAULT_INTERPOLATOR); view.startAnimation(animationSet); view.invalidate(); viewWrapper.prevLeft = view.getLeft(); viewWrapper.prevTop = view.getTop(); viewWrapper.prevWidth = view.getWidth(); viewWrapper.prevHeight = view.getHeight(); }
@Override protected void onLayout( final boolean changed, final int left, final int top, final int right, final int bottom) { final int cellWidth = getMeasuredWidth() / GRID_WIDTH; final int cellHeight = getMeasuredHeight() / GRID_HEIGHT; final int padding = getResources().getDimensionPixelOffset(R.dimen.multiple_attachment_preview_padding); final int count = mPreviewViews.size(); for (int i = 0; i < count; i++) { final ViewWrapper viewWrapper = mPreviewViews.get(i); final View view = viewWrapper.view; final Tile imageTile = mCurrentLayout.tiles.get(i); final int tileLeft = imageTile.startX * cellWidth; final int tileTop = imageTile.startY * cellHeight; view.layout( tileLeft + padding, tileTop + padding, tileLeft + view.getMeasuredWidth(), tileTop + view.getMeasuredHeight()); if (viewWrapper.needsSlideAnimation) { trySlideAttachmentView(viewWrapper); viewWrapper.needsSlideAnimation = false; } else { viewWrapper.prevLeft = view.getLeft(); viewWrapper.prevTop = view.getTop(); viewWrapper.prevWidth = view.getWidth(); viewWrapper.prevHeight = view.getHeight(); } if (i == count - 1 && mPlusTextView != null) { // The plus text view always covers the last attachment. mPlusTextView.layout( tileLeft + padding, tileTop + padding, tileLeft + mPlusTextView.getMeasuredWidth(), tileTop + mPlusTextView.getMeasuredHeight()); } } }
private void buildViews( final Iterable<MessagePartData> attachments, final ArrayList<ViewWrapper> previousViews, final Rect transitionRect) { final LayoutInflater layoutInflater = LayoutInflater.from(getContext()); final int count = mCurrentLayout.tiles.size(); int i = 0; final Iterator<MessagePartData> iterator = attachments.iterator(); while (iterator.hasNext() && i < count) { final MessagePartData attachment = iterator.next(); ViewWrapper attachmentWrapper = null; // Try to recycle a previous view first for (int j = 0; j < previousViews.size(); j++) { final ViewWrapper previousView = previousViews.get(j); if (previousView.attachment.equals(attachment) && !(previousView.attachment instanceof PendingAttachmentData)) { attachmentWrapper = previousView; previousViews.remove(j); break; } } if (attachmentWrapper == null) { final View view = AttachmentPreviewFactory.createAttachmentPreview( layoutInflater, attachment, this, AttachmentPreviewFactory.TYPE_MULTIPLE, false /* startImageRequest */, mAttachmentClickListener); if (view == null) { // createAttachmentPreview can return null if something goes wrong (e.g. // attachment has unsupported contentType) continue; } if (view instanceof AsyncImageView && mImageViewDelayLoader != null) { AsyncImageView asyncImageView = (AsyncImageView) view; asyncImageView.setDelayLoader(mImageViewDelayLoader); } addView(view); attachmentWrapper = new ViewWrapper(view, attachment); // Help animate from single to multi by copying over the prev location if (count == 2 && i == 1 && transitionRect != null) { attachmentWrapper.prevLeft = transitionRect.left; attachmentWrapper.prevTop = transitionRect.top; attachmentWrapper.prevWidth = transitionRect.width(); attachmentWrapper.prevHeight = transitionRect.height(); } } i++; Assert.notNull(attachmentWrapper); mPreviewViews.add(attachmentWrapper); // The first view will animate in using PopupTransitionAnimation, but the remaining // views will slide from their previous position to their new position within the // layout if (i == 0) { AttachmentPreview.tryAnimateViewIn(attachment, attachmentWrapper.view); } attachmentWrapper.needsSlideAnimation = i > 0; } // Build the plus text view (e.g. "+2") for when there are more attachments than what // this layout can display. if (mPlusNumber > 0) { mPlusTextView = (TextView) layoutInflater.inflate(R.layout.attachment_more_text_view, null /* parent */); mPlusTextView.setText(getResources().getString(R.string.attachment_more_items, mPlusNumber)); addView(mPlusTextView); } }