// invalidate a rectangle relative to the view's coordinate system all the way up the view // hierarchy public static void invalidateGlobalRegion(View view, RectF childBounds) { // childBounds.offset(view.getTranslationX(), view.getTranslationY()); if (DEBUG_INVALIDATE) LogUtils.v(TAG, "-------------"); while (view.getParent() != null && view.getParent() instanceof View) { view = (View) view.getParent(); view.getMatrix().mapRect(childBounds); view.invalidate( (int) Math.floor(childBounds.left), (int) Math.floor(childBounds.top), (int) Math.ceil(childBounds.right), (int) Math.ceil(childBounds.bottom)); if (DEBUG_INVALIDATE) { LogUtils.v( TAG, "INVALIDATE(" + (int) Math.floor(childBounds.left) + "," + (int) Math.floor(childBounds.top) + "," + (int) Math.ceil(childBounds.right) + "," + (int) Math.ceil(childBounds.bottom)); } } }
/** Restores preferences from a backup. */ public void restorePreferences(final List<BackupSharedPreference> preferences) { for (final BackupSharedPreference preference : preferences) { final String key = preference.getKey(); final Object value = preference.getValue(); if (!canBackup(key) || value == null) { continue; } final Object restoreValue = getRestoreValue(key, value); if (restoreValue instanceof Boolean) { getEditor().putBoolean(key, (Boolean) restoreValue); LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference); } else if (restoreValue instanceof Float) { getEditor().putFloat(key, (Float) restoreValue); LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference); } else if (restoreValue instanceof Integer) { getEditor().putInt(key, (Integer) restoreValue); LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference); } else if (restoreValue instanceof Long) { getEditor().putLong(key, (Long) restoreValue); LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference); } else if (restoreValue instanceof String) { getEditor().putString(key, (String) restoreValue); LogUtils.v(LOG_TAG, "MailPrefs Restore: %s", preference); } else if (restoreValue instanceof Set) { getEditor().putStringSet(key, (Set<String>) restoreValue); } else { LogUtils.e(LOG_TAG, "Unknown MailPrefs preference data type: %s", value.getClass()); } } getEditor().apply(); }
@Override public void loadMore(long messageId) throws RemoteException { /// M: We Can't load more in low storage state @{ if (StorageLowState.checkIfStorageLow(mContext)) { LogUtils.e(Logging.LOG_TAG, "Can't load more due to low storage"); return; } /// @} // Load a message for view... try { // 1. Resample the message, in case it disappeared or synced while // this command was in queue final EmailContent.Message message = EmailContent.Message.restoreMessageWithId(mContext, messageId); if (message == null) { return; } if (message.mFlagLoaded == EmailContent.Message.FLAG_LOADED_COMPLETE) { // We should NEVER get here return; } // 2. Open the remote folder. // TODO combine with common code in loadAttachment final Account account = Account.restoreAccountWithId(mContext, message.mAccountKey); final Mailbox mailbox = Mailbox.restoreMailboxWithId(mContext, message.mMailboxKey); if (account == null || mailbox == null) { // mListeners.loadMessageForViewFailed(messageId, "null account or mailbox"); return; } TrafficStats.setThreadStatsTag(TrafficFlags.getSyncFlags(mContext, account)); final Store remoteStore = Store.getInstance(account, mContext); final String remoteServerId; // If this is a search result, use the protocolSearchInfo field to get the // correct remote location if (!TextUtils.isEmpty(message.mProtocolSearchInfo)) { remoteServerId = message.mProtocolSearchInfo; } else { remoteServerId = mailbox.mServerId; } final Folder remoteFolder = remoteStore.getFolder(remoteServerId); remoteFolder.open(OpenMode.READ_WRITE); // 3. Set up to download the entire message final Message remoteMessage = remoteFolder.getMessage(message.mServerId); final FetchProfile fp = new FetchProfile(); fp.add(FetchProfile.Item.BODY); remoteFolder.fetch(new Message[] {remoteMessage}, fp, null); // 4. Write to provider Utilities.copyOneMessageToProvider( mContext, remoteMessage, account, mailbox, EmailContent.Message.FLAG_LOADED_COMPLETE); } catch (MessagingException me) { if (Logging.LOGD) LogUtils.v(Logging.LOG_TAG, "", me); } catch (RuntimeException rte) { LogUtils.d(Logging.LOG_TAG, "RTE During loadMore"); } }
/** * {@link #setUserVisibleHint(boolean)} only works on API >= 15, so implement our own for * reliability on older platforms. */ public void setExtraUserVisibleHint(boolean isVisibleToUser) { LogUtils.v(LOG_TAG, "in CVF.setHint, val=%s (%s)", isVisibleToUser, this); if (mUserVisible != isVisibleToUser) { mUserVisible = isVisibleToUser; MessageCursor cursor = getMessageCursor(); if (mUserVisible && (cursor != null && cursor.isLoaded() && cursor.getCount() == 0)) { // Pop back to conversation list and show error. onError(); return; } onUserVisibleHintChanged(); } }
public boolean onTouchEvent(MotionEvent ev) { if (!mDragging) { return false; } mVelocityTracker.addMovement(ev); final int action = ev.getAction(); switch (action) { case MotionEvent.ACTION_OUTSIDE: case MotionEvent.ACTION_MOVE: if (mCurrView != null) { float deltaX = ev.getX() - mInitialTouchPosX; // If the swipe started in the dead region, ignore it. if (mInitialTouchPosX <= (DEAD_REGION_FOR_SWIPE * mDensityScale)) { return true; } // If the user has gone vertical and not gone horizontalish AT // LEAST minBeforeLock, switch to scroll. Otherwise, cancel // the swipe. float minDistance = MIN_SWIPE; if (Math.abs(deltaX) < minDistance) { // Don't start the drag until at least X distance has // occurred. return true; } // don't let items that can't be dismissed be dragged more // than maxScrollDistance if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) { float size = getSize(mCurrAnimView); float maxScrollDistance = 0.15f * size; if (Math.abs(deltaX) >= size) { deltaX = deltaX > 0 ? maxScrollDistance : -maxScrollDistance; } else { deltaX = maxScrollDistance * (float) Math.sin((deltaX / size) * (Math.PI / 2)); } } setTranslation(mCurrAnimView, deltaX); if (FADE_OUT_DURING_SWIPE && mCanCurrViewBeDimissed) { mCurrAnimView.setAlpha(getAlphaForOffset(mCurrAnimView)); if (mPrevView != null) { // Base how much the text of the prev item is faded // on how far the current item has moved. mPrevView.setTextAlpha(getTextAlphaForOffset(mCurrAnimView)); } } invalidateGlobalRegion(mCurrView.getSwipeableView().getView()); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: if (mCurrView != null) { float maxVelocity = MAX_DISMISS_VELOCITY * mDensityScale; mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, maxVelocity); float escapeVelocity = SWIPE_ESCAPE_VELOCITY * mDensityScale; float velocity = getVelocity(mVelocityTracker); float perpendicularVelocity = getPerpendicularVelocity(mVelocityTracker); // Decide whether to dismiss the current view // Tweak constants below as required to prevent erroneous // swipe/dismiss float translation = Math.abs(mCurrAnimView.getTranslationX()); float currAnimViewSize = getSize(mCurrAnimView); // Long swipe = translation of .4 * width boolean childSwipedFarEnough = DISMISS_IF_SWIPED_FAR_ENOUGH && translation > 0.4 * currAnimViewSize; // Fast swipe = > escapeVelocity and translation of .1 * // width boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) && (Math.abs(velocity) > Math.abs(perpendicularVelocity)) && (velocity > 0) == (mCurrAnimView.getTranslationX() > 0) && translation > 0.05 * currAnimViewSize; if (LOG_SWIPE_DISMISS_VELOCITY) { LogUtils.v( TAG, "Swipe/Dismiss: " + velocity + "/" + escapeVelocity + "/" + perpendicularVelocity + ", x: " + translation + "/" + currAnimViewSize); } boolean dismissChild = mCallback.canChildBeDismissed(mCurrView) && (childSwipedFastEnough || childSwipedFarEnough); if (dismissChild) { dismissChild(mCurrView, childSwipedFastEnough ? velocity : 0f); } else { snapChild(mCurrView); } } break; } return true; }