1f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein/* 2f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * Copyright (C) 2011 The Android Open Source Project 3f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * 4f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * Licensed under the Apache License, Version 2.0 (the "License"); 5f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * you may not use this file except in compliance with the License. 6f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * You may obtain a copy of the License at 7f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * 8f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * http://www.apache.org/licenses/LICENSE-2.0 9f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * 10f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * Unless required by applicable law or agreed to in writing, software 11f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * distributed under the License is distributed on an "AS IS" BASIS, 12f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * See the License for the specific language governing permissions and 14f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein * limitations under the License. 15f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein */ 16f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 17237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sappersteinpackage com.android.mail.ui; 18f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 198081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrookimport android.app.FragmentManager; 20f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.content.Context; 21e1557036849265afc24528be9effbe299b640bffAndrew Sappersteinimport android.content.res.Resources; 2262066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport android.graphics.Bitmap; 23e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sappersteinimport android.util.AttributeSet; 24f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.view.LayoutInflater; 25f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.view.View; 26f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport android.widget.FrameLayout; 27f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 28e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sappersteinimport com.android.mail.R; 294f347e811052f446c3958c76db278bcd7b39a44fAndy Huangimport com.android.mail.browse.ConversationMessage; 30237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sappersteinimport com.android.mail.browse.MessageAttachmentTile; 31237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sappersteinimport com.android.mail.compose.ComposeAttachmentTile; 324f347e811052f446c3958c76db278bcd7b39a44fAndy Huangimport com.android.mail.photo.MailPhotoViewActivity; 334f347e811052f446c3958c76db278bcd7b39a44fAndy Huangimport com.android.mail.providers.Account; 34f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport com.android.mail.providers.Attachment; 3562066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.android.mail.ui.AttachmentTile.AttachmentPreview; 3662066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.android.mail.ui.AttachmentTile.AttachmentPreviewCache; 37db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sappersteinimport com.android.mail.utils.ViewUtils; 3862066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.google.common.collect.Lists; 3962066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport com.google.common.collect.Maps; 4062066e47fe69c33b60ed970e46809ba81d044064Mark Wei 4162066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport java.util.ArrayList; 4262066e47fe69c33b60ed970e46809ba81d044064Mark Weiimport java.util.HashMap; 43f986850eb04ff614feb915e178227c4f53ca695bAndrew Sappersteinimport java.util.List; 44f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 45f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein/** 46237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein * Acts as a grid composed of {@link AttachmentTile}s. 47f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein */ 484f347e811052f446c3958c76db278bcd7b39a44fAndy Huangpublic class AttachmentTileGrid extends FrameLayout implements AttachmentPreviewCache, 494f347e811052f446c3958c76db278bcd7b39a44fAndy Huang MessageAttachmentTile.PhotoViewHandler { 5069c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei private final LayoutInflater mInflater; 51e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein private final int mTileMinSize; 52e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein private final int mTilePadding; 53e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein private int mColumnCount; 544cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein private List<Attachment> mAttachments; 5569c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei private final HashMap<String, AttachmentPreview> mAttachmentPreviews; 568081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook private FragmentManager mFragmentManager; 574f347e811052f446c3958c76db278bcd7b39a44fAndy Huang private Account mAccount; 58833123d9c31b0b2dd23f7f74738c5bccf8a546d3Andrew Sapperstein private ConversationMessage mMessage; 59f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 60e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein public AttachmentTileGrid(Context context, AttributeSet attrs) { 61e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein super(context, attrs); 62f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein mInflater = LayoutInflater.from(context); 63e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein final Resources res = context.getResources(); 64e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein mTileMinSize = res.getDimensionPixelSize(R.dimen.attachment_tile_min_size); 65e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein mTilePadding = res.getDimensionPixelSize(R.dimen.attachment_tile_padding); 6662066e47fe69c33b60ed970e46809ba81d044064Mark Wei mAttachmentPreviews = Maps.newHashMap(); 67f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 68f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 69f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein /** 70e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein * Configures the grid to add {@link Attachment}s information to the views. 71f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein */ 724f347e811052f446c3958c76db278bcd7b39a44fAndy Huang public void configureGrid(FragmentManager fragmentManager, Account account, 734f347e811052f446c3958c76db278bcd7b39a44fAndy Huang ConversationMessage message, List<Attachment> list, boolean loaderResult) { 744f347e811052f446c3958c76db278bcd7b39a44fAndy Huang 758081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook mFragmentManager = fragmentManager; 764f347e811052f446c3958c76db278bcd7b39a44fAndy Huang mAccount = account; 774f347e811052f446c3958c76db278bcd7b39a44fAndy Huang mMessage = message; 784cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein mAttachments = list; 79e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Adding tiles to grid and filling in attachment information 80e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein int index = 0; 81e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein for (Attachment attachment : list) { 828081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook addMessageTileFromAttachment(attachment, index++, loaderResult); 83f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 84f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 85f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 868081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook private void addMessageTileFromAttachment(Attachment attachment, int index, 878081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook boolean loaderResult) { 888081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook final MessageAttachmentTile attachmentTile; 89f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 90e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein if (getChildCount() <= index) { 91f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein attachmentTile = MessageAttachmentTile.inflate(mInflater, this); 928081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook attachmentTile.initialize(mFragmentManager); 934f347e811052f446c3958c76db278bcd7b39a44fAndy Huang attachmentTile.setPhotoViewHandler(this); 94f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein addView(attachmentTile); 95f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } else { 968081df46ef5a7794374e41cd1836e778a2da9b31Paul Westbrook attachmentTile = (MessageAttachmentTile) getChildAt(index); 97f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 98f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 994f347e811052f446c3958c76db278bcd7b39a44fAndy Huang attachmentTile.render(attachment, index, this, loaderResult); 100f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 101f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 102237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein public ComposeAttachmentTile addComposeTileFromAttachment(Attachment attachment) { 103237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein final ComposeAttachmentTile attachmentTile = 104237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein ComposeAttachmentTile.inflate(mInflater, this); 105237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein 106237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein addView(attachmentTile); 1074f347e811052f446c3958c76db278bcd7b39a44fAndy Huang attachmentTile.render(attachment, this); 108237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein 109237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein return attachmentTile; 110237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein } 111237129ddf57a1e25469d8990322fb7913e18ae20Andrew Sapperstein 112f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein @Override 1134f347e811052f446c3958c76db278bcd7b39a44fAndy Huang public void viewPhoto(MessageAttachmentTile source) { 1144f347e811052f446c3958c76db278bcd7b39a44fAndy Huang final int photoIndex = indexOfChild(source); 1154f347e811052f446c3958c76db278bcd7b39a44fAndy Huang 1164f347e811052f446c3958c76db278bcd7b39a44fAndy Huang MailPhotoViewActivity.startMailPhotoViewActivity(getContext(), mAccount.getEmailAddress(), 117a00a413f293b73b8b6d16c0707d08f881fd92e1cMartin Hibdon mAccount.getType(), mMessage, photoIndex); 1184f347e811052f446c3958c76db278bcd7b39a44fAndy Huang } 1194f347e811052f446c3958c76db278bcd7b39a44fAndy Huang 1204f347e811052f446c3958c76db278bcd7b39a44fAndy Huang @Override 121f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 122f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein onMeasureForTiles(widthMeasureSpec); 123f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 124f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 125f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein private void onMeasureForTiles(int widthMeasureSpec) { 126f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein final int width = MeasureSpec.getSize(widthMeasureSpec); 127f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 128f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein final int childCount = getChildCount(); 129f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein if (childCount == 0) { 130f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // Just in case... 131f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein setMeasuredDimension(width, 0); 132f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein return; 133f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 134f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 135e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Divide width by minimum tile size to get the number of columns. 136e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Truncation will ensure that the minimum will always be the minimum 137e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // but that the tiles can (and likely will) grow larger. 138e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein mColumnCount = width / mTileMinSize; 139e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 140e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Just in case... 141e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein if (mColumnCount == 0) { 142e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein mColumnCount = 1; 143e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein } 144e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 145f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // 1. Calculate image size. 146f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // = [total width] / [child count] 147f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // 148f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // 2. Set it to width/height of each children. 149e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // If we have a remainder, some tiles will have 150e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // 1 pixel larger width than its height. 151f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // 152f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // 3. Set the dimensions of itself. 153f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // Let width = given width. 154e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Let height = image size + bottom padding. 155a6e8789043b567a54cb930dd785fba573cf65f5cMark Wei 156e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein final int widthMinusPadding = width - (mColumnCount - 1) * mTilePadding; 157e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein 158e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein final int imageSize = (widthMinusPadding) / mColumnCount; 159e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein final int remainder = widthMinusPadding - (imageSize * mColumnCount); 160f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 161f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein for (int i = 0; i < childCount; i++) { 162f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein final View child = getChildAt(i); 163e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Compensate for the remainder 164e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein final int childWidth = imageSize + (i < remainder ? 1 : 0); 165f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein child.measure( 166f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.EXACTLY), 167e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein MeasureSpec.makeMeasureSpec(imageSize, MeasureSpec.EXACTLY) 168f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein ); 169f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 170e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 171e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Calculate the number of rows so we can get the proper height. 172e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Then multiply by the height of one tile to get the grid height. 173e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein final int numRows = ((childCount - 1) / mColumnCount) + 1; 174e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein setMeasuredDimension(width, 175e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein numRows * (imageSize + getChildAt(0).getPaddingBottom()) + 176e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein (numRows - 1) * mTilePadding); 177e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein } 178e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 179e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein @Override 180e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein protected void onLayout(boolean changed, int left, int top, int right, int bottom) { 181e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein onLayoutForTiles(); 182e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein } 183e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 184e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein private void onLayoutForTiles() { 185e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein final int count = getChildCount(); 186db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein if (count == 0) { 187db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein return; 188db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein } 189db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein 190e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein boolean skipBeginningOfRowFirstTime = true; 191db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein final boolean isRtl = ViewUtils.isViewRtl(this); 192db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein final int width = getMeasuredWidth(); 193e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein int childLeft = (isRtl) ? width - getChildAt(0).getMeasuredWidth() : 0; 194db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein int childTop = 0; 195e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 196e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Layout the grid. 197e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein for (int i = 0; i < count; i++) { 198e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein final View child = getChildAt(i); 199e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 200e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // Note MeasuredWidth and MeasuredHeight include the padding. 201e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein final int childWidth = child.getMeasuredWidth(); 202e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein final int childHeight = child.getMeasuredHeight(); 203e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 204e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // If we're at the beginning of a row and it is not the first row 205e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // in the grid, reset childLeft to 0 and update childTop 206e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein // to reflect the top of the new row. 207e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein if (!skipBeginningOfRowFirstTime && i % mColumnCount == 0) { 208db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein childLeft = (isRtl) ? width - childWidth : 0; 209e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein childTop += childHeight + mTilePadding; 210e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein } else { 211e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein skipBeginningOfRowFirstTime = false; 212e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein } 213e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein 214e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein child.layout(childLeft, childTop, 215e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein childLeft + childWidth, childTop + childHeight); 216db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein 217db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein if (isRtl) { 218e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein childLeft -= childWidth - mTilePadding; 219db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein } else { 220e1557036849265afc24528be9effbe299b640bffAndrew Sapperstein childLeft += childWidth + mTilePadding; 221db65689be3ada3965c12312ad60b2a5d6917a98eAndrew Sapperstein } 222e4798f5d8bd07eb39bf9dac57fd2a304b53916a0Andrew Sapperstein } 223f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 224f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein 225f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein @Override 226f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein public void sendAccessibilityEvent(int eventType) { 227f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // This method is called when the child tile is INVISIBLE (meaning "empty"), and the 228f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // Accessibility Manager needs to find alternative content description to speak. 229f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // Here, we ignore the default behavior, since we don't want to let the manager speak 230f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein // a contact name for the tile next to the INVISIBLE tile. 231f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein } 2324cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein 2334cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein public List<Attachment> getAttachments() { 2344cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein return mAttachments; 2354cb51dbce9635f4bf68a6de88f759e2f86d20325Andrew Sapperstein } 23662066e47fe69c33b60ed970e46809ba81d044064Mark Wei 23762066e47fe69c33b60ed970e46809ba81d044064Mark Wei public ArrayList<AttachmentPreview> getAttachmentPreviews() { 23862066e47fe69c33b60ed970e46809ba81d044064Mark Wei return Lists.newArrayList(mAttachmentPreviews.values()); 23962066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 24062066e47fe69c33b60ed970e46809ba81d044064Mark Wei 24162066e47fe69c33b60ed970e46809ba81d044064Mark Wei public void setAttachmentPreviews(ArrayList<AttachmentPreview> previews) { 24262066e47fe69c33b60ed970e46809ba81d044064Mark Wei if (previews != null) { 24362066e47fe69c33b60ed970e46809ba81d044064Mark Wei for (AttachmentPreview preview : previews) { 24462066e47fe69c33b60ed970e46809ba81d044064Mark Wei mAttachmentPreviews.put(preview.attachmentIdentifier, preview); 24562066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 24662066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 24762066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 24862066e47fe69c33b60ed970e46809ba81d044064Mark Wei 24962066e47fe69c33b60ed970e46809ba81d044064Mark Wei /* 25062066e47fe69c33b60ed970e46809ba81d044064Mark Wei * Save the preview for an attachment 25162066e47fe69c33b60ed970e46809ba81d044064Mark Wei */ 25262066e47fe69c33b60ed970e46809ba81d044064Mark Wei @Override 25362066e47fe69c33b60ed970e46809ba81d044064Mark Wei public void set(Attachment attachment, Bitmap preview) { 25469c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei final String attachmentIdentifier = attachment.getIdentifierUri().toString(); 25562066e47fe69c33b60ed970e46809ba81d044064Mark Wei if (attachmentIdentifier != null) { 25662066e47fe69c33b60ed970e46809ba81d044064Mark Wei mAttachmentPreviews.put( 25762066e47fe69c33b60ed970e46809ba81d044064Mark Wei attachmentIdentifier, new AttachmentPreview(attachment, preview)); 25862066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 25962066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 26062066e47fe69c33b60ed970e46809ba81d044064Mark Wei 26162066e47fe69c33b60ed970e46809ba81d044064Mark Wei /* 26262066e47fe69c33b60ed970e46809ba81d044064Mark Wei * Returns a saved preview that was previously set 26362066e47fe69c33b60ed970e46809ba81d044064Mark Wei */ 26462066e47fe69c33b60ed970e46809ba81d044064Mark Wei @Override 26562066e47fe69c33b60ed970e46809ba81d044064Mark Wei public Bitmap get(Attachment attachment) { 26669c4ddb7a49f11377143c9ff1c7b85b2450449e9Mark Wei final String attachmentIdentifier = attachment.getIdentifierUri().toString(); 26762066e47fe69c33b60ed970e46809ba81d044064Mark Wei if (attachmentIdentifier != null) { 26862066e47fe69c33b60ed970e46809ba81d044064Mark Wei final AttachmentPreview attachmentPreview = mAttachmentPreviews.get( 26962066e47fe69c33b60ed970e46809ba81d044064Mark Wei attachmentIdentifier); 27062066e47fe69c33b60ed970e46809ba81d044064Mark Wei if (attachmentPreview != null) { 27162066e47fe69c33b60ed970e46809ba81d044064Mark Wei return attachmentPreview.preview; 27262066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 27362066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 27462066e47fe69c33b60ed970e46809ba81d044064Mark Wei return null; 27562066e47fe69c33b60ed970e46809ba81d044064Mark Wei } 276f986850eb04ff614feb915e178227c4f53ca695bAndrew Sapperstein} 277