List of usage examples for android.view ViewTreeObserver addOnPreDrawListener
public void addOnPreDrawListener(OnPreDrawListener listener)
From source file:ch.gianulli.flashcards.ui.Flashcard.java
/** * @param view Instance of flashcard.xml *//*from w ww .j av a 2s. c o m*/ public Flashcard(View view, OnCardAnsweredListener listener) { mListener = listener; mView = view; mQuestion = (StyledMarkdownView) view.findViewById(R.id.question); mAnswer = (StyledMarkdownView) view.findViewById(R.id.answer); mCardView = (CardView) view.findViewById(R.id.card); mButtonBar = view.findViewById(R.id.button_bar); mCorrectButton = (Button) view.findViewById(R.id.correct_button); mWrongButton = (Button) view.findViewById(R.id.wrong_button); mContext = mView.getContext(); // Load colors int[] attrs = { android.R.attr.textColorSecondary, android.R.attr.textColorPrimary }; TypedArray ta = mView.getContext().obtainStyledAttributes(R.style.AppTheme, attrs); sDeactivatedTextColor = colorToCSSString(ta.getColor(0, 0)); sDefaultTextColor = colorToCSSString(ta.getColor(1, 0)); ta.recycle(); sGreenTextColor = colorToCSSString(ContextCompat.getColor(mContext, R.color.green)); mQuestionColor = sDefaultTextColor; mAnswerColor = sGreenTextColor; // Make question visible mQuestion.setAlpha(1.0f); mAnswer.setAlpha(0.0f); // Setup WebViews WebSettings settings = mQuestion.getSettings(); settings.setDefaultFontSize(mFontSize); settings.setLoadsImagesAutomatically(true); settings.setGeolocationEnabled(false); settings.setAllowFileAccess(false); settings.setDisplayZoomControls(false); settings.setNeedInitialFocus(false); settings.setSupportZoom(false); settings.setSaveFormData(false); settings.setJavaScriptEnabled(true); mQuestion.setHorizontalScrollBarEnabled(false); mQuestion.setVerticalScrollBarEnabled(false); settings = mAnswer.getSettings(); settings.setDefaultFontSize(mFontSize); settings.setLoadsImagesAutomatically(true); settings.setGeolocationEnabled(false); settings.setAllowFileAccess(false); settings.setDisplayZoomControls(false); settings.setNeedInitialFocus(false); settings.setSupportZoom(false); settings.setSaveFormData(false); settings.setJavaScriptEnabled(true); mAnswer.setHorizontalScrollBarEnabled(false); mAnswer.setVerticalScrollBarEnabled(false); // Hack to disable text selection in WebViews mQuestion.setOnLongClickListener(new View.OnLongClickListener() { public boolean onLongClick(View v) { return true; } }); mAnswer.setOnLongClickListener(new View.OnLongClickListener() { public boolean onLongClick(View v) { return true; } }); // Card should "turn" on click final FrameLayout questionLayout = (FrameLayout) view.findViewById(R.id.question_layout); questionLayout.setClickable(true); questionLayout.setOnTouchListener(mTurnCardListener); mQuestion.setOnTouchListener(mTurnCardListener); mAnswer.setOnTouchListener(mTurnCardListener); // Deactivate card when user answers it mCorrectButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { deactivateCard(true); mListener.onCardAnswered(mCard, true); } }); mWrongButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { deactivateCard(false); mListener.onCardAnswered(mCard, false); } }); // Limit card width to 400dp ViewTreeObserver observer = mCardView.getViewTreeObserver(); final int width480dp = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 400, view.getContext().getResources().getDisplayMetrics()); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (mCardView.getWidth() > width480dp) { ViewGroup.LayoutParams layoutParams = mCardView.getLayoutParams(); layoutParams.width = width480dp; mCardView.setLayoutParams(layoutParams); mCardView.requestLayout(); return false; } return true; } }); }
From source file:com.example.android.expandingcells.ExpandingListView.java
/** * This method collapses the view that was clicked and animates all the views * around it to close around the collapsing view. There are several steps required * to do this which are outlined below.//from ww w. j a va 2 s. c o m * * 1. Update the layout parameters of the view clicked so as to minimize its height * to the original collapsed (default) state. * 2. After invoking a layout, the listview will shift all the cells so as to display * them most efficiently. Therefore, during the first predraw pass, the listview * must be offset by some amount such that given the custom bound change upon * collapse, all the cells that need to be on the screen after the layout * are rendered by the listview. * 3. On the second predraw pass, all the items are first returned to their original * location (before the first layout). * 4. The collapsing view's bounds are animated to what the final values should be. * 5. The bounds above the collapsing view are animated downwards while the bounds * below the collapsing view are animated upwards. * 6. The extra text is faded out as its contents become visible throughout the * animation process. */ private void collapseView(final View view) { final ExpandableListItem viewObject = (ExpandableListItem) getItemAtPosition(getPositionForView(view)); /* Store the original top and bottom bounds of all the cells.*/ final int oldTop = view.getTop(); final int oldBottom = view.getBottom(); int childCount = getChildCount(); final HashMap<View, int[]> oldCoordinates = new HashMap<View, int[]>(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); ViewCompat.setHasTransientState(v, true); oldCoordinates.put(v, new int[] { v.getTop(), v.getBottom() }); } /* Update the layout so the extra content becomes invisible.*/ view.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, viewObject.getCollapsedHeight())); /* Add an onPreDraw listener. */ final ViewTreeObserver observer = getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (!mShouldRemoveObserver) { /*Same as for expandingView, the parameters for setSelectionFromTop must * be determined such that the necessary cells of the ListView are rendered * and added to it.*/ mShouldRemoveObserver = true; int newTop = view.getTop(); int newBottom = view.getBottom(); int newHeight = newBottom - newTop; int oldHeight = oldBottom - oldTop; int deltaHeight = oldHeight - newHeight; mTranslate = getCollapsingTopAndBottomTranslation(getPositionForView(view), oldTop, oldBottom, deltaHeight); int currentTop = view.getTop(); int futureTop = oldTop + mTranslate[0]; int firstChildStartTop = getChildAt(0).getTop(); int firstVisiblePosition = getFirstVisiblePosition(); int deltaTop = currentTop - futureTop; int i; int childCount = getChildCount(); for (i = 0; i < childCount; i++) { View v = getChildAt(i); int height = v.getBottom() - Math.max(0, v.getTop()); if (deltaTop - height > 0) { firstVisiblePosition++; deltaTop -= height; } else { break; } } if (i > 0) { firstChildStartTop = 0; } setSelectionFromTop(firstVisiblePosition, firstChildStartTop - deltaTop); requestLayout(); return false; } mShouldRemoveObserver = false; observer.removeOnPreDrawListener(this); int yTranslateTop = mTranslate[0]; int yTranslateBottom = mTranslate[1]; int index = indexOfChild(view); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); int[] old = oldCoordinates.get(v); if (old != null) { /* If the cell was present in the ListView before the collapse and * after the collapse then the bounds are reset to their old values.*/ handleSetTopAndBottom(v, old[0], old[1]); ViewCompat.setHasTransientState(v, false); } else { /* If the cell is present in the ListView after the collapse but * not before the collapse then the bounds are calculated using * the bottom and top translation of the collapsing cell.*/ int delta = i > index ? yTranslateBottom : -yTranslateTop; handleSetTopAndBottom(v, v.getTop() + delta, v.getBottom() + delta); } } /* Animates all the cells present on the screen after the collapse. */ ArrayList<Animator> animations = new ArrayList<Animator>(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); if (v != view) { int old[] = oldCoordinates.get(v); float diff = i > index ? yTranslateBottom : yTranslateTop; if (old != null) { animations.add(getAnimation(v, old[0], old[1], diff, diff)); } else { animations.add(getAnimation(v, v.getTop() - (int) diff, v.getBottom() - (int) diff, diff, diff)); } } } final View expandingLayout = view.findViewById(R.id.expanding_layout); /* Adds animation for collapsing the cell that was clicked. */ int old[] = oldCoordinates.get(view); animations.add(getAnimation(view, old[0], old[1], yTranslateTop, (float) yTranslateBottom)); /* Adds an animation for fading out the extra content. */ animations.add(ObjectAnimator.ofFloat(expandingLayout, "alpha", 1, 0)); /* Disabled the ListView for the duration of the animation.*/ setEnabled(false); setClickable(false); /* Play all the animations created above together at the same time. */ AnimatorSet s = new AnimatorSet(); s.playTogether(animations); s.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { expandingLayout.setVisibility(View.GONE); view.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT)); viewObject.setExpanded(false); setEnabled(true); setClickable(true); /* Note that alpha must be set back to 1 in case this view is reused * by a cell that was expanded, but not yet collapsed, so its state * should persist in an expanded state with the extra content visible.*/ ViewHelper.setAlpha(expandingLayout, 1); if (mOnExpandingListener != null) { mOnExpandingListener.onCollasped(view); } } }); s.start(); return true; } }); }
From source file:com.example.android.expandingcells.ExpandingListView.java
/** * This method expands the view that was clicked and animates all the views * around it to make room for the expanding view. There are several steps required * to do this which are outlined below.// w ww .j av a2 s . co m * * 1. Store the current top and bottom bounds of each visible item in the listview. * 2. Update the layout parameters of the selected view. In the context of this * method, the view should be originally collapsed and set to some custom height. * The layout parameters are updated so as to wrap the content of the additional * text that is to be displayed. * * After invoking a layout to take place, the listview will order all the items * such that there is space for each view. This layout will be independent of what * the bounds of the items were prior to the layout so two pre-draw passes will * be made. This is necessary because after the layout takes place, some views that * were visible before the layout may now be off bounds but a reference to these * views is required so the animation completes as intended. * * 3. The first predraw pass will set the bounds of all the visible items to * their original location before the layout took place and then force another * layout. Since the bounds of the cells cannot be set directly, the method * setSelectionFromTop can be used to achieve a very similar effect. * 4. The expanding view's bounds are animated to what the final values should be * from the original bounds. * 5. The bounds above the expanding view are animated upwards while the bounds * below the expanding view are animated downwards. * 6. The extra text is faded in as its contents become visible throughout the * animation process. * * It is important to note that the listview is disabled during the animation * because the scrolling behaviour is unpredictable if the bounds of the items * within the listview are not constant during the scroll. */ private void expandView(final View view) { final ExpandableListItem viewObject = (ExpandableListItem) getItemAtPosition(getPositionForView(view)); /* Store the original top and bottom bounds of all the cells.*/ final int oldTop = view.getTop(); final int oldBottom = view.getBottom(); final HashMap<View, int[]> oldCoordinates = new HashMap<View, int[]>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); ViewCompat.setHasTransientState(v, true); oldCoordinates.put(v, new int[] { v.getTop(), v.getBottom() }); } /* Update the layout so the extra content becomes visible.*/ final View expandingLayout = view.findViewById(R.id.expanding_layout); if (expandingLayout == null) { throw new IllegalStateException("Layout must have a ExpandingLayout called expanding_layout."); } expandingLayout.setVisibility(View.VISIBLE); /* Add an onPreDraw Listener to the listview. onPreDraw will get invoked after onLayout * and onMeasure have run but before anything has been drawn. This * means that the final post layout properties for all the items have already been * determined, but still have not been rendered onto the screen.*/ final ViewTreeObserver observer = getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { /* Determine if this is the first or second pass.*/ if (!mShouldRemoveObserver) { mShouldRemoveObserver = true; /* Calculate what the parameters should be for setSelectionFromTop. * The ListView must be offset in a way, such that after the animation * takes place, all the cells that remain visible are rendered completely * by the ListView.*/ int newTop = view.getTop(); int newBottom = view.getBottom(); int newHeight = newBottom - newTop; int oldHeight = oldBottom - oldTop; int delta = newHeight - oldHeight; mTranslate = getExpandingTopAndBottomTranslations(getPositionForView(view), oldTop, oldBottom, delta); int currentTop = view.getTop(); int futureTop = oldTop - mTranslate[0]; int firstChildStartTop = getChildAt(0).getTop(); int firstVisiblePosition = getFirstVisiblePosition(); int deltaTop = currentTop - futureTop; int i; int childCount = getChildCount(); for (i = 0; i < childCount; i++) { View v = getChildAt(i); int height = v.getBottom() - Math.max(0, v.getTop()); if (deltaTop - height > 0) { firstVisiblePosition++; deltaTop -= height; } else { break; } } if (i > 0) { firstChildStartTop = 0; } setSelectionFromTop(firstVisiblePosition, firstChildStartTop - deltaTop); /* Request another layout to update the layout parameters of the cells.*/ requestLayout(); /* Return false such that the ListView does not redraw its contents on * this layout but only updates all the parameters associated with its * children.*/ return false; } /* Remove the predraw listener so this method does not keep getting called. */ mShouldRemoveObserver = false; observer.removeOnPreDrawListener(this); int yTranslateTop = mTranslate[0]; int yTranslateBottom = mTranslate[1]; ArrayList<Animator> animations = new ArrayList<Animator>(); int index = indexOfChild(view); /* Loop through all the views that were on the screen before the cell was * expanded. Some cells will still be children of the ListView while * others will not. The cells that remain children of the ListView * simply have their bounds animated appropriately. The cells that are no * longer children of the ListView also have their bounds animated, but * must also be added to a list of views which will be drawn in dispatchDraw.*/ for (View v : oldCoordinates.keySet()) { int[] old = oldCoordinates.get(v); handleSetTopAndBottom(v, old[0], old[1]); if (v == view) { continue; } else if (v.getParent() == null) { mViewsToDraw.add(v); int delta = old[0] < oldTop ? -yTranslateTop : yTranslateBottom; animations.add(getAnimation(v, old[0], old[1], delta, delta)); } else { int i = indexOfChild(v); if (v != view) { int delta = i > index ? yTranslateBottom : -yTranslateTop; animations.add(getAnimation(v, old[0], old[1], delta, delta)); } ViewCompat.setHasTransientState(v, false); } } /* Adds animation for expanding the cell that was clicked. */ int[] old = oldCoordinates.get(view); animations.add(getAnimation(view, old[0], old[1], -yTranslateTop, yTranslateBottom)); /* Adds an animation for fading in the extra content. */ animations.add(ObjectAnimator.ofFloat(view.findViewById(R.id.expanding_layout), "alpha", 0, 1)); /* Disabled the ListView for the duration of the animation.*/ setEnabled(false); setClickable(false); /* Play all the animations created above together at the same time. */ AnimatorSet s = new AnimatorSet(); s.playTogether(animations); s.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { viewObject.setExpanded(true); setEnabled(true); setClickable(true); if (mViewsToDraw.size() > 0) { for (View v : mViewsToDraw) { ViewCompat.setHasTransientState(v, false); } } mViewsToDraw.clear(); if (mOnExpandingListener != null) { mOnExpandingListener.onExpanded(view); } } }); s.start(); return true; } }); }
From source file:net.osmand.plus.views.controls.DynamicListView.java
/** * This method determines whether the hover cell has been shifted far enough * to invoke a cell swap. If so, then the respective cell swap candidate is * determined and the data set is changed. Upon posting a notification of the * data set change, a layout is invoked to place the cells in the right place. * Using a ViewTreeObserver and a corresponding OnPreDrawListener, we can * offset the cell being swapped to where it previously was and then animate it to * its new position.//from w w w . j ava2 s . c o m */ private void handleCellSwitch() { final int deltaY = mLastEventY - mDownY; final int deltaYTotal = mHoverCellOriginalBounds.top + mTotalOffset + deltaY; View belowView = getViewForID(mBelowItemId); View mobileView = getViewForID(mMobileItemId); View aboveView = getViewForID(mAboveItemId); boolean isBelow = (belowView != null) && (deltaYTotal > belowView.getTop()); boolean isAbove = (aboveView != null) && (deltaYTotal < aboveView.getTop()); if (isBelow || isAbove) { final long switchItemID = isBelow ? mBelowItemId : mAboveItemId; View switchView = isBelow ? belowView : aboveView; final int originalItem = getPositionForView(mobileView) - getHeaderViewsCount(); final int switchItem = getPositionForView(switchView) - getHeaderViewsCount(); swapElements(originalItem, switchItem); getStableAdapter().notifyDataSetChanged(); mDownY = mLastEventY; final int switchViewStartTop = switchView.getTop(); if (android.os.Build.VERSION.SDK_INT <= android.os.Build.VERSION_CODES.KITKAT) { mobileView.setVisibility(View.VISIBLE); switchView.setVisibility(View.INVISIBLE); } updateNeighborViewsForID(mMobileItemId); final ViewTreeObserver observer = getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { observer.removeOnPreDrawListener(this); View switchView = getViewForID(switchItemID); mTotalOffset += deltaY; int switchViewNewTop = switchView.getTop(); int delta = switchViewStartTop - switchViewNewTop; ViewCompat.setTranslationY(switchView, delta); if (android.os.Build.VERSION.SDK_INT < 12) { ViewCompat.animate(switchView).translationY(0).setDuration(MOVE_DURATION); } else { ObjectAnimator animator = ObjectAnimator.ofFloat(switchView, View.TRANSLATION_Y, 0); animator.setDuration(MOVE_DURATION); animator.start(); } return true; } }); } }
From source file:com.spatialnetworks.fulcrum.widget.DynamicListView.java
/** * This method determines whether the hover cell has been shifted far enough * to invoke a cell swap. If so, then the respective cell swap candidate is * determined and the data set is changed. Upon posting a notification of the * data set change, a layout is invoked to place the cells in the right place. * Using a ViewTreeObserver and a corresponding OnPreDrawListener, we can * offset the cell being swapped to where it previously was and then animate it to * its new position./* www . j a va 2s .c o m*/ */ private void handleCellSwitch() { final int deltaY = mLastEventY - mDownY; int deltaYTotal = mHoverCellOriginalBounds.top + mTotalOffset + deltaY; View belowView = getViewForID(mBelowItemId); View mobileView = getViewForID(mMobileItemId); View aboveView = getViewForID(mAboveItemId); boolean isBelow = (belowView != null) && (deltaYTotal > belowView.getTop()); boolean isAbove = (aboveView != null) && (deltaYTotal < aboveView.getTop()); if (isBelow || isAbove) { final long switchItemID = isBelow ? mBelowItemId : mAboveItemId; View switchView = isBelow ? belowView : aboveView; final int originalItem = getPositionForView(mobileView); swapElements(originalItem, getPositionForView(switchView)); // Josh mobileView.setVisibility(VISIBLE); ((BaseAdapter) getAdapter()).notifyDataSetChanged(); mDownY = mLastEventY; final int switchViewStartTop = switchView.getTop(); // Josh // mobileView.setVisibility(View.VISIBLE); // switchView.setVisibility(View.INVISIBLE); updateNeighborViewsForID(mMobileItemId); final ViewTreeObserver observer = getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { observer.removeOnPreDrawListener(this); // Josh View mobileView = getViewForID(mMobileItemId); if (mobileView != null) { mobileView.setVisibility(INVISIBLE); } View switchView = getViewForID(switchItemID); mTotalOffset += deltaY; int switchViewNewTop = switchView.getTop(); int delta = switchViewStartTop - switchViewNewTop; switchView.setTranslationY(delta); ObjectAnimator animator = ObjectAnimator.ofFloat(switchView, View.TRANSLATION_Y, 0); animator.setDuration(MOVE_DURATION); animator.start(); return true; } }); } }
From source file:com.androidinspain.deskclock.timer.TimerFragment.java
/** * @param toView one of {@link #mTimersView} or {@link #mCreateTimerView} * @param timerToRemove the timer to be removed during the animation; {@code null} if no timer * should be removed/*from w w w . j a va2 s . c o m*/ * @param animateDown {@code true} if the views should animate upwards, otherwise downwards */ private void animateToView(final View toView, final Timer timerToRemove, final boolean animateDown) { if (mCurrentView == toView) { return; } final boolean toTimers = toView == mTimersView; if (toTimers) { mTimersView.setVisibility(VISIBLE); } else { mCreateTimerView.setVisibility(VISIBLE); } // Avoid double-taps by enabling/disabling the set of buttons active on the new view. updateFab(BUTTONS_DISABLE); final long animationDuration = UiDataModel.getUiDataModel().getLongAnimationDuration(); final ViewTreeObserver viewTreeObserver = toView.getViewTreeObserver(); viewTreeObserver.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (viewTreeObserver.isAlive()) { viewTreeObserver.removeOnPreDrawListener(this); } final View view = mTimersView.findViewById(com.androidinspain.deskclock.R.id.timer_time); final float distanceY = view != null ? view.getHeight() + view.getY() : 0; final float translationDistance = animateDown ? distanceY : -distanceY; toView.setTranslationY(-translationDistance); mCurrentView.setTranslationY(0f); toView.setAlpha(0f); mCurrentView.setAlpha(1f); final Animator translateCurrent = ObjectAnimator.ofFloat(mCurrentView, TRANSLATION_Y, translationDistance); final Animator translateNew = ObjectAnimator.ofFloat(toView, TRANSLATION_Y, 0f); final AnimatorSet translationAnimatorSet = new AnimatorSet(); translationAnimatorSet.playTogether(translateCurrent, translateNew); translationAnimatorSet.setDuration(animationDuration); translationAnimatorSet.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN); final Animator fadeOutAnimator = ObjectAnimator.ofFloat(mCurrentView, ALPHA, 0f); fadeOutAnimator.setDuration(animationDuration / 2); fadeOutAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { super.onAnimationStart(animation); // The fade-out animation and fab-shrinking animation should run together. updateFab(FAB_AND_BUTTONS_SHRINK); } @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); if (toTimers) { showTimersView(FAB_AND_BUTTONS_EXPAND); // Reset the state of the create view. mCreateTimerView.reset(); } else { showCreateTimerView(FAB_AND_BUTTONS_EXPAND); } if (timerToRemove != null) { DataModel.getDataModel().removeTimer(timerToRemove); Events.sendTimerEvent(com.androidinspain.deskclock.R.string.action_delete, com.androidinspain.deskclock.R.string.label_deskclock); } // Update the fab and button states now that the correct view is visible and // before the animation to expand the fab and buttons starts. updateFab(FAB_AND_BUTTONS_IMMEDIATE); } }); final Animator fadeInAnimator = ObjectAnimator.ofFloat(toView, ALPHA, 1f); fadeInAnimator.setDuration(animationDuration / 2); fadeInAnimator.setStartDelay(animationDuration / 2); final AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(fadeOutAnimator, fadeInAnimator, translationAnimatorSet); animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mTimersView.setTranslationY(0f); mCreateTimerView.setTranslationY(0f); mTimersView.setAlpha(1f); mCreateTimerView.setAlpha(1f); } }); animatorSet.start(); return true; } }); }
From source file:paulscode.android.mupen64plusae.GalleryActivity.java
@Override public void onResume() { super.onResume(); //mRefreshNeeded will be set to true whenever a game is launched if (mRefreshNeeded) { mRefreshNeeded = false;//ww w. j ava 2s .c o m refreshGrid(); mGameSidebar.setVisibility(View.GONE); mDrawerList.setVisibility(View.VISIBLE); //Close the drawer without an animation final View view = mDrawerLayout.getChildAt(mDrawerLayout.getChildCount() - 1); final ViewTreeObserver vto = view.getViewTreeObserver(); vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { final DrawerLayout.LayoutParams lp = new DrawerLayout.LayoutParams(view.getWidth(), view.getHeight()); lp.gravity = GravityCompat.START; view.setLayoutParams(lp); view.setLeft(-view.getMeasuredWidth()); view.getViewTreeObserver().removeOnPreDrawListener(this); return true; } }); } }
From source file:com.velli.passwordmanager.FragmentPasswordDetails.java
@SuppressLint("NewApi") @Override//w ww. j a v a 2 s.co m public View onCreateView(LayoutInflater inflater, ViewGroup root, Bundle savedInstanceState) { final View v; final Bundle bundle = savedInstanceState != null ? savedInstanceState : getArguments(); if (bundle != null) { mIsPassword = bundle.getInt(BUNDLE_KEY_TYPE, TYPE_PASSWORD) == TYPE_PASSWORD; mEntryId = bundle.getInt(BUNDLE_KEY_ENTRY_ID, -1); } v = inflater.inflate( mIsPassword ? R.layout.fragment_layout_details : R.layout.fragment_layout_details_credit_card, root, false); mBottomToolbar = (Toolbar) v.findViewById(R.id.details_view_bottom_toolbar); mBottomBarDivider = v.findViewById(R.id.details_view_toolbar_divider); mTitle = (RobotoTextView) v.findViewById(R.id.details_view_description); mLoginType = (RobotoTextView) v.findViewById(R.id.details_view_login_type); mUrl = (RobotoTextView) v.findViewById(R.id.details_view_url); mUrlTitle = (RobotoTextView) v.findViewById(R.id.details_view_url_title); mUsername = (RobotoTextView) v.findViewById(R.id.details_view_username); mUsernameTitle = (RobotoTextView) v.findViewById(R.id.details_view_username_title); mPassword = (RobotoTextView) v.findViewById(R.id.details_view_password); mNotes = (RobotoTextView) v.findViewById(R.id.details_view_notes); mNotesTitle = (RobotoTextView) v.findViewById(R.id.details_view_notes_title); mGroup = (RobotoTextView) v.findViewById(R.id.details_view_group); mGroupTitle = (RobotoTextView) v.findViewById(R.id.details_view_group_title); mLoginIcon = (ImageView) v.findViewById(R.id.details_view_login_icon); mInfoContainer = (LinearLayout) v.findViewById(R.id.details_info_container); mCardType = (RobotoTextView) v.findViewById(R.id.details_view_card_type); mCardNumber = (RobotoTextView) v.findViewById(R.id.details_view_card_number); mCardExpDate = (RobotoTextView) v.findViewById(R.id.details_view_card_exp_date); mCardCSV = (RobotoTextView) v.findViewById(R.id.details_view_card_csv); mWifiSecurity = (RobotoTextView) v.findViewById(R.id.details_view_wifi_security); mWifiSecurityTitle = (RobotoTextView) v.findViewById(R.id.details_view_wifi_security_title); mWifiSSID = (RobotoTextView) v.findViewById(R.id.details_view_wifi_ssid); mWifiSSIDTitle = (RobotoTextView) v.findViewById(R.id.details_view_wifi_ssid_title); mViewsSet = true; if (mEntry != null) { onGetPassword(mEntry); } if (bundle != null && !mAnimated) { final int titleY = bundle.getInt(BUNDLE_KEY_TITLE_Y_POS, -1); final int titleX = bundle.getInt(BUNDLE_KEY_TITLE_X_POS, -1); final int iconY = bundle.getInt(BUNDLE_KEY_ICON_Y_POS, -1); final int iconX = bundle.getInt(BUNDLE_KEY_ICON_X_POS, -1); mIsGridLayoutManager = bundle.getBoolean(BUNDLE_KEY_IS_GRID_LAYOUT_MANAGER, false); if (titleY != -1 && titleX != -1 && iconY != -1 && iconX != -1) { final ViewTreeObserver viewTreeObserver = getActivity().getWindow().getDecorView() .getViewTreeObserver(); viewTreeObserver.addOnPreDrawListener(new OnPreDrawListener() { @SuppressLint("NewApi") @Override public boolean onPreDraw() { if (viewTreeObserver.isAlive()) { viewTreeObserver.removeOnPreDrawListener(this); } if (mTitleAnimator == null) { mTitleAnimator = new DetailsTitleAnimator(); } mTitleAnimator.animate(titleY, titleX, iconY, iconX, v.getHeight()); return false; } }); } else if (mBottomToolbar != null) { mBottomToolbar.setVisibility(View.VISIBLE); } } else if (mBottomToolbar != null) { mBottomToolbar.setVisibility(View.VISIBLE); } return v; }
From source file:graphic.expand_graphic.ExpandingListView.java
/** * This method collapses the view that was clicked and animates all the * views around it to close around the collapsing view. There are several * steps required to do this which are outlined below. * <p/>//from w w w . ja v a 2 s .c o m * 1. Update the layout parameters of the view clicked so as to minimize its * height to the original collapsed (default) state. 2. After invoking a * layout, the listview will shift all the cells so as to display them most * efficiently. Therefore, during the first predraw pass, the listview must * be offset by some amount such that given the custom bound change upon * collapse, all the cells that need to be on the screen after the layout * are rendered by the listview. 3. On the second predraw pass, all the * items are first returned to their original location (before the first * layout). 4. The collapsing view's bounds are animated to what the final * values should be. 5. The bounds above the collapsing view are animated * downwards while the bounds below the collapsing view are animated * upwards. 6. The extra text is faded out as its contents become visible * throughout the animation process. */ private void collapseView(final View view) { /* Store the original top and bottom bounds of all the cells. */ final int oldTop = view.getTop(); final int oldBottom = view.getBottom(); final HashMap<View, int[]> oldCoordinates = new HashMap<View, int[]>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); ViewCompat.setHasTransientState(v, true); oldCoordinates.put(v, new int[] { v.getTop(), v.getBottom() }); } /* Update the layout so the extra content becomes invisible. */ view.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, viewObject.mCollapsedHeight)); /* Add an onPreDraw listener. */ final ViewTreeObserver observer = getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (!mShouldRemoveObserver) { /* * Same as for expandingView, the parameters for * setSelectionFromTop must be determined such that the * necessary cells of the ListView are rendered and added to * it. */ mShouldRemoveObserver = true; int newTop = view.getTop(); int newBottom = view.getBottom(); int newHeight = newBottom - newTop; int oldHeight = oldBottom - oldTop; int deltaHeight = oldHeight - newHeight; mTranslate = getTopAndBottomTranslations(oldTop, oldBottom, deltaHeight, false); int currentTop = view.getTop(); int futureTop = oldTop + mTranslate[0]; int firstChildStartTop = getChildAt(0).getTop(); int firstVisiblePosition = getFirstVisiblePosition(); int deltaTop = currentTop - futureTop; int i; int childCount = getChildCount(); for (i = 0; i < childCount; i++) { View v = getChildAt(i); int height = v.getBottom() - Math.max(0, v.getTop()); if (deltaTop - height > 0) { firstVisiblePosition++; deltaTop -= height; } else { break; } } if (i > 0) { firstChildStartTop = 0; } setSelectionFromTop(firstVisiblePosition, firstChildStartTop - deltaTop); requestLayout(); return false; } mShouldRemoveObserver = false; observer.removeOnPreDrawListener(this); int yTranslateTop = mTranslate[0]; int yTranslateBottom = mTranslate[1]; int index = indexOfChild(view); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); int[] old = oldCoordinates.get(v); if (old != null) { /* * If the cell was present in the ListView before the * collapse and after the collapse then the bounds are * reset to their old values. */ v.setTop(old[0]); v.setBottom(old[1]); ViewCompat.setHasTransientState(v, false); } else { /* * If the cell is present in the ListView after the * collapse but not before the collapse then the bounds * are calculated using the bottom and top translation * of the collapsing cell. */ int delta = i > index ? yTranslateBottom : -yTranslateTop; v.setTop(v.getTop() + delta); v.setBottom(v.getBottom() + delta); } } final View expandingLayout = view.findViewById(R.id.expanding_layout); /* * Animates all the cells present on the screen after the * collapse. */ ArrayList<Animator> animations = new ArrayList<Animator>(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); if (v != view) { float diff = i > index ? -yTranslateBottom : yTranslateTop; animations.add(getAnimation(v, diff, diff)); } } /* Adds animation for collapsing the cell that was clicked. */ animations.add(getAnimation(view, yTranslateTop, -yTranslateBottom)); /* Adds an animation for fading out the extra content. */ animations.add(ObjectAnimator.ofFloat(expandingLayout, View.ALPHA, 1, 0)); /* Disabled the ListView for the duration of the animation. */ setEnabled(false); setClickable(false); /* * Play all the animations created above together at the same * time. */ AnimatorSet s = new AnimatorSet(); s.playTogether(animations); s.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { expandingLayout.setVisibility(View.GONE); view.setLayoutParams( new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); viewObject.setExpanded(false); setEnabled(true); setClickable(true); /* * Note that alpha must be set back to 1 in case this * view is reused by a cell that was expanded, but not * yet collapsed, so its state should persist in an * expanded state with the extra content visible. */ expandingLayout.setAlpha(1); } }); s.start(); return true; } }); }
From source file:graphic.expand_graphic.ExpandingListView.java
/** * This method expands the view that was clicked and animates all the views * around it to make room for the expanding view. There are several steps * required to do this which are outlined below. * <p/>//from ww w . j a v a2 s.c om * 1. Store the current top and bottom bounds of each visible item in the * listview. 2. Update the layout parameters of the selected view. In the * context of this method, the view should be originally collapsed and set * to some custom height. The layout parameters are updated so as to wrap * the content of the additional text that is to be displayed. * <p/> * After invoking a layout to take place, the listview will order all the * items such that there is space for each view. This layout will be * independent of what the bounds of the items were prior to the layout so * two pre-draw passes will be made. This is necessary because after the * layout takes place, some views that were visible before the layout may * now be off bounds but a reference to these views is required so the * animation completes as intended. * <p/> * 3. The first predraw pass will set the bounds of all the visible items to * their original location before the layout took place and then force * another layout. Since the bounds of the cells cannot be set directly, the * method setSelectionFromTop can be used to achieve a very similar effect. * 4. The expanding view's bounds are animated to what the final values * should be from the original bounds. 5. The bounds above the expanding * view are animated upwards while the bounds below the expanding view are * animated downwards. 6. The extra text is faded in as its contents become * visible throughout the animation process. * <p/> * It is important to note that the listview is disabled during the * animation because the scrolling behaviour is unpredictable if the bounds * of the items within the listview are not constant during the scroll. */ private void expandView(final View view) { /* Store the original top and bottom bounds of all the cells. */ final int oldTop = view.getTop(); final int oldBottom = view.getBottom(); final HashMap<View, int[]> oldCoordinates = new HashMap<View, int[]>(); int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View v = getChildAt(i); ViewCompat.setHasTransientState(v, true); oldCoordinates.put(v, new int[] { v.getTop(), v.getBottom() }); } /* Update the layout so the extra content becomes visible. */ final View expandingLayout = view.findViewById(R.id.expanding_layout); expandingLayout.setVisibility(View.VISIBLE); /* * Add an onPreDraw Listener to the listview. onPreDraw will get invoked * after onLayout and onMeasure have run but before anything has been * drawn. This means that the final post layout properties for all the * items have already been determined, but still have not been rendered * onto the screen. */ final ViewTreeObserver observer = getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { /* Determine if this is the first or second pass. */ if (!mShouldRemoveObserver) { mShouldRemoveObserver = true; /* * Calculate what the parameters should be for * setSelectionFromTop. The ListView must be offset in a * way, such that after the animation takes place, all the * cells that remain visible are rendered completely by the * ListView. */ int newTop = view.getTop(); int newBottom = view.getBottom(); int newHeight = newBottom - newTop; int oldHeight = oldBottom - oldTop; int delta = newHeight - oldHeight; mTranslate = getTopAndBottomTranslations(oldTop, oldBottom, delta, true); int currentTop = view.getTop(); int futureTop = oldTop - mTranslate[0]; int firstChildStartTop = getChildAt(0).getTop(); int firstVisiblePosition = getFirstVisiblePosition(); int deltaTop = currentTop - futureTop; int i; int childCount = getChildCount(); for (i = 0; i < childCount; i++) { View v = getChildAt(i); int height = v.getBottom() - Math.max(0, v.getTop()); if (deltaTop - height > 0) { firstVisiblePosition++; deltaTop -= height; } else { break; } } if (i > 0) { firstChildStartTop = 0; } setSelectionFromTop(firstVisiblePosition, firstChildStartTop - deltaTop); /* * Request another layout to update the layout parameters of * the cells. */ requestLayout(); /* * Return false such that the ListView does not redraw its * contents on this layout but only updates all the * parameters associated with its children. */ return false; } /* * Remove the predraw listener so this method does not keep * getting called. */ mShouldRemoveObserver = false; observer.removeOnPreDrawListener(this); int yTranslateTop = mTranslate[0]; int yTranslateBottom = mTranslate[1]; ArrayList<Animator> animations = new ArrayList<Animator>(); int index = indexOfChild(view); /* * Loop through all the views that were on the screen before the * cell was expanded. Some cells will still be children of the * ListView while others will not. The cells that remain * children of the ListView simply have their bounds animated * appropriately. The cells that are no longer children of the * ListView also have their bounds animated, but must also be * added to a list of views which will be drawn in dispatchDraw. */ for (View v : oldCoordinates.keySet()) { int[] old = oldCoordinates.get(v); v.setTop(old[0]); v.setBottom(old[1]); if (v.getParent() == null) { mViewsToDraw.add(v); int delta = old[0] < oldTop ? -yTranslateTop : yTranslateBottom; animations.add(getAnimation(v, delta, delta)); } else { int i = indexOfChild(v); if (v != view) { int delta = i > index ? yTranslateBottom : -yTranslateTop; animations.add(getAnimation(v, delta, delta)); } ViewCompat.setHasTransientState(v, false); } } /* Adds animation for expanding the cell that was clicked. */ animations.add(getAnimation(view, -yTranslateTop, yTranslateBottom)); /* Adds an animation for fading in the extra content. */ animations.add(ObjectAnimator.ofFloat(view.findViewById(R.id.expanding_layout), View.ALPHA, 0, 1)); /* Disabled the ListView for the duration of the animation. */ setEnabled(false); setClickable(false); /* * Play all the animations created above together at the same * time. */ AnimatorSet s = new AnimatorSet(); s.playTogether(animations); s.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { viewObject.setExpanded(true); setEnabled(true); setClickable(true); if (mViewsToDraw.size() > 0) { for (View v : mViewsToDraw) { ViewCompat.setHasTransientState(v, false); } } mViewsToDraw.clear(); } }); s.start(); return true; } }); }