List of usage examples for android.view ViewTreeObserver removeOnPreDrawListener
public void removeOnPreDrawListener(OnPreDrawListener victim)
From source file:com.android.incallui.CircularRevealActivity.java
private void setupDecorView(final Point touchPoint, MaterialPalette palette) { final View view = getWindow().getDecorView(); // The circle starts from an initial size of 0 so clip it such that it is invisible. When // the animation later starts, this clip will be clobbered by the circular reveal clip. // See ViewAnimationUtils.createCircularReveal. view.setOutlineProvider(new ViewOutlineProvider() { @Override//from w w w . ja v a2 s . c om public void getOutline(View view, Outline outline) { // Using (0, 0, 0, 0) will not work since the outline will simply be treated as // an empty outline. outline.setOval(-1, -1, 0, 0); } }); view.setClipToOutline(true); if (palette != null) { view.findViewById(R.id.outgoing_call_animation_circle).setBackgroundColor(palette.mPrimaryColor); getWindow().setStatusBarColor(palette.mSecondaryColor); } view.getViewTreeObserver().addOnPreDrawListener(new OnPreDrawListener() { @Override public boolean onPreDraw() { final ViewTreeObserver vto = view.getViewTreeObserver(); if (vto.isAlive()) { vto.removeOnPreDrawListener(this); } final Animator animator = getRevealAnimator(touchPoint); // Since this animator is a RenderNodeAnimator (native animator), add an arbitary // start delay to force the onAnimationStart callback to happen later on the UI // thread. Otherwise it would happen right away inside animator.start() animator.setStartDelay(5); animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { InCallPresenter.getInstance().onCircularRevealStarted(CircularRevealActivity.this); } @Override public void onAnimationEnd(Animator animation) { view.setClipToOutline(false); super.onAnimationEnd(animation); } }); animator.start(); return false; } }); }
From source file:com.cocosw.accessory.views.adapter.AdapterViewAnimator.java
public void animate() { if (animateCalled) { throw new RuntimeException("animate must only be called once"); }//w ww. j a v a 2 s . c om animateCalled = true; final ViewTreeObserver observer = adapterView.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { observer.removeOnPreDrawListener(this); Adapter adapter = adapterView.getAdapter(); final int firstVisiblePosition = adapterView.getFirstVisiblePosition(); for (int i = 0, childCount = adapterView.getChildCount(); i < childCount; i++) { final int position = firstVisiblePosition + i; final long id = adapter.getItemId(position); idToViewMap.remove(id); final View child = adapterView.getChildAt(i); final Rect bounds = viewBounds.get(id); Runnable endAction = new Runnable() { @Override public void run() { ViewCompat.setHasTransientState(child, false); } }; if (bounds != null) { if (callback == null || !callback.onMoveView(adapterView, child, position, id, bounds, endAction)) { final int dx = bounds.left - child.getLeft(); final int dy = bounds.top - child.getTop(); ViewCompat.setTranslationX(child, dx); ViewCompat.setTranslationY(child, dy); ViewCompat.animate(child).setDuration(DURATION_MOVE).translationX(0.0f) .translationY(0.0f).withEndAction(endAction); } } else { if (callback == null || !callback.onAddView(adapterView, child, position, id)) { ViewCompat.setAlpha(child, 0.0f); ViewCompat.animate(child).setDuration(DURATION_ADD).alpha(1.0f); } } } int[] adapterViewLocation = new int[2]; int[] hostViewLocation = new int[2]; final int size = idToViewMap.size(); for (int i = 0; i < size; i++) { final long id = idToViewMap.keyAt(i); final View child = idToViewMap.get(id); ViewCompat.setHasTransientState(child, false); final View viewCopy = new ViewCopy(child); Rect bounds = viewBounds.get(id); if (overlay == null) { ViewGroup parent = (ViewGroup) adapterView.getParent(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) overlay = parent.getOverlay(); adapterView.getLocationOnScreen(adapterViewLocation); parent.getLocationOnScreen(hostViewLocation); } overlay.add(viewCopy); viewCopy.offsetLeftAndRight(adapterViewLocation[0] - hostViewLocation[0]); viewCopy.offsetTopAndBottom(adapterViewLocation[1] - hostViewLocation[1]); if (callback == null || !callback.onRemoveView(adapterView, viewCopy, id, bounds)) { ViewCompat.animate(viewCopy).setDuration(DURATION_REMOVE).alpha(0.0f) .withEndAction(new Runnable() { @Override public void run() { overlay.remove(viewCopy); } }); } } return true; } }); }
From source file:com.amagi82.kerbalspaceapp.MissionPlanner.java
/** * This method animates all other views in the ListView container (not including ignoreView) into their final positions. It is called * after ignoreView has been removed from the adapter, but before layout has been run. The approach here is to figure out where * everything is now, then allow layout to run, then figure out where everything is after layout, and then to run animations between all * of those start/end positions.//from w w w . ja v a 2 s . co m */ 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 = mAdapter.getItemId(position); mItemIdTopMap.put(itemId, child.getTop()); } } // Delete the item from the adapter int position = mListView.getPositionForView(viewToRemove); mAdapter.remove(mAdapter.getItem(position)); mAdapter.notifyDataSetChanged(); refreshDeltaV(); final ViewTreeObserver observer = listview.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override 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 = mAdapter.getItemId(position); Integer startTop = mItemIdTopMap.get(itemId); int top = child.getTop(); if (startTop != null) { if (startTop != top) { int delta = startTop - top; child.setTranslationY(delta); child.animate().setDuration(MOVE_DURATION).translationY(0); if (firstAnimation) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { child.animate().setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mBackgroundContainer.hideBackground(); mSwiping = false; mListView.setEnabled(true); } }); } else { child.animate().withEndAction(new Runnable() { @Override public void run() { mBackgroundContainer.hideBackground(); mSwiping = false; mListView.setEnabled(true); } }); 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(); startTop = top + (i > 0 ? childHeight : -childHeight); int delta = startTop - top; child.setTranslationY(delta); child.animate().setDuration(MOVE_DURATION).translationY(0); if (firstAnimation) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) { child.animate().setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mBackgroundContainer.hideBackground(); mSwiping = false; mListView.setEnabled(true); } }); } else { child.animate().withEndAction(new Runnable() { @Override public void run() { mBackgroundContainer.hideBackground(); mSwiping = false; mListView.setEnabled(true); } }); firstAnimation = false; } } } } mItemIdTopMap.clear(); return true; } }); }
From source file:com.shalzz.attendance.fragment.AttendanceListFragment.java
@Override public void onItemExpanded(final View view) { final int spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); final ExpandableListAdapter.GenericViewHolder viewHolder = (ExpandableListAdapter.GenericViewHolder) view .getTag();/*from www .j a v a2s.co m*/ final RelativeLayout childView = viewHolder.childView; childView.measure(spec, spec); final int startingHeight = view.getHeight(); final ViewTreeObserver observer = mRecyclerView.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // We don'mTracker want to continue getting called for every draw. if (observer.isAlive()) { observer.removeOnPreDrawListener(this); } // Calculate some values to help with the animation. final int endingHeight = view.getHeight(); final int distance = Math.abs(endingHeight - startingHeight); final int baseHeight = Math.min(endingHeight, startingHeight); final boolean isExpanded = endingHeight > startingHeight; // Set the views back to the start state of the animation view.getLayoutParams().height = startingHeight; if (!isExpanded) { viewHolder.childView.setVisibility(View.VISIBLE); } // Set up the fade effect for the action buttons. if (isExpanded) { // Start the fade in after the expansion has partly completed, otherwise it // will be mostly over before the expansion completes. viewHolder.childView.setAlpha(0f); viewHolder.childView.animate().alpha(1f).setStartDelay(mFadeInStartDelay) .setDuration(mFadeInDuration).start(); } else { viewHolder.childView.setAlpha(1f); viewHolder.childView.animate().alpha(0f).setDuration(mFadeOutDuration).start(); } view.requestLayout(); // Set up the animator to animate the expansion and shadow depth. ValueAnimator animator = isExpanded ? ValueAnimator.ofFloat(0f, 1f) : ValueAnimator.ofFloat(1f, 0f); // scroll to make the view fully visible. mRecyclerView.smoothScrollToPosition(viewHolder.position); animator.addUpdateListener(animator1 -> { Float value = (Float) animator1.getAnimatedValue(); // For each value from 0 to 1, animate the various parts of the layout. view.getLayoutParams().height = (int) (value * distance + baseHeight); float z = mExpandedItemTranslationZ * value; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { view.setTranslationZ(z); } view.requestLayout(); }); // Set everything to their final values when the animation's done. animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; if (!isExpanded) { viewHolder.childView.setVisibility(View.GONE); } else { // This seems like it should be unnecessary, but without this, after // navigating out of the activity and then back, the action view alpha // is defaulting to the value (0) at the start of the expand animation. viewHolder.childView.setAlpha(1); } } }); animator.setDuration(mExpandCollapseDuration); animator.start(); // Return false so this draw does not occur to prevent the final frame from // being drawn for the single frame before the animations start. return false; } }); }
From source file:com.dgnt.dominionCardPicker.view.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. ja v a 2 s . 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); if (switchView == null) { updateNeighborViewsForID(mMobileItemId); return; } swapElements(list, originalItem, getPositionForView(switchView)); ((BaseAdapter) getAdapter()).notifyDataSetChanged(); mDownY = mLastEventY; final int switchViewStartTop = switchView.getTop(); mobileView.setVisibility(View.VISIBLE); switchView.setVisibility(View.VISIBLE); 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; switchView.setTranslationY(delta); ObjectAnimator animator = ObjectAnimator.ofFloat(switchView, View.TRANSLATION_Y, 0); animator.setDuration(MOVE_DURATION); animator.start(); return true; } }); } }
From source file:org.mozilla.gecko.animation.PropertyAnimator.java
public void start() { if (mDuration == 0) { return;/*from w w w . j av a2 s . c o m*/ } mStartTime = AnimationUtils.currentAnimationTimeMillis(); // Fix the from value based on current position and property for (ElementHolder element : mElementsList) { if (element.property == Property.ALPHA) element.from = element.proxy.getAlpha(); else if (element.property == Property.TRANSLATION_Y) element.from = element.proxy.getTranslationY(); else if (element.property == Property.TRANSLATION_X) element.from = element.proxy.getTranslationX(); else if (element.property == Property.SCROLL_Y) element.from = element.proxy.getScrollY(); else if (element.property == Property.SCROLL_X) element.from = element.proxy.getScrollX(); else if (element.property == Property.WIDTH) element.from = element.proxy.getWidth(); else if (element.property == Property.HEIGHT) element.from = element.proxy.getHeight(); ViewCompat.setHasTransientState(element.view, true); if (shouldEnableHardwareLayer(element)) element.view.setLayerType(View.LAYER_TYPE_HARDWARE, null); else element.view.setDrawingCacheEnabled(true); } // Get ViewTreeObserver from any of the participant views // in the animation. final ViewTreeObserver treeObserver; if (mElementsList.size() > 0) { treeObserver = mElementsList.get(0).view.getViewTreeObserver(); } else { treeObserver = null; } final ViewTreeObserver.OnPreDrawListener preDrawListener = new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { if (treeObserver.isAlive()) { treeObserver.removeOnPreDrawListener(this); } mFramePoster.postFirstAnimationFrame(); return true; } }; // Try to start animation after any on-going layout round // in the current view tree. OnPreDrawListener seems broken // on pre-Honeycomb devices, start animation immediatelly // in this case. if (Versions.feature11Plus && treeObserver != null && treeObserver.isAlive()) { treeObserver.addOnPreDrawListener(preDrawListener); } else { mFramePoster.postFirstAnimationFrame(); } if (mListeners != null) { for (PropertyAnimationListener listener : mListeners) { listener.onPropertyAnimationStart(); } } }
From source file:com.example.customview.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 ww w.jav a 2 s. co 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); if (switchView == null) { updateNeighborViewsForID(mMobileItemId); return; } if (getPositionForView(switchView) == mPanelList.size() - 1) { return; } swapElements(mPanelList, originalItem, getPositionForView(switchView)); ((BaseAdapter) getAdapter()).notifyDataSetChanged(); mDownY = mLastEventY; 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; switchView.setTranslationY(delta); ObjectAnimator animator = ObjectAnimator.ofFloat(switchView, View.TRANSLATION_Y, 0); animator.setDuration(MOVE_DURATION); animator.start(); return true; } }); } }
From source file:com.geecko.QuickLyric.fragment.LocalLyricsFragment.java
public void addObserver(final LongSparseArray<Integer> itemIdTopMap) { final boolean[] firstAnimation = { true }; final ViewTreeObserver observer = megaListView.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { public boolean onPreDraw() { observer.removeOnPreDrawListener(this); firstAnimation[0] = true;/*w w w . j a v a 2s.co m*/ int firstVisiblePosition = megaListView.getFirstVisiblePosition(); for (int i = 0; i < megaListView.getChildCount(); ++i) { final View child = megaListView.getChildAt(i); int position = firstVisiblePosition + i; long itemId = getListView().getAdapter().getItemId(position); Integer formerTop = itemIdTopMap.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[0]) { child.animate().setListener(new AnimatorActionListener(new Runnable() { public void run() { mSwiping = false; getListView().setEnabled(true); } }, AnimatorActionListener.ActionType.END)); firstAnimation[0] = 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() + megaListView.getDividerHeight(); boolean isFurthest = true; for (int j = 0; j < itemIdTopMap.size(); j++) { Integer top = itemIdTopMap.valueAt(j); if (top - childHeight > newTop) { isFurthest = false; break; } } formerTop = newTop + (i > 0 ? childHeight : -childHeight); int delta = formerTop - newTop; int MOVE_DURATION = 500; if (isFurthest) { child.setTranslationY(delta); child.animate().setDuration(MOVE_DURATION).translationY(0); } else { int translationX = formerTop > childHeight ? child.getWidth() : 0; child.setTranslationX(translationX); if (translationX == 0) child.setTranslationY(formerTop - newTop); child.animate().setDuration(MOVE_DURATION).translationX(0).translationY(0); } if (firstAnimation[0]) { child.animate().setListener(new AnimatorActionListener(new Runnable() { public void run() { getListView().setEnabled(true); mSwiping = false; } }, AnimatorActionListener.ActionType.END)); firstAnimation[0] = false; } } } if (firstAnimation[0]) { mSwiping = false; getListView().setEnabled(true); firstAnimation[0] = false; } itemIdTopMap.clear(); return true; } }); }
From source file:ucsc.hci.rankit.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 ww w. 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); if (switchView == null) { updateNeighborViewsForID(mMobileItemId); return; } swapElements(mObjectList, originalItem, getPositionForView(switchView)); ((BaseAdapter) getAdapter()).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); // } // else { // mobileView.setVisibility(View.INVISIBLE); // switchView.setVisibility(View.VISIBLE); // } 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; switchView.setTranslationY(delta); ObjectAnimator animator = ObjectAnimator.ofFloat(switchView, View.TRANSLATION_Y, 0); animator.setDuration(MOVE_DURATION); animator.start(); return true; } }); } }
From source file:ch.gianulli.flashcards.ui.Flashcard.java
private void expandButtonBar() { mButtonBarShowing = true;/*w ww .j a va 2 s. c o m*/ mButtonBar.setVisibility(View.VISIBLE); mButtonBar.setAlpha(0.0f); final int startingHeight = mCardView.getHeight(); final ViewTreeObserver observer = mCardView.getViewTreeObserver(); observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { @Override public boolean onPreDraw() { // We don't want to continue getting called for every listview drawing. if (observer.isAlive()) { observer.removeOnPreDrawListener(this); } final int endingHeight = mCardView.getHeight(); final int distance = endingHeight - startingHeight; mCardView.getLayoutParams().height = startingHeight; mCardView.requestLayout(); ValueAnimator heightAnimator = ValueAnimator.ofFloat(0f, 1f).setDuration(300); heightAnimator.setInterpolator(new DecelerateInterpolator()); heightAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animator) { Float value = (Float) animator.getAnimatedValue(); mCardView.getLayoutParams().height = (int) (value * distance + startingHeight); mCardView.requestLayout(); } }); heightAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mCardView.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT; } }); mButtonBar.setLayerType(View.LAYER_TYPE_HARDWARE, null); ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(mButtonBar, "alpha", 0.0f, 1.0f); alphaAnimator.setInterpolator(new DecelerateInterpolator()); alphaAnimator.setDuration(300); alphaAnimator.setStartDelay(100); AnimatorSet set = new AnimatorSet(); set.playTogether(heightAnimator, alphaAnimator); set.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mButtonBar.setLayerType(View.LAYER_TYPE_SOFTWARE, null); } }); set.start(); return false; } }); }