List of usage examples for android.os Debug startMethodTracing
public static void startMethodTracing(String tracePath)
From source file:com.anysoftkeyboard.ui.dev.DeveloperUtils.java
public static void startTracing() { Debug.startMethodTracing(getTraceFile().getAbsolutePath()); msTracingStarted = true; }
From source file:com.binomed.showtime.android.util.activity.AbstractCineShowTimeActivity.java
/** Called when the activity is first created. */ @Override//from w w w . ja v a 2 s .com public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // mContext = getApplicationContext(); if (CineShowtimeCst.TRACE_VIEW_ENABLE) { Debug.startMethodTracing("cineshowtimeTraceView" + getTAG()); } startActivityTime = System.currentTimeMillis(); getTracker(); CineShowTimeLayoutUtils.onActivityCreateSetTheme(this, getPrefs()); tracker.trackEvent(CineShowtimeCst.ANALYTICS_CATEGORY_ACTIVITY // Category , CineShowtimeCst.ANALYTICS_ACTION_OPEN // Action , getTrackerName() // Label , 0 // Value ); // Init vital informations openDB(); getModelActivity(); // try to restore informations before onPreRestoreBundle(savedInstanceState); // We call the contentView setContentView(R.layout.cst_action_bar_activity); // Init theme background // Drawable d = getResources().getDrawable(R.drawable.background_dark); // String defaultTheme = getResources().getString(R.string.preference_gen_default_theme); // String theme = getPrefs().getString(getResources().getString(R.string.preference_gen_key_theme), defaultTheme); // if (!theme.equals(defaultTheme)) { // d = getResources().getDrawable(R.drawable.background_light); // } // d.setDither(true); mActionBarHost = (ActionBarHost) findViewById(R.id.gd_action_bar_host); // mActionBarHost.setBackgroundDrawable(d); mActionBarHost.getContentView().removeAllViews(); LayoutInflater.from(this).inflate(getLayout(), mActionBarHost.getContentView()); // d = mActionBarHost.getBackground(); // d.setDither(true); // mActionBarHost.setBackgroundDrawable(d); // Drawable backActionBar = mActionBarHost.getActionBar().getBackground(); // backActionBar.setDither(true); // mActionBarHost.getActionBar().setBackgroundDrawable(backActionBar); // Init adds adView = (AdView) findViewById(R.id.adView); withAdd = !getPackageName().toLowerCase().equals("com.binomed.showtime.adsfree"); if (adView != null) { AdRequest adRequest = new AdRequest(); adRequest.addTestDevice(AdRequest.TEST_EMULATOR); adView.loadAd(adRequest); if (!withAdd) { adView.setVisibility(View.GONE); } } // We load the content initContentView(); // We add actions bar items addActionBarItems(getActionBar()); addActionBarItem( getActionBar().newActionBarItem(NormalActionBarItem.class).setDrawable( new ActionBarDrawable(this, R.drawable.ic_menu_moreoverflow_normal_holo_light)), R.id.action_bar_menu); prepareQuickActionBar(); // We manage the results for other activity refreshResultsIntent(); // try to restore information after onPostRestoreBundle(savedInstanceState); }
From source file:com.android.calendar.Event.java
/** * Loads <i>days</i> days worth of instances starting at <i>startDay</i>. *//*w ww . j a va 2 s. c o m*/ public static void loadEvents(Context context, ArrayList<Event> events, int startDay, int days, int requestId, AtomicInteger sequenceNumber) { if (PROFILE) { Debug.startMethodTracing("loadEvents"); } if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED) { //If permission is not granted then just return. return; } Cursor cEvents = null; Cursor cAllday = null; events.clear(); try { int endDay = startDay + days - 1; // We use the byDay instances query to get a list of all events for // the days we're interested in. // The sort order is: events with an earlier start time occur // first and if the start times are the same, then events with // a later end time occur first. The later end time is ordered // first so that long rectangles in the calendar views appear on // the left side. If the start and end times of two events are // the same then we sort alphabetically on the title. This isn't // required for correctness, it just adds a nice touch. // Respect the preference to show/hide declined events SharedPreferences prefs = GeneralPreferences.getSharedPreferences(context); boolean hideDeclined = prefs.getBoolean(GeneralPreferences.KEY_HIDE_DECLINED, false); String where = EVENTS_WHERE; String whereAllday = ALLDAY_WHERE; if (hideDeclined) { String hideString = " AND " + Instances.SELF_ATTENDEE_STATUS + "!=" + Attendees.ATTENDEE_STATUS_DECLINED; where += hideString; whereAllday += hideString; } cEvents = instancesQuery(context.getContentResolver(), EVENT_PROJECTION, startDay, endDay, where, null, SORT_EVENTS_BY); cAllday = instancesQuery(context.getContentResolver(), EVENT_PROJECTION, startDay, endDay, whereAllday, null, SORT_ALLDAY_BY); // Check if we should return early because there are more recent // load requests waiting. if (requestId != sequenceNumber.get()) { return; } buildEventsFromCursor(events, cEvents, context, startDay, endDay); buildEventsFromCursor(events, cAllday, context, startDay, endDay); } finally { if (cEvents != null) { cEvents.close(); } if (cAllday != null) { cAllday.close(); } if (PROFILE) { Debug.stopMethodTracing(); } } }
From source file:com.hippo.widget.lockpattern.LockPatternView.java
private void handleActionDown(MotionEvent event) { resetPattern();//from w ww. j a va2s .c om final float x = event.getX(); final float y = event.getY(); final Cell hitCell = detectAndAddHit(x, y); if (hitCell != null) { mPatternInProgress = true; mPatternDisplayMode = DisplayMode.Correct; notifyPatternStarted(); } else if (mPatternInProgress) { mPatternInProgress = false; notifyPatternCleared(); } if (hitCell != null) { final float startX = getCenterXForColumn(hitCell.column); final float startY = getCenterYForRow(hitCell.row); final float widthOffset = mSquareWidth / 2f; final float heightOffset = mSquareHeight / 2f; invalidate((int) (startX - widthOffset), (int) (startY - heightOffset), (int) (startX + widthOffset), (int) (startY + heightOffset)); } mInProgressX = x; mInProgressY = y; if (PROFILE_DRAWING) { if (!mDrawingProfilingStarted) { Debug.startMethodTracing("LockPatternDrawing"); mDrawingProfilingStarted = true; } } }
From source file:com.rexmtorres.android.patternlock.PatternLockView.java
private void handleActionDown(MotionEvent event) { resetPattern();//from ww w . ja va2 s. co m final float x = event.getX(); final float y = event.getY(); final Cell hitCell = detectAndAddHit(x, y); if (hitCell != null) { setPatternInProgress(true); mPatternDisplayMode = DisplayMode.Correct; notifyPatternStarted(); } else if (mPatternInProgress) { setPatternInProgress(false); notifyPatternCleared(); } if (hitCell != null) { final float startX = getCenterXForColumn(hitCell.column); final float startY = getCenterYForRow(hitCell.row); final float widthOffset = mSquareWidth / 2f; final float heightOffset = mSquareHeight / 2f; invalidate((int) (startX - widthOffset), (int) (startY - heightOffset), (int) (startX + widthOffset), (int) (startY + heightOffset)); } mInProgressX = x; mInProgressY = y; if (PROFILE_DRAWING) { if (!mDrawingProfilingStarted) { Debug.startMethodTracing("LockPatternDrawing"); mDrawingProfilingStarted = true; } } }
From source file:com.android.nobug.view.pattern.PatternView.java
private void handleActionDown(MotionEvent event) { resetPattern();// ww w . j a v a2 s .com final float x = event.getX(); final float y = event.getY(); final Cell hitCell = detectAndAddHit(x, y); if (hitCell != null) { setPatternInProgress(true); mPatternDisplayMode = DisplayMode.Correct; notifyPatternStarted(); } else if (mPatternInProgress) { setPatternInProgress(false); notifyPatternCleared(); } if (hitCell != null) { final float startX = getCenterXForColumn(hitCell.column); final float startY = getCenterYForRow(hitCell.row); final float widthOffset = mSquareWidth / 2f; final float heightOffset = mSquareHeight / 2f; invalidate((int) (startX - widthOffset), (int) (startY - heightOffset), (int) (startX + widthOffset), (int) (startY + heightOffset)); } mInProgressX = x; mInProgressY = y; if (PROFILE_DRAWING) { if (!mDrawingProfilingStarted) { Debug.startMethodTracing("LockPatternDrawing"); mDrawingProfilingStarted = true; } } }
From source file:org.distantshoresmedia.keyboard.LatinIME.java
@Override public void onStartInputView(EditorInfo attribute, boolean restarting) { sKeyboardSettings.editorPackageName = attribute.packageName; sKeyboardSettings.editorFieldName = attribute.fieldName; sKeyboardSettings.editorFieldId = attribute.fieldId; sKeyboardSettings.editorInputType = attribute.inputType; //Log.i("PCKeyboard", "onStartInputView " + attribute + ", inputType= " + Integer.toHexString(attribute.inputType) + ", restarting=" + restarting); TKKeyboardView inputView = mKeyboardSwitcher.getInputView(); // In landscape mode, this method gets called without the input view // being created. if (inputView == null) { return;/*from ww w. ja v a 2s. c o m*/ } if (mRefreshKeyboardRequired) { mRefreshKeyboardRequired = false; toggleLanguage(true, true); } mKeyboardSwitcher.makeKeyboards(false); TextEntryState.newSession(this); // Most such things we decide below in the switch statement, but we need to know // now whether this is a password text field, because we need to know now (before // the switch statement) whether we want to enable the voice button. mPasswordText = false; int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD || variation == EditorInfo.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD || variation == 0xe0 /* EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD */ ) { if ((attribute.inputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) { mPasswordText = true; } } mEnableVoiceButton = shouldShowVoiceButton(attribute); final boolean enableVoiceButton = mEnableVoiceButton && mEnableVoice; // if (mVoiceRecognitionTrigger != null) { // mVoiceRecognitionTrigger.onStartInputView(); // } mInputTypeNoAutoCorrect = false; mPredictionOnForMode = false; mCompletionOn = false; mCompletions = null; mModCtrl = false; mModAlt = false; mModMeta = false; mModFn = false; mEnteredText = null; mSuggestionForceOn = false; mSuggestionForceOff = false; mKeyboardModeOverridePortrait = 0; mKeyboardModeOverrideLandscape = 0; sKeyboardSettings.useExtension = false; switch (attribute.inputType & EditorInfo.TYPE_MASK_CLASS) { case EditorInfo.TYPE_CLASS_NUMBER: case EditorInfo.TYPE_CLASS_DATETIME: // fall through // NOTE: For now, we use the phone keyboard for NUMBER and DATETIME // until we get // a dedicated number entry keypad. // TODO: Use a dedicated number entry keypad here when we get one. case EditorInfo.TYPE_CLASS_PHONE: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_PHONE, attribute.imeOptions, enableVoiceButton, null); break; case EditorInfo.TYPE_CLASS_TEXT: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, attribute.imeOptions, enableVoiceButton, null); // startPrediction(); mPredictionOnForMode = true; // Make sure that passwords are not displayed in candidate view if (mPasswordText) { mPredictionOnForMode = false; } if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS || variation == EditorInfo.TYPE_TEXT_VARIATION_PERSON_NAME || !mLanguageSwitcher.allowAutoSpace()) { mAutoSpace = false; } else { mAutoSpace = true; } if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) { mPredictionOnForMode = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_EMAIL, attribute.imeOptions, enableVoiceButton, null); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_URI) { mPredictionOnForMode = false; mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_URL, attribute.imeOptions, enableVoiceButton, null); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_SHORT_MESSAGE) { mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_IM, attribute.imeOptions, enableVoiceButton, null); } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_FILTER) { mPredictionOnForMode = false; } else if (variation == EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) { mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_WEB, attribute.imeOptions, enableVoiceButton, null); // If it's a browser edit field and auto correct is not ON // explicitly, then // disable auto correction, but keep suggestions on. if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0) { mInputTypeNoAutoCorrect = true; } } // If NO_SUGGESTIONS is set, don't do prediction. if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_NO_SUGGESTIONS) != 0) { mPredictionOnForMode = false; mInputTypeNoAutoCorrect = true; } // If it's not multiline and the autoCorrect flag is not set, then // don't correct if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT) == 0 && (attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE) == 0) { mInputTypeNoAutoCorrect = true; } if ((attribute.inputType & EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) { mPredictionOnForMode = false; mCompletionOn = isFullscreenMode(); } break; default: mKeyboardSwitcher.setKeyboardMode(KeyboardSwitcher.MODE_TEXT, attribute.imeOptions, enableVoiceButton, null); } inputView.closing(); resetPrediction(); loadSettings(); updateShiftKeyState(attribute); mPredictionOnPref = (mCorrectionMode > 0 || mShowSuggestions); setCandidatesViewShownInternal(isCandidateStripVisible() || mCompletionOn, false /* needsInputViewShown */); updateSuggestions(); // If the dictionary is not big enough, don't auto correct mHasDictionary = mSuggest.hasMainDictionary(); updateCorrectionMode(); inputView.setPreviewEnabled(mPopupOn); inputView.setProximityCorrectionEnabled(true); // If we just entered a text field, maybe it has some old text that // requires correction checkReCorrectionOnStart(); checkTutorial(attribute.privateImeOptions); if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); }
From source file:io.authme.sdk.widget.LockPatternView.java
private void handleActionDown(MotionEvent event) { resetPattern();/*ww w .j av a2 s .c om*/ final float x = event.getX(); final float y = event.getY(); final Cell hitCell = detectAndAddHit(x, y); if (hitCell != null) { mPatternInProgress = true; mPatternDisplayMode = DisplayMode.Correct; notifyPatternStarted(); } else { /* * Original source check for mPatternInProgress == true first before * calling this block. But if we do that, there will be nothing * happened when the user taps at empty area and releases the * finger. We want the pattern to be reset and the message will be * updated after the user did that. */ mPatternInProgress = false; notifyPatternCleared(); } if (hitCell != null) { final float startX = getCenterXForColumn(hitCell.column); final float startY = getCenterYForRow(hitCell.row); final float widthOffset = mSquareWidth / 2f; final float heightOffset = mSquareHeight / 2f; invalidate((int) (startX - widthOffset), (int) (startY - heightOffset), (int) (startX + widthOffset), (int) (startY + heightOffset)); } mInProgressX = x; mInProgressY = y; if (PROFILE_DRAWING) { if (!mDrawingProfilingStarted) { Debug.startMethodTracing("LockPatternDrawing"); mDrawingProfilingStarted = true; } } }
From source file:com.mobiletin.inputmethod.indic.LatinIME.java
@SuppressWarnings("deprecation") private void onStartInputViewInternal(final EditorInfo editorInfo, final boolean restarting) { super.onStartInputView(editorInfo, restarting); mRichImm.clearSubtypeCaches();/*w w w.ja va2s .c om*/ final KeyboardSwitcher switcher = mKeyboardSwitcher; switcher.updateKeyboardTheme(); final MainKeyboardView mainKeyboardView = switcher.getMainKeyboardView(); // If we are starting input in a different text field from before, we'll have to reload // settings, so currentSettingsValues can't be final. SettingsValues currentSettingsValues = mSettings.getCurrent(); if (editorInfo == null) { Log.e(TAG, "Null EditorInfo in onStartInputView()"); if (DebugFlags.DEBUG_ENABLED) { throw new NullPointerException("Null EditorInfo in onStartInputView()"); } return; } if (DEBUG) { Log.d(TAG, "onStartInputView: editorInfo:" + String.format("inputType=0x%08x imeOptions=0x%08x", editorInfo.inputType, editorInfo.imeOptions)); Log.d(TAG, "All caps = " + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) + ", sentence caps = " + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) + ", word caps = " + ((editorInfo.inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0)); } Log.e(TAG, "Starting input. Cursor position = " + editorInfo.initialSelStart + "," + editorInfo.initialSelEnd); // TODO: Consolidate these checks with {@link InputAttributes}. if (InputAttributes.inPrivateImeOptions(null, NO_MICROPHONE_COMPAT, editorInfo)) { Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions); Log.w(TAG, "Use " + getPackageName() + "." + NO_MICROPHONE + " instead"); } if (InputAttributes.inPrivateImeOptions(getPackageName(), FORCE_ASCII, editorInfo)) { Log.w(TAG, "Deprecated private IME option specified: " + editorInfo.privateImeOptions); Log.w(TAG, "Use EditorInfo.IME_FLAG_FORCE_ASCII flag instead"); } // In landscape mode, this method gets called without the input view being created. if (mainKeyboardView == null) { return; } // Forward this event to the accessibility utilities, if enabled. final AccessibilityUtils accessUtils = AccessibilityUtils.getInstance(); if (accessUtils.isTouchExplorationEnabled()) { accessUtils.onStartInputViewInternal(mainKeyboardView, editorInfo, restarting); } final boolean inputTypeChanged = !currentSettingsValues.isSameInputType(editorInfo); final boolean isDifferentTextField = !restarting || inputTypeChanged; if (isDifferentTextField) { mSubtypeSwitcher.updateParametersOnStartInputView(); } // The EditorInfo might have a flag that affects fullscreen mode. // Note: This call should be done by InputMethodService? updateFullscreenMode(); // ALERT: settings have not been reloaded and there is a chance they may be stale. // In the practice, if it is, we should have gotten onConfigurationChanged so it should // be fine, but this is horribly confusing and must be fixed AS SOON AS POSSIBLE. // In some cases the input connection has not been reset yet and we can't access it. In // this case we will need to call loadKeyboard() later, when it's accessible, so that we // can go into the correct mode, so we need to do some housekeeping here. final boolean needToCallLoadKeyboardLater; final Suggest suggest = mInputLogic.mSuggest; if (!currentSettingsValues.mHasHardwareKeyboard) { // The app calling setText() has the effect of clearing the composing // span, so we should reset our state unconditionally, even if restarting is true. // We also tell the input logic about the combining rules for the current subtype, so // it can adjust its combiners if needed. mInputLogic.startInput(mSubtypeSwitcher.getCombiningRulesExtraValueOfCurrentSubtype(), currentSettingsValues); // Note: the following does a round-trip IPC on the main thread: be careful final Locale currentLocale = mSubtypeSwitcher.getCurrentSubtypeLocale(); if (null != currentLocale && !currentLocale.equals(suggest.getLocale())) { // TODO: Do this automatically. resetSuggest(); } // TODO[IL]: Can the following be moved to InputLogic#startInput? if (!mInputLogic.mConnection.resetCachesUponCursorMoveAndReturnSuccess(editorInfo.initialSelStart, editorInfo.initialSelEnd, false /* shouldFinishComposition */)) { // Sometimes, while rotating, for some reason the framework tells the app we are not // connected to it and that means we can't refresh the cache. In this case, schedule // a refresh later. // We try resetting the caches up to 5 times before giving up. mHandler.postResetCaches(isDifferentTextField, 5 /* remainingTries */); // mLastSelection{Start,End} are reset later in this method, no need to do it here needToCallLoadKeyboardLater = true; } else { // When rotating, initialSelStart and initialSelEnd sometimes are lying. Make a best // effort to work around this bug. mInputLogic.mConnection.tryFixLyingCursorPosition(); mHandler.postResumeSuggestions(true /* shouldIncludeResumedWordInSuggestions */, true /* shouldDelay */); needToCallLoadKeyboardLater = false; } } else { // If we have a hardware keyboard we don't need to call loadKeyboard later anyway. needToCallLoadKeyboardLater = false; } if (isDifferentTextField || !currentSettingsValues.hasSameOrientation(getResources().getConfiguration())) { loadSettings(); } if (isDifferentTextField) { mainKeyboardView.closing(); currentSettingsValues = mSettings.getCurrent(); if (currentSettingsValues.mAutoCorrectionEnabledPerUserSettings) { suggest.setAutoCorrectionThreshold(currentSettingsValues.mAutoCorrectionThreshold); } switcher.loadKeyboard(editorInfo, currentSettingsValues, getCurrentAutoCapsState(), getCurrentRecapitalizeState()); if (needToCallLoadKeyboardLater) { // If we need to call loadKeyboard again later, we need to save its state now. The // later call will be done in #retryResetCaches. switcher.saveKeyboardState(); } } else if (restarting) { // TODO: Come up with a more comprehensive way to reset the keyboard layout when // a keyboard layout set doesn't get reloaded in this method. switcher.resetKeyboardStateToAlphabet(getCurrentAutoCapsState(), getCurrentRecapitalizeState()); // In apps like Talk, we come here when the text is sent and the field gets emptied and // we need to re-evaluate the shift state, but not the whole layout which would be // disruptive. // Space state must be updated before calling updateShiftState switcher.requestUpdatingShiftState(getCurrentAutoCapsState(), getCurrentRecapitalizeState()); } // This will set the punctuation suggestions if next word suggestion is off; // otherwise it will clear the suggestion strip. setNeutralSuggestionStrip(); mHandler.cancelUpdateSuggestionStrip(); mainKeyboardView.setMainDictionaryAvailability(mDictionaryFacilitator.hasInitializedMainDictionary()); mainKeyboardView.setKeyPreviewPopupEnabled(currentSettingsValues.mKeyPreviewPopupOn, currentSettingsValues.mKeyPreviewPopupDismissDelay); mainKeyboardView.setSlidingKeyInputPreviewEnabled(currentSettingsValues.mSlidingKeyInputPreviewEnabled); mainKeyboardView.setGestureHandlingEnabledByUser(currentSettingsValues.mGestureInputEnabled, currentSettingsValues.mGestureTrailEnabled, currentSettingsValues.mGestureFloatingPreviewTextEnabled); // Contextual dictionary should be updated for the current application. mContextualDictionaryUpdater.onStartInputView(editorInfo.packageName); if (TRACE) Debug.startMethodTracing("/data/trace/latinime"); }
From source file:com.glview.widget.AbsListView.java
private void scrollIfNeeded(int x, int y, MotionEvent vtev) { int rawDeltaY = y - mMotionY; int scrollOffsetCorrection = 0; int scrollConsumedCorrection = 0; if (mLastY == Integer.MIN_VALUE) { rawDeltaY -= mMotionCorrection;//from w ww .j a v a 2s.c om } if (dispatchNestedPreScroll(0, mLastY != Integer.MIN_VALUE ? mLastY - y : -rawDeltaY, mScrollConsumed, mScrollOffset)) { rawDeltaY += mScrollConsumed[1]; scrollOffsetCorrection = -mScrollOffset[1]; scrollConsumedCorrection = mScrollConsumed[1]; if (vtev != null) { vtev.offsetLocation(0, mScrollOffset[1]); mNestedYOffset += mScrollOffset[1]; } } final int deltaY = rawDeltaY; int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY + scrollConsumedCorrection : deltaY; int lastYCorrection = 0; if (mTouchMode == TOUCH_MODE_SCROLL) { if (PROFILE_SCROLLING) { if (!mScrollProfilingStarted) { Debug.startMethodTracing("AbsListViewScroll"); mScrollProfilingStarted = true; } } if (y != mLastY) { // We may be here after stopping a fling and continuing to scroll. // If so, we haven't disallowed intercepting touch events yet. // Make sure that we do so in case we're in a parent that can intercept. if ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) == 0 && Math.abs(rawDeltaY) > mTouchSlop) { final ViewGroup parent = getParent(); if (parent != null) { parent.requestDisallowInterceptTouchEvent(true); } } final int motionIndex; if (mMotionPosition >= 0) { motionIndex = mMotionPosition - mFirstPosition; } else { // If we don't have a motion position that we can reliably track, // pick something in the middle to make a best guess at things below. motionIndex = getChildCount() / 2; } int motionViewPrevTop = 0; View motionView = this.getChildAt(motionIndex); if (motionView != null) { motionViewPrevTop = motionView.getTop(); } // No need to do all this work if we're not going to move anyway boolean atEdge = false; if (incrementalDeltaY != 0) { atEdge = trackMotionScroll(deltaY, incrementalDeltaY); } // Check to see if we have bumped into the scroll limit motionView = this.getChildAt(motionIndex); if (motionView != null) { // Check if the top of the motion view is where it is // supposed to be final int motionViewRealTop = motionView.getTop(); if (atEdge) { // Apply overscroll int overscroll = -incrementalDeltaY - (motionViewRealTop - motionViewPrevTop); if (dispatchNestedScroll(0, overscroll - incrementalDeltaY, 0, overscroll, mScrollOffset)) { lastYCorrection -= mScrollOffset[1]; if (vtev != null) { vtev.offsetLocation(0, mScrollOffset[1]); mNestedYOffset += mScrollOffset[1]; } } else { final boolean atOverscrollEdge = overScrollBy(0, overscroll, 0, mScrollY, 0, 0, 0, mOverscrollDistance, true); if (atOverscrollEdge && mVelocityTracker != null) { // Don't allow overfling if we're at the edge mVelocityTracker.clear(); } final int overscrollMode = getOverScrollMode(); if (overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) { if (!atOverscrollEdge) { mDirection = 0; // Reset when entering overscroll. mTouchMode = TOUCH_MODE_OVERSCROLL; } if (incrementalDeltaY > 0) { mEdgeGlowTop.onPull((float) -overscroll / getHeight(), (float) x / getWidth()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidate(0, 0, getWidth(), mEdgeGlowTop.getMaxHeight() + getPaddingTop()); } else if (incrementalDeltaY < 0) { mEdgeGlowBottom.onPull((float) overscroll / getHeight(), 1.f - (float) x / getWidth()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); } invalidate(0, getHeight() - getPaddingBottom() - mEdgeGlowBottom.getMaxHeight(), getWidth(), getHeight()); } } } } mMotionY = y + lastYCorrection + scrollOffsetCorrection; } mLastY = y + lastYCorrection + scrollOffsetCorrection; } } else if (mTouchMode == TOUCH_MODE_OVERSCROLL) { if (y != mLastY) { final int oldScroll = mScrollY; final int newScroll = oldScroll - incrementalDeltaY; int newDirection = y > mLastY ? 1 : -1; if (mDirection == 0) { mDirection = newDirection; } int overScrollDistance = -incrementalDeltaY; if ((newScroll < 0 && oldScroll >= 0) || (newScroll > 0 && oldScroll <= 0)) { overScrollDistance = -oldScroll; incrementalDeltaY += overScrollDistance; } else { incrementalDeltaY = 0; } if (overScrollDistance != 0) { overScrollBy(0, overScrollDistance, 0, mScrollY, 0, 0, 0, mOverscrollDistance, true); final int overscrollMode = getOverScrollMode(); if (overscrollMode == OVER_SCROLL_ALWAYS || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && !contentFits())) { if (rawDeltaY > 0) { mEdgeGlowTop.onPull((float) overScrollDistance / getHeight(), (float) x / getWidth()); if (!mEdgeGlowBottom.isFinished()) { mEdgeGlowBottom.onRelease(); } invalidate(0, 0, getWidth(), mEdgeGlowTop.getMaxHeight() + getPaddingTop()); } else if (rawDeltaY < 0) { mEdgeGlowBottom.onPull((float) overScrollDistance / getHeight(), 1.f - (float) x / getWidth()); if (!mEdgeGlowTop.isFinished()) { mEdgeGlowTop.onRelease(); } invalidate(0, getHeight() - getPaddingBottom() - mEdgeGlowBottom.getMaxHeight(), getWidth(), getHeight()); } } } if (incrementalDeltaY != 0) { // Coming back to 'real' list scrolling if (mScrollY != 0) { mScrollY = 0; invalidate(); } trackMotionScroll(incrementalDeltaY, incrementalDeltaY); mTouchMode = TOUCH_MODE_SCROLL; // We did not scroll the full amount. Treat this essentially like the // start of a new touch scroll final int motionPosition = findClosestMotionRow(y); mMotionCorrection = 0; View motionView = getChildAt(motionPosition - mFirstPosition); mMotionViewOriginalTop = motionView != null ? motionView.getTop() : 0; mMotionY = y + scrollOffsetCorrection; mMotionPosition = motionPosition; } mLastY = y + lastYCorrection + scrollOffsetCorrection; mDirection = newDirection; } } }