1 /** 2 * Copyright (C) 2014 Google Inc. 3 * Licensed to The Android Open Source Project. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package com.android.mail.ui; 18 19 import android.content.Context; 20 import android.support.annotation.LayoutRes; 21 import android.util.AttributeSet; 22 import android.view.LayoutInflater; 23 import android.view.View; 24 import android.widget.ImageView; 25 import android.widget.LinearLayout; 26 27 import com.android.mail.R; 28 import com.android.mail.bitmap.AccountAvatarDrawable; 29 import com.android.mail.content.ObjectCursor; 30 import com.android.mail.providers.Account; 31 import com.android.mail.providers.Folder; 32 import com.google.common.collect.Lists; 33 34 import java.util.List; 35 36 /** 37 * A smaller version of the account- and folder-switching drawer view for tablet UIs. 38 */ 39 public class MiniDrawerView extends LinearLayout { 40 41 private FolderListFragment mController; 42 private final int mDrawWidth; 43 // use the same dimen as AccountItemView to participate in recycling 44 // TODO: but Material account switcher doesn't recycle... 45 private final int mAvatarDecodeSize; 46 47 private View mDotdotdot; 48 private View mSpacer; 49 50 private AccountItem mCurrentAccount; 51 private final List<AccountItem> mRecentAccounts = Lists.newArrayList(); 52 53 private final LayoutInflater mInflater; 54 55 private static final int NUM_RECENT_ACCOUNTS = 2; 56 57 public MiniDrawerView(Context context) { 58 this(context, null); 59 } 60 61 public MiniDrawerView(Context context, AttributeSet attrs) { 62 super(context, attrs); 63 64 mDrawWidth = getResources().getDimensionPixelSize(R.dimen.two_pane_drawer_width_mini); 65 mAvatarDecodeSize = getResources().getDimensionPixelSize(R.dimen.account_avatar_dimension); 66 67 mInflater = LayoutInflater.from(context); 68 } 69 70 @Override 71 protected void onFinishInflate() { 72 super.onFinishInflate(); 73 74 mCurrentAccount = new AccountItem((ImageView) findViewById(R.id.current_account_avatar)); 75 mSpacer = findViewById(R.id.spacer); 76 mDotdotdot = findViewById(R.id.dotdotdot); 77 mDotdotdot.setOnClickListener(new View.OnClickListener() { 78 @Override 79 public void onClick(View v) { 80 mController.toggleDrawerState(); 81 } 82 }); 83 } 84 85 public void setController(FolderListFragment flf) { 86 mController = flf; 87 88 if (!mController.isMiniDrawerEnabled()) { 89 return; 90 } 91 92 // wait for the controller to set these up 93 mCurrentAccount.setupDrawable(); 94 } 95 96 public void refresh() { 97 if (mController == null) { 98 return; 99 } 100 101 final Account currentAccount = mController.getCurrentAccount(); 102 if (currentAccount != null) { 103 mCurrentAccount.setAccount(currentAccount); 104 } 105 106 View child; 107 108 // TODO: figure out the N most recent accounts, don't just take the first few 109 final int removePos = indexOfChild(mSpacer) + 1; 110 if (getChildCount() > removePos) { 111 removeViews(removePos, getChildCount() - removePos); 112 } 113 final Account[] accounts = mController.getAllAccounts(); 114 int count = 0; 115 for (Account a : accounts) { 116 if (count >= NUM_RECENT_ACCOUNTS) { 117 break; 118 } 119 if (currentAccount.uri.equals(a.uri)) { 120 continue; 121 } 122 final ImageView iv = (ImageView) mInflater.inflate( 123 R.layout.mini_drawer_recent_account_item, this, false /* attachToRoot */); 124 final AccountItem item = new AccountItem(iv); 125 item.setupDrawable(); 126 item.setAccount(a); 127 iv.setTag(item); 128 addView(iv); 129 count++; 130 } 131 132 // reset the inbox views for this account 133 while ((child=getChildAt(1)) != mDotdotdot) { 134 removeView(child); 135 } 136 final ObjectCursor<Folder> folderCursor = mController.getFoldersCursor(); 137 if (folderCursor != null && !folderCursor.isClosed()) { 138 int pos = -1; 139 int numInboxes = 0; 140 while (folderCursor.moveToPosition(++pos)) { 141 final Folder f = folderCursor.getModel(); 142 if (f.isInbox()) { 143 final ImageView iv = (ImageView) mInflater.inflate( 144 R.layout.mini_drawer_folder_item, this, false /* attachToRoot */); 145 iv.setTag(new FolderItem(f, iv)); 146 addView(iv, 1 + numInboxes); 147 numInboxes++; 148 } 149 } 150 } 151 } 152 153 private class FolderItem implements View.OnClickListener { 154 public final Folder folder; 155 public final ImageView view; 156 157 public FolderItem(Folder f, ImageView iv) { 158 folder = f; 159 view = iv; 160 Folder.setIcon(folder, view); 161 view.setOnClickListener(this); 162 } 163 164 @Override 165 public void onClick(View v) { 166 mController.onFolderSelected(folder, "mini-drawer"); 167 } 168 } 169 170 private class AccountItem implements View.OnClickListener { 171 private Account mAccount; 172 // FIXME: this codepath doesn't use GMS Core, resulting in inconsistent avatars 173 // vs. ownerslib. switch to a generic photo getter+listener interface on FLF 174 // so these drawables are obtainable regardless of how they are loaded. 175 private AccountAvatarDrawable mDrawable; 176 public final ImageView view; 177 178 public AccountItem(ImageView iv) { 179 view = iv; 180 view.setOnClickListener(this); 181 } 182 183 public void setupDrawable() { 184 mDrawable = new AccountAvatarDrawable(getResources(), 185 mController.getBitmapCache(), mController.getContactResolver()); 186 mDrawable.setDecodeDimensions(mAvatarDecodeSize, mAvatarDecodeSize); 187 view.setImageDrawable(mDrawable); 188 } 189 190 public void setAccount(Account acct) { 191 mAccount = acct; 192 mDrawable.bind(mAccount.getSenderName(), mAccount.getEmailAddress()); 193 } 194 195 @Override 196 public void onClick(View v) { 197 mController.onAccountSelected(mAccount); 198 } 199 200 } 201 202 } 203