/** * Update the Start/Stop text. The button is within a view group with a transition that is needed * to animate the button moving. The transition also animates the the text changing, but that * animation does not provide a good look and feel. Temporarily disable the view group transition * while the text is changing and restore it afterwards. * * @param parent - View Group holding the start/stop button * @param textView - The start/stop button * @param text - Start or Stop id */ private void setStartStopText(final ViewGroup parent, TextView textView, int text) { final LayoutTransition layoutTransition = parent.getLayoutTransition(); // Tap into the parent layout->draw flow just before the draw ViewTreeObserver viewTreeObserver = parent.getViewTreeObserver(); if (viewTreeObserver != null) { viewTreeObserver.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { /** * Re-establish the transition handler Remove this listener * * @return true so that onDraw() is called */ @Override public boolean onPreDraw() { parent.setLayoutTransition(layoutTransition); ViewTreeObserver viewTreeObserver = parent.getViewTreeObserver(); if (viewTreeObserver != null) { viewTreeObserver.removeOnPreDrawListener(this); } return true; } }); } // Remove the transition while the text is updated parent.setLayoutTransition(null); String textStr = getActivity().getResources().getString(text); textView.setText(textStr); textView.setContentDescription(textStr); }
private void initView() { textView = (TextView) findViewById(R.id.textview); ViewTreeObserver treeObserver = textView.getViewTreeObserver(); treeObserver.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (!hasMeasure) { maxLines = textView.getLineCount(); textView.setMaxLines(MAX); hasMeasure = true; } return true; } }); textView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { toggle(); } }); }
private void fixLayout() { ViewTreeObserver obs = fragmentView.getViewTreeObserver(); obs.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (fragmentView == null) { return true; } fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); LinearLayout layout = (LinearLayout) fragmentView; WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); int rotation = manager.getDefaultDisplay().getRotation(); if (rotation == Surface.ROTATION_270 || rotation == Surface.ROTATION_90) { layout.setOrientation(LinearLayout.HORIZONTAL); } else { layout.setOrientation(LinearLayout.VERTICAL); } fragmentView.setPadding( fragmentView.getPaddingLeft(), 0, fragmentView.getPaddingRight(), fragmentView.getPaddingBottom()); return true; } }); }
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_collage_editor); getSupportActionBar().setDisplayHomeAsUpEnabled(true); interstitial = new InterstitialAd(this); interstitial.setAdUnitId(getString(R.string.interstitial_ad_unit_id)); // Create ad request. AdRequest adRequest = new AdRequest.Builder().build(); // Begin loading your interstitial. interstitial.loadAd(adRequest); Intent i = getIntent(); imgid = i.getIntExtra("frameId", 0); typeId = i.getIntExtra("typeId", 0); imgBackground = (ImageView) findViewById(R.id.imgBackground); imgBackground.setBackgroundResource(imgid); ViewTreeObserver vto = imgBackground.getViewTreeObserver(); // vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { // @SuppressLint("NewApi") // @SuppressWarnings("deprecation") // @Override // public void onGlobalLayout() { // imgBackgroundWidth = imgBackground.getWidth(); // imgBackgroundHeight = imgBackground.getHeight(); // GenerateUI(); // // if (android.os.Build.VERSION.SDK_INT >= // android.os.Build.VERSION_CODES.JELLY_BEAN) // imgBackground.getViewTreeObserver().removeOnGlobalLayoutListener(this); // else // imgBackground.getViewTreeObserver().removeGlobalOnLayoutListener(this); // // // } // }); vto.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { imgBackgroundWidth = imgBackground.getWidth(); imgBackgroundHeight = imgBackground.getHeight(); GenerateUI(); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) imgBackground.getViewTreeObserver().removeOnPreDrawListener(this); else imgBackground.getViewTreeObserver().removeOnPreDrawListener(this); return true; } }); collageEditorRelativeLayout = (RelativeLayout) findViewById(R.id.collageEditorRelativeLayout); }
private void initFloatingWindow() { mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mWindow = PolicyManager.makeNewWindow(mContext); mWindow.setWindowManager(mWindowManager, null, null); mWindow.requestFeature(Window.FEATURE_NO_TITLE); mDecor = mWindow.getDecorView(); /// M: Get measured height of window and update. @{ ViewTreeObserver vto = mDecor.getViewTreeObserver(); vto.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { mHeight = mDecor.getMeasuredHeight(); updateFloatingWindowLayout(); mWindowManager.updateViewLayout(mDecor, mDecorLayoutParams); mDecor.getViewTreeObserver().removeOnPreDrawListener(this); return true; } }); /// @} mDecor.setOnTouchListener(mTouchListener); mWindow.setContentView(this); mWindow.setBackgroundDrawableResource(android.R.color.transparent); // While the media controller is up, the volume control keys should // affect the media stream type mWindow.setVolumeControlStream(AudioManager.STREAM_MUSIC); setFocusable(true); setFocusableInTouchMode(true); setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS); requestFocus(); }
void getSize(SizeReadyCallback cb) { int currentWidth = getViewWidthOrParam(); int currentHeight = getViewHeightOrParam(); if (isSizeValid(currentWidth) && isSizeValid(currentHeight)) { int paddingAdjustedWidth = currentWidth == WindowManager.LayoutParams.WRAP_CONTENT ? currentWidth : currentWidth - ViewCompat.getPaddingStart(view) - ViewCompat.getPaddingEnd(view); int paddingAdjustedHeight = currentHeight == LayoutParams.WRAP_CONTENT ? currentHeight : currentHeight - view.getPaddingTop() - view.getPaddingBottom(); cb.onSizeReady(paddingAdjustedWidth, paddingAdjustedHeight); } else { // We want to notify callbacks in the order they were added and we only expect one or two // callbacks to // be added a time, so a List is a reasonable choice. if (!cbs.contains(cb)) { cbs.add(cb); } if (layoutListener == null) { final ViewTreeObserver observer = view.getViewTreeObserver(); layoutListener = new SizeDeterminerLayoutListener(this); observer.addOnPreDrawListener(layoutListener); } } }
@Override public View getView(int position, View convertView, ViewGroup parent) { final ViewHolder viewHolder; if (convertView == null) { LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE); convertView = mInflater.inflate(R.layout.specimen_list_item, null); viewHolder = new ViewHolder(); viewHolder.specimenImageView = (ImageView) convertView.findViewById(R.id.specimen_image); viewHolder.specimenTitleView = (TextView) convertView.findViewById(R.id.specimen_title); viewHolder.specimenScientificName = (TextView) convertView.findViewById(R.id.scientific_name); viewHolder.specimenLocality = (TextView) convertView.findViewById(R.id.specimen_locality); viewHolder.specimenDescription = (TextView) convertView.findViewById(R.id.specimen_description); viewHolder.itemLocatedView = (ImageView) convertView.findViewById(R.id.item_located); convertView.setTag(viewHolder); } else { viewHolder = (ViewHolder) convertView.getTag(); } final SpecimenListItem specimenListItem = objects.get(position); if (specimenListItem.getImagePath() == null) { viewHolder.specimenImageView.setImageResource(specimenListItem.getSpecimenImage()); } else { final ViewTreeObserver vto = viewHolder.specimenImageView.getViewTreeObserver(); if (vto.isAlive()) { vto.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { if (vto.isAlive()) { vto.removeOnPreDrawListener(this); } thumbnailHeight = viewHolder.specimenImageView.getMeasuredHeight(); thumbnailWidth = viewHolder.specimenImageView.getMeasuredWidth(); if (cancelPotentialWork( specimenListItem.getImagePath(), viewHolder.specimenImageView)) { final LoadThumbnailTask loadThumbnailTask = new LoadThumbnailTask(viewHolder.specimenImageView); final AsyncDrawable asyncDrawable = new AsyncDrawable(resources, bitmapPlaceHolder, loadThumbnailTask); viewHolder.specimenImageView.setImageDrawable(asyncDrawable); thumbnailWidth = viewHolder.specimenImageView.getMeasuredWidth(); loadThumbnailTask.execute(specimenListItem.getImagePath()); } return true; } }); } } viewHolder.specimenTitleView.setText(specimenListItem.getSpecimenTitle()); viewHolder.specimenScientificName.setText(specimenListItem.getScientificName()); viewHolder.specimenLocality.setText(specimenListItem.getSpecimenLocality()); viewHolder.specimenDescription.setText(specimenListItem.getSpecimenDescription()); viewHolder.itemLocatedView.setSelected(specimenListItem.isLocated()); if (onClickListener != null) { viewHolder.specimenImageView.setOnClickListener(onClickListener); } return convertView; }
public void registerOnPreDrawListener(View v) { // Listen for the first draw if (mViewTreeObserver == null) { mViewTreeObserver = v.getViewTreeObserver(); mViewTreeObserver.addOnPreDrawListener(this); } }
public void setupListener() { final ViewTreeObserver viewTreeObserver = mView.getViewTreeObserver(); if (viewTreeObserver != null) { viewTreeObserver.addOnGlobalLayoutListener(this); viewTreeObserver.addOnGlobalFocusChangeListener(this); viewTreeObserver.addOnPreDrawListener(this); viewTreeObserver.addOnScrollChangedListener(this); viewTreeObserver.addOnTouchModeChangeListener(this); } }
public void testDispatchOnPreDraw() { final LinearLayout layout = (LinearLayout) mActivity.findViewById(R.id.linearlayout); mViewTreeObserver = layout.getViewTreeObserver(); MockOnPreDrawListener listener = new MockOnPreDrawListener(); assertFalse(listener.hasCalledOnPreDraw()); mViewTreeObserver.addOnPreDrawListener(listener); mViewTreeObserver.dispatchOnPreDraw(); assertTrue(listener.hasCalledOnPreDraw()); }
@Override public void onActivityCreated(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); view3 = (SurfaceView) this.getActivity().findViewById(R.id.view_3); ViewTreeObserver vto = view3.getViewTreeObserver(); vto.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { Data_RW.view_height = view3.getMeasuredHeight(); Data_RW.view_width = view3.getMeasuredWidth(); return true; } }); }
private void fixLayout() { if (listView != null) { ViewTreeObserver obs = listView.getViewTreeObserver(); obs.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { fixLayoutInternal(); if (listView != null) { listView.getViewTreeObserver().removeOnPreDrawListener(this); } return true; } }); } }
private static void sceneChangeRunTransition( final ViewGroup sceneRoot, final Transition transition) { if (transition != null) { final ViewTreeObserver observer = sceneRoot.getViewTreeObserver(); final ViewTreeObserver.OnPreDrawListener listener = new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { sceneRoot.getViewTreeObserver().removeOnPreDrawListener(this); sPendingTransitions.remove(sceneRoot); // Add to running list, handle end to remove it final ArrayMap<ViewGroup, ArrayList<Transition>> runningTransitions = getRunningTransitions(); ArrayList<Transition> currentTransitions = runningTransitions.get(sceneRoot); ArrayList<Transition> previousRunningTransitions = null; if (currentTransitions == null) { currentTransitions = new ArrayList<Transition>(); runningTransitions.put(sceneRoot, currentTransitions); } else if (currentTransitions.size() > 0) { previousRunningTransitions = new ArrayList<Transition>(currentTransitions); } currentTransitions.add(transition); transition.addListener( new Transition.TransitionListenerAdapter() { @Override public void onTransitionEnd(Transition transition) { ArrayList<Transition> currentTransitions = runningTransitions.get(sceneRoot); currentTransitions.remove(transition); } }); transition.captureValues(sceneRoot, false); if (previousRunningTransitions != null) { for (Transition runningTransition : previousRunningTransitions) { runningTransition.resume(); } } transition.playTransition(sceneRoot); return true; } }; observer.addOnPreDrawListener(listener); } }
public AsymmetricGridView(final Context context, final AttributeSet attrs) { super(context, attrs); defaultPadding = Utils.dpToPx(context, 5); requestedHorizontalSpacing = defaultPadding; requestedVerticalSpacing = defaultPadding; padding = new Rect(defaultPadding, defaultPadding, defaultPadding, defaultPadding); final ViewTreeObserver vto = getViewTreeObserver(); if (vto != null) vto.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { getViewTreeObserver().removeOnPreDrawListener(this); determineColumns(); if (gridAdapter != null) gridAdapter.notifyDataSetChanged(); return false; } }); }
private void toggle(final boolean visible, final boolean animate, boolean force) { if (mVisible != visible || force) { mVisible = visible; int height = getHeight(); if (height == 0 && !force) { ViewTreeObserver vto = getViewTreeObserver(); if (vto.isAlive()) { vto.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { ViewTreeObserver currentVto = getViewTreeObserver(); if (currentVto.isAlive()) { currentVto.removeOnPreDrawListener(this); } toggle(visible, animate, true); return true; } }); return; } } int translationY = visible ? 0 : height + getMarginBottom(); if (animate) { animate() .setInterpolator(mInterpolator) // .setDuration(TRANSLATE_DURATION_MILLIS) // .translationY(translationY); } else { setTranslationY(translationY); } // On pre-Honeycomb a translated view is still clickable, so we need // to disable clicks manually if (!hasHoneycombApi()) { setClickable(visible); } } }
private void fixLayout() { ViewTreeObserver obs = fragmentView.getViewTreeObserver(); obs.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { fragmentView.getViewTreeObserver().removeOnPreDrawListener(this); if (listAdapter != null) { listAdapter.notifyDataSetChanged(); } if (listView != null) { listView.post( new Runnable() { @Override public void run() { listView.scrollTo(0); } }); } return false; } }); }
/** * 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>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 prepareCollapseView(final CardView view, final View expandingLayout) { final Card card = (Card) 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); if (Build.VERSION.SDK_INT >= 16) { v.setHasTransientState(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, view.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; } setSelection(firstVisiblePosition); // 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 numOfColumns = getNumColumns(); int rowOfSelectedItem = (int) index / numOfColumns; 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]); if (Build.VERSION.SDK_INT >= 16) { v.setHasTransientState(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 rowOfv = (int) i / numOfColumns; int delta = (i > index && rowOfv > rowOfSelectedItem) ? yTranslateBottom : -yTranslateTop; v.setTop(v.getTop() + delta); v.setBottom(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) { float diff = i > index ? -yTranslateBottom : yTranslateTop; animations.add(getAnimation(v, diff, diff)); } } /* ValueAnimator animator = ValueAnimator.ofInt( yTranslateTop,-yTranslateBottom); animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { int value = (Integer) valueAnimator.getAnimatedValue(); ViewGroup.LayoutParams layoutParams = expandingLayout.getLayoutParams(); layoutParams.height = value; expandingLayout.setLayoutParams(layoutParams); } }); animations.add(animator);*/ /* 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, 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)); view.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); if (card.getOnCollapseAnimatorEndListener() != null) card.getOnCollapseAnimatorEndListener().onCollapseEnd(card); } }); s.start(); return true; } }); }
private void prepareExpandView(final CardView view, final View expandingLayout) { final Card card = (Card) 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); if (Build.VERSION.SDK_INT >= 16) { v.setHasTransientState(true); } oldCoordinates.put(v, new int[] {v.getTop(), v.getBottom()}); } /* Update the layout so the extra content becomes visible.*/ if (expandingLayout != null) 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; } setSelection(firstVisiblePosition); // 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); int numOfColumns = getNumColumns(); int rowOfSelectedItem = (int) index / numOfColumns; /* 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 rowOfv = (int) i / numOfColumns; int delta = (i > index && rowOfv > rowOfSelectedItem) ? yTranslateBottom : -yTranslateTop; animations.add(getAnimation(v, delta, delta)); } v.setHasTransientState(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(expandingLayout, 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) { view.setExpanded(true); // card.setExpanded(true); setEnabled(true); setClickable(true); if (mViewsToDraw.size() > 0) { for (View v : mViewsToDraw) { if (Build.VERSION.SDK_INT >= 16) { v.setHasTransientState(false); } } } mViewsToDraw.clear(); if (card.getOnExpandAnimatorEndListener() != null) card.getOnExpandAnimatorEndListener().onExpandEnd(card); } }); s.start(); return true; } }); }
/** * 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. */ 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); if (switchView == null) { updateNeighborViewsForId(mMobileItemId); return; } if (getPositionForView(switchView) < getHeaderViewsCount()) { return; } swapElements(originalItem, getPositionForView(switchView)); BaseAdapter adapter; if (getAdapter() instanceof HeaderViewListAdapter) { adapter = (BaseAdapter) ((HeaderViewListAdapter) getAdapter()).getWrappedAdapter(); } else { adapter = (BaseAdapter) getAdapter(); } adapter.notifyDataSetChanged(); mDownY = mLastEventY; mDownX = mLastEventX; final int switchViewStartTop = switchView.getTop(); 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; ViewHelper.setTranslationY(switchView, delta); ObjectAnimator animator = ObjectAnimator.ofFloat(switchView, "translationY", 0); animator.setDuration(MOVE_DURATION); animator.start(); return true; } }); } }
private void animateRemoval(final ListView listview, View viewToRemove) { int firstVisiblePosition = listview.getFirstVisiblePosition(); for (int i = 0; i < listview.getChildCount(); ++i) { View child = listview.getChildAt(i); if (child != viewToRemove) { int position = firstVisiblePosition + i; long itemId = listview.getAdapter().getItemId(position); mItemIdTopMap.put(itemId, child.getTop()); } } // Delete the item from the adapter LocalAdapter.ChildViewHolder childViewHolder = (LocalAdapter.ChildViewHolder) viewToRemove.getTag(); ((LocalAdapter) getExpandableListAdapter()) .remove(childViewHolder.groupPosition, viewToRemove); new WriteToDatabaseTask(LocalLyricsFragment.this) .execute(LocalLyricsFragment.this, null, childViewHolder.lyrics); final ViewTreeObserver observer = listview.getViewTreeObserver(); observer.addOnPreDrawListener( new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { observer.removeOnPreDrawListener(this); boolean firstAnimation = true; int firstVisiblePosition = listview.getFirstVisiblePosition(); for (int i = 0; i < listview.getChildCount(); ++i) { final View child = listview.getChildAt(i); int position = firstVisiblePosition + i; long itemId = getListView().getAdapter().getItemId(position); Integer formerTop = mItemIdTopMap.get(itemId); int newTop = child.getTop(); if (formerTop != null) { if (formerTop != newTop) { int delta = formerTop - newTop; child.setTranslationY(delta); int MOVE_DURATION = 500; child.animate().setDuration(MOVE_DURATION).translationY(0); if (firstAnimation) { child .animate() .setListener( new AnimatorActionListener( new Runnable() { public void run() { mBackgroundContainer.hideBackground(); mSwiping = false; getListView().setEnabled(true); } }, AnimatorActionListener.ActionType.END)); firstAnimation = false; } } } else { // Animate new views along with the others. The catch is that they did not // exist in the start state, so we must calculate their starting position // based on neighboring views. int childHeight = child.getHeight() + listview.getDividerHeight(); formerTop = newTop + (i > 0 ? childHeight : -childHeight); int delta = formerTop - newTop; child.setTranslationY(delta); int MOVE_DURATION = 500; child.animate().setDuration(MOVE_DURATION).translationY(0); if (firstAnimation) { child .animate() .setListener( new AnimatorActionListener( new Runnable() { public void run() { mBackgroundContainer.hideBackground(); mSwiping = false; getListView().setEnabled(true); } }, AnimatorActionListener.ActionType.END)); firstAnimation = false; } } } mBackgroundContainer.hideBackground(); mItemIdTopMap.clear(); return true; } }); }