List of usage examples for android.animation AnimatorSet AnimatorSet
public AnimatorSet()
From source file:org.getlantern.firetweet.fragment.support.AccountsDashboardFragment.java
private void onAccountSelected(AccountProfileImageViewHolder holder, final ParcelableAccount account) { if (mSwitchAccountAnimationPlaying) return;//www .j av a 2 s . c o m final ImageView snapshotView = mFloatingProfileImageSnapshotView; final ShapedImageView profileImageView = mAccountProfileImageView; final ShapedImageView clickedImageView = holder.getIconView(); // Reset snapshot view position snapshotView.setPivotX(0); snapshotView.setPivotY(0); snapshotView.setTranslationX(0); snapshotView.setTranslationY(0); final Matrix matrix = new Matrix(); final RectF sourceBounds = new RectF(), destBounds = new RectF(), snapshotBounds = new RectF(); getLocationOnScreen(clickedImageView, sourceBounds); getLocationOnScreen(profileImageView, destBounds); getLocationOnScreen(snapshotView, snapshotBounds); final float finalScale = destBounds.width() / sourceBounds.width(); final Bitmap snapshotBitmap = TransitionUtils.createViewBitmap(clickedImageView, matrix, new RectF(0, 0, sourceBounds.width(), sourceBounds.height())); final ViewGroup.LayoutParams lp = snapshotView.getLayoutParams(); lp.width = clickedImageView.getWidth(); lp.height = clickedImageView.getHeight(); snapshotView.setLayoutParams(lp); // Copied from MaterialNavigationDrawer: https://github.com/madcyph3r/AdvancedMaterialDrawer/ AnimatorSet set = new AnimatorSet(); set.play(ObjectAnimator.ofFloat(snapshotView, View.TRANSLATION_X, sourceBounds.left - snapshotBounds.left, destBounds.left - snapshotBounds.left)) .with(ObjectAnimator.ofFloat(snapshotView, View.TRANSLATION_Y, sourceBounds.top - snapshotBounds.top, destBounds.top - snapshotBounds.top)) .with(ObjectAnimator.ofFloat(snapshotView, View.SCALE_X, 1, finalScale)) .with(ObjectAnimator.ofFloat(snapshotView, View.SCALE_Y, 1, finalScale)) .with(ObjectAnimator.ofFloat(profileImageView, View.ALPHA, 1, 0)) .with(ObjectAnimator.ofFloat(clickedImageView, View.SCALE_X, 0, 1)) .with(ObjectAnimator.ofFloat(clickedImageView, View.SCALE_Y, 0, 1)); final long animationTransition = 400; set.setDuration(animationTransition); set.setInterpolator(new DecelerateInterpolator()); set.addListener(new AnimatorListener() { private Drawable clickedDrawable; private int[] clickedColors; @Override public void onAnimationStart(Animator animation) { snapshotView.setVisibility(View.VISIBLE); snapshotView.setImageBitmap(snapshotBitmap); final Drawable profileDrawable = profileImageView.getDrawable(); clickedDrawable = clickedImageView.getDrawable(); clickedColors = clickedImageView.getBorderColors(); final ParcelableAccount oldSelectedAccount = mAccountsAdapter.getSelectedAccount(); mImageLoader.displayDashboardProfileImage(clickedImageView, oldSelectedAccount.profile_image_url, profileDrawable); // mImageLoader.displayDashboardProfileImage(profileImageView, // account.profile_image_url, clickedDrawable); clickedImageView.setBorderColors(profileImageView.getBorderColors()); mSwitchAccountAnimationPlaying = true; } @Override public void onAnimationEnd(Animator animation) { finishAnimation(); } private void finishAnimation() { final Editor editor = mPreferences.edit(); editor.putLong(KEY_DEFAULT_ACCOUNT_ID, account.account_id); editor.apply(); mAccountsAdapter.setSelectedAccountId(account.account_id); mAccountOptionsAdapter.setSelectedAccount(account); updateAccountOptionsSeparatorLabel(clickedDrawable); snapshotView.setVisibility(View.INVISIBLE); snapshotView.setImageDrawable(null); profileImageView.setImageDrawable(clickedDrawable); profileImageView.setBorderColors(clickedColors); profileImageView.setAlpha(1f); clickedImageView.setScaleX(1); clickedImageView.setScaleY(1); clickedImageView.setAlpha(1f); mSwitchAccountAnimationPlaying = false; } @Override public void onAnimationCancel(Animator animation) { finishAnimation(); } @Override public void onAnimationRepeat(Animator animation) { } }); set.start(); }
From source file:me.zchang.onchart.ui.MainActivity.java
private void popupThisWeek(int weekNum) { popupWeekText.setText(String.format(getString(R.string.weekday_week), weekNum)); popupWeekText.setVisibility(View.VISIBLE); popupWeekText.setScaleX(.3f);//from ww w.j av a 2 s . c o m popupWeekText.setScaleY(.3f); popupWeekText.setAlpha(.7f); Animator scaleAnimator = ObjectAnimator.ofFloat(popupWeekText, "scaleX", 1f); Animator scaleAnimator2 = ObjectAnimator.ofFloat(popupWeekText, "scaleY", 1f); scaleAnimator.setDuration(150); scaleAnimator2.setDuration(150); Animator alphaAnimator = ObjectAnimator.ofFloat(popupWeekText, "alpha", 0f); alphaAnimator.setStartDelay(120); alphaAnimator.setDuration(500); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(scaleAnimator).with(scaleAnimator2).with(alphaAnimator); animatorSet.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { popupWeekText.setVisibility(View.GONE); } @Override public void onAnimationCancel(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } }); animatorSet.start(); }
From source file:com.pitchedapps.primenumbercalculator.Calculator.java
License:asdf
private void onResult(final String result) { // Calculate the values needed to perform the scale and translation animations, // accounting for how the scale will affect the final position of the text. final float resultScale = mInputEditText.getVariableTextSize(result) / mResultEditText.getTextSize(); final float resultTranslationX = (1.0f - resultScale) * (mResultEditText.getWidth() / 2.0f - mResultEditText.getPaddingEnd()); final float resultTranslationY = (1.0f - resultScale) * //TODO delete unnecessary lines for animation (mResultEditText.getHeight() / 2.0f - mResultEditText.getPaddingBottom()) + (mInputEditText.getBottom() - mResultEditText.getBottom()) + (mResultEditText.getPaddingBottom() - mInputEditText.getPaddingBottom()); final float inputTranslationY = -mInputEditText.getBottom(); // Use a value animator to fade to the final text color over the course of the animation. final int resultTextColor = mResultEditText.getCurrentTextColor(); final int inputEditText = mInputEditText.getCurrentTextColor(); final ValueAnimator textColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), resultTextColor, inputEditText);/* w ww . j a v a2 s. c o m*/ textColorAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { mResultEditText.setTextColor((int) valueAnimator.getAnimatedValue()); } }); final AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(textColorAnimator, ObjectAnimator.ofFloat(mResultEditText, View.SCALE_X, resultScale), ObjectAnimator.ofFloat(mResultEditText, View.SCALE_Y, resultScale), ObjectAnimator.ofFloat(mResultEditText, View.TRANSLATION_X, resultTranslationX), ObjectAnimator.ofFloat(mResultEditText, View.TRANSLATION_Y, resultTranslationY), ObjectAnimator.ofFloat(mInputEditText, View.TRANSLATION_Y, inputTranslationY)); animatorSet.setDuration(getResources().getInteger(android.R.integer.config_longAnimTime)); animatorSet.setInterpolator(new AccelerateDecelerateInterpolator()); animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { mResultEditText.setText(result); } @Override public void onAnimationEnd(Animator animation) { // Reset all of the values modified during the animation. mResultEditText.setTextColor(resultTextColor); mResultEditText.setScaleX(1.0f); mResultEditText.setScaleY(1.0f); mResultEditText.setTranslationX(0.0f); mResultEditText.setTranslationY(0.0f); mInputEditText.setTranslationY(0.0f); // Finally update the input to use the current result. mInputEditText.setText(result); //TODO figure out how to reset after equal sign without changing input text mResultEditText.getEditableText().clear(); setState(CalculatorState.RESULT); mCurrentAnimator = null; } }); mCurrentAnimator = animatorSet; animatorSet.start(); }
From source file:com.stasbar.knowyourself.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 av a 2s.co m*/ private void animateToView(View toView, final Timer timerToRemove) { if (mCurrentView == toView) { return; } final boolean toTimers = toView == mTimersView; final long duration = UiDataModel.getUiDataModel().getShortAnimationDuration(); final Animator rotateFrom = ObjectAnimator.ofFloat(mCurrentView, SCALE_X, 1, 0); rotateFrom.setDuration(duration); rotateFrom.setInterpolator(new DecelerateInterpolator()); rotateFrom.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (timerToRemove != null) { DataModel.getDataModel().removeTimer(timerToRemove); ((MainActivity) getActivity()).stopActivity(activityItem, timerToRemove); } mCurrentView.setScaleX(1); if (toTimers) { showTimersView(); } else { showCreateTimerView(); } } }); final Animator rotateTo = ObjectAnimator.ofFloat(toView, SCALE_X, 0, 1); rotateTo.setDuration(duration); rotateTo.setInterpolator(new AccelerateInterpolator()); final AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(rotateFrom).before(rotateTo); animatorSet.start(); }
From source file:com.wizardsofm.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 . jav a2s .co m*/ */ private void animateToView(View toView, final Timer timerToRemove) { if (mCurrentView == toView) { throw new IllegalStateException("toView is already the current view"); } final boolean toTimers = toView == mTimersView; // Avoid double-taps by enabling/disabling the set of buttons active on the new view. updateFab(UpdateType.DISABLE_BUTTONS); final long duration = UiDataModel.getUiDataModel().getShortAnimationDuration(); final Animator rotateFrom = ObjectAnimator.ofFloat(mCurrentView, SCALE_X, 1, 0); rotateFrom.setDuration(duration); rotateFrom.setInterpolator(new DecelerateInterpolator()); rotateFrom.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (timerToRemove != null) { DataModel.getDataModel().removeTimer(timerToRemove); Events.sendTimerEvent(com.wizardsofm.deskclock.R.string.action_delete, com.wizardsofm.deskclock.R.string.label_deskclock); } mCurrentView.setScaleX(1); if (toTimers) { showTimersView(UpdateType.FAB_AND_BUTTONS_SHRINK_AND_EXPAND); } else { showCreateTimerView(UpdateType.FAB_AND_BUTTONS_SHRINK_AND_EXPAND); } } }); final Animator rotateTo = ObjectAnimator.ofFloat(toView, SCALE_X, 0, 1); rotateTo.setDuration(duration); rotateTo.setInterpolator(new AccelerateInterpolator()); final AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(rotateFrom).before(rotateTo); animatorSet.start(); }
From source file:com.androidinspain.deskclock.alarms.dataadapter.ExpandedAlarmViewHolder.java
private Animator createExpandingAnimator(AlarmItemViewHolder oldHolder, long duration) { final View oldView = oldHolder.itemView; final View newView = itemView; final Animator boundsAnimator = AnimatorUtils.getBoundsAnimator(newView, oldView, newView); boundsAnimator.setDuration(duration); boundsAnimator.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN); final Animator backgroundAnimator = ObjectAnimator.ofPropertyValuesHolder(newView, PropertyValuesHolder.ofInt(AnimatorUtils.BACKGROUND_ALPHA, 0, 255)); backgroundAnimator.setDuration(duration); final View oldArrow = oldHolder.arrow; final Rect oldArrowRect = new Rect(0, 0, oldArrow.getWidth(), oldArrow.getHeight()); final Rect newArrowRect = new Rect(0, 0, arrow.getWidth(), arrow.getHeight()); ((ViewGroup) newView).offsetDescendantRectToMyCoords(arrow, newArrowRect); ((ViewGroup) oldView).offsetDescendantRectToMyCoords(oldArrow, oldArrowRect); final float arrowTranslationY = oldArrowRect.bottom - newArrowRect.bottom; arrow.setTranslationY(arrowTranslationY); arrow.setVisibility(View.VISIBLE); clock.setVisibility(View.VISIBLE); onOff.setVisibility(View.VISIBLE); final long longDuration = (long) (duration * ANIM_LONG_DURATION_MULTIPLIER); final Animator repeatAnimation = ObjectAnimator.ofFloat(repeat, View.ALPHA, 1f).setDuration(longDuration); final Animator repeatDaysAnimation = ObjectAnimator.ofFloat(repeatDays, View.ALPHA, 1f) .setDuration(longDuration);//from w w w . j av a 2 s. c o m final Animator ringtoneAnimation = ObjectAnimator.ofFloat(ringtone, View.ALPHA, 1f) .setDuration(longDuration); final Animator dismissAnimation = ObjectAnimator.ofFloat(preemptiveDismissButton, View.ALPHA, 1f) .setDuration(longDuration); final Animator vibrateAnimation = ObjectAnimator.ofFloat(vibrate, View.ALPHA, 1f).setDuration(longDuration); final Animator editLabelAnimation = ObjectAnimator.ofFloat(editLabel, View.ALPHA, 1f) .setDuration(longDuration); final Animator hairLineAnimation = ObjectAnimator.ofFloat(hairLine, View.ALPHA, 1f) .setDuration(longDuration); final Animator deleteAnimation = ObjectAnimator.ofFloat(delete, View.ALPHA, 1f).setDuration(longDuration); final Animator arrowAnimation = ObjectAnimator.ofFloat(arrow, View.TRANSLATION_Y, 0f).setDuration(duration); arrowAnimation.setInterpolator(AnimatorUtils.INTERPOLATOR_FAST_OUT_SLOW_IN); // Set the stagger delays; delay the first by the amount of time it takes for the collapse // to complete, then stagger the expansion with the remaining time. long startDelay = (long) (duration * ANIM_STANDARD_DELAY_MULTIPLIER); final int numberOfItems = countNumberOfItems(); final long delayIncrement = (long) (duration * ANIM_SHORT_DELAY_INCREMENT_MULTIPLIER) / (numberOfItems - 1); repeatAnimation.setStartDelay(startDelay); startDelay += delayIncrement; final boolean daysVisible = repeatDays.getVisibility() == View.VISIBLE; if (daysVisible) { repeatDaysAnimation.setStartDelay(startDelay); startDelay += delayIncrement; } ringtoneAnimation.setStartDelay(startDelay); vibrateAnimation.setStartDelay(startDelay); startDelay += delayIncrement; editLabelAnimation.setStartDelay(startDelay); startDelay += delayIncrement; hairLineAnimation.setStartDelay(startDelay); if (preemptiveDismissButton.getVisibility() == View.VISIBLE) { dismissAnimation.setStartDelay(startDelay); startDelay += delayIncrement; } deleteAnimation.setStartDelay(startDelay); final AnimatorSet animatorSet = new AnimatorSet(); animatorSet.playTogether(backgroundAnimator, repeatAnimation, boundsAnimator, repeatDaysAnimation, vibrateAnimation, ringtoneAnimation, editLabelAnimation, deleteAnimation, hairLineAnimation, dismissAnimation, arrowAnimation); animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animator) { AnimatorUtils.startDrawableAnimation(arrow); } }); return animatorSet; }
From source file:com.modprobe.profit.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 v a 2s .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 SuggestionExpandingListViewItem viewObject = (SuggestionExpandingListViewItem) 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 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 = 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 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.*/ expandingLayout.setAlpha(1); } }); s.start(); return true; } }); }
From source file:com.example.mike.birdalarm.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 . jav 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. */ public void collapseView(final View view) { final Alarm viewObject = (Alarm) 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<>(); 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.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 = 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.options_layout); /* * Animates all the cells present on the screen after the * collapse. */ ArrayList<Animator> animations = new ArrayList<>(); 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.setExpandedState(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:com.shoshin.paidpay.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 w ww . j a va2s. 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(); 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 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 = 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. */ //TODO 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 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.*/ expandingLayout.setAlpha(1); invalidateViews(); } }); s.start(); return true; } }); }
From source file:android.support.graphics.drawable.AnimatorInflaterCompat.java
private static Animator createAnimatorFromXml(Context context, Resources res, Theme theme, XmlPullParser parser, AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize) throws XmlPullParserException, IOException { Animator anim = null;// w w w.j a v a 2 s . c om ArrayList<Animator> childAnims = null; // Make sure we are on a start tag. int type; int depth = parser.getDepth(); while (((type = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { continue; } String name = parser.getName(); boolean gotValues = false; if (name.equals("objectAnimator")) { anim = loadObjectAnimator(context, res, theme, attrs, pixelSize, parser); } else if (name.equals("animator")) { anim = loadAnimator(context, res, theme, attrs, null, pixelSize, parser); } else if (name.equals("set")) { anim = new AnimatorSet(); TypedArray a = TypedArrayUtils.obtainAttributes(res, theme, attrs, AndroidResources.STYLEABLE_ANIMATOR_SET); int ordering = TypedArrayUtils.getNamedInt(a, parser, "ordering", AndroidResources.STYLEABLE_ANIMATOR_SET_ORDERING, TOGETHER); createAnimatorFromXml(context, res, theme, parser, attrs, (AnimatorSet) anim, ordering, pixelSize); a.recycle(); } else if (name.equals("propertyValuesHolder")) { PropertyValuesHolder[] values = loadValues(context, res, theme, parser, Xml.asAttributeSet(parser)); if (values != null && anim != null && (anim instanceof ValueAnimator)) { ((ValueAnimator) anim).setValues(values); } gotValues = true; } else { throw new RuntimeException("Unknown animator name: " + parser.getName()); } if (parent != null && !gotValues) { if (childAnims == null) { childAnims = new ArrayList<Animator>(); } childAnims.add(anim); } } if (parent != null && childAnims != null) { Animator[] animsArray = new Animator[childAnims.size()]; int index = 0; for (Animator a : childAnims) { animsArray[index++] = a; } if (sequenceOrdering == TOGETHER) { parent.playTogether(animsArray); } else { parent.playSequentially(animsArray); } } return anim; }