Unable to run this animator on a separate screen! reveal effect

I am trying to create a disclosure effect in my application, but to no avail. What I want opens a map when I open a fragment. I have tried so far:

private void toggleInformationView(View view) { infoContainer = view.findViewById(R.id.contact_card); int cx = (view.getLeft() + view.getRight()) / 2; int cy = (view.getTop() + view.getBottom()) / 2; float radius = Math.max(infoContainer.getWidth(), infoContainer.getHeight()) * 2.0f; if (infoContainer.getVisibility() == View.INVISIBLE) { infoContainer.setVisibility(View.VISIBLE); ViewAnimationUtils.createCircularReveal(infoContainer, cx, cy, 0, radius).start(); } else { Animator reveal = ViewAnimationUtils.createCircularReveal( infoContainer, cx, cy, radius, 0); reveal.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { infoContainer.setVisibility(View.INVISIBLE); } }); reveal.start(); } } 

and in onCreateView I started the method:

 toggleInformationView(view); 

this is a map:

 <android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:id="@+id/contact_card" android:visibility="invisible" android:layout_height="wrap_content" android:layout_margin="5dp" android:elevation="4dp" android:foreground="?android:attr/selectableItemBackground" android:orientation="vertical" android:padding="10dp" card_view:cardCornerRadius="2dp" > <LinearLayout android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" > <ImageView android:id="@+id/bg_contact" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_weight="0" android:adjustViewBounds="true" android:scaleType="centerCrop" android:src="@drawable/banner" /> </LinearLayout> </android.support.v7.widget.CardView> 

and logcat:

 11-08 17:25:48.541: E/AndroidRuntime(26925): java.lang.IllegalStateException: Cannot start this animator on a detached view! 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.view.RenderNode.addAnimator(RenderNode.java:817) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.view.RenderNodeAnimator.setTarget(RenderNodeAnimator.java:277) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.view.RenderNodeAnimator.setTarget(RenderNodeAnimator.java:261) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.animation.RevealAnimator.<init>(RevealAnimator.java:37) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.view.ViewAnimationUtils.createCircularReveal(ViewAnimationUtils.java:48) 11-08 17:25:48.541: E/AndroidRuntime(26925): at com.as.asapp.TFragment.toggleInformationView(TFragment.java:64) 11-08 17:25:48.541: E/AndroidRuntime(26925): at com.as.asapp.TFragmentshowInformation(TFragment.java:52) 11-08 17:25:48.541: E/AndroidRuntime(26925): at com.as.asapp.TFragment.onCreateView(TFragment.java:37) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1786) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1126) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:739) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1489) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:454) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.os.Handler.handleCallback(Handler.java:739) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.os.Handler.dispatchMessage(Handler.java:95) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.os.Looper.loop(Looper.java:135) 11-08 17:25:48.541: E/AndroidRuntime(26925): at android.app.ActivityThread.main(ActivityThread.java:5221) 11-08 17:25:48.541: E/AndroidRuntime(26925): at java.lang.reflect.Method.invoke(Native Method) 11-08 17:25:48.541: E/AndroidRuntime(26925): at java.lang.reflect.Method.invoke(Method.java:372) 11-08 17:25:48.541: E/AndroidRuntime(26925): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899) 11-08 17:25:48.541: E/AndroidRuntime(26925): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694) 

Checking it seems that getWidth() and getHeight() returns 0. But I do not know if this is a real problem. Thanks

+59
java android android-animation
Nov 08 '14 at 16:36
source share
10 answers

This is how I solved it, I added the onLayoutChange listener to the view in the onCreateView callback, so whenever it is attached to the view and ready to draw, it does an expansion

 @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment final View view = inflater.inflate(R.layout.fragment_map_list, container, false); if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { v.removeOnLayoutChangeListener(this); toggleInformationView(view); } }); } return view; } 
+70
Nov 11 '14 at 9:49
source share

You can use runnable to create animations. Runnable will start after the view is created.

 view.post(new Runnable() { @Override public void run() { //create your anim here } }); 
+34
Oct 10 '15 at 11:09
source share

A small addition to Hitesh's answer. Better use https://developer.android.com/reference/android/support/v4/view/ViewCompat.html#isAttachedToWindow(android.view.View)

 android.support.v4.view.ViewCompat boolean isAttachedToWindow (View view) 

Example:

 LinearLayout rootView = null; rootView = (LinearLayout) findViewById(R.id.rootView); boolean isAttachedToWindow = ViewCompat.isAttachedToWindow(rootView); 
+12
26 Oct '16 at 7:40
source share

How to simply place a method in the onViewCreated () method:

 @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); toggleInformationView(view); } 

works

+6
Feb 11 '15 at 7:54
source share

ah, finally, here is the solution to this error. Actually, the problem is that we assign the animation representation with its height and width, and suddenly we did not notice that there may be a case where the representation that we assign for the animation will not load properly. So for this we need to wait until the view loads correctly.

 LayoutInflater inflater = this.getLayoutInflater(); View rowView = inflater.inflate( R.layout.fileselecttype,null, true ); rowView or [Your View] [Your View].post(new Runnable() { @Override public void run() { //Do your animation work here. } }); 
+2
Jan 12 '18 at 17:01
source share

Try calling it using the onViewCreated method

+1
Nov 10 '14 at 16:41
source share

Use ViewTreeObserver.

  ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver(); if (viewTreeObserver.isAlive()) { viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { revealActivity(revealX, revealY); rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } 
+1
Aug 04 '17 at 2:16 on
source share

simplified out of the question

 private void startAnimation(@NonNull final View view, @NonNull final Runnable onAttachedToWindow) { if (view.isAttachedToWindow()) { onAttachedToWindow.run(); } else { view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View view) { onAttachedToWindow.run(); view.removeOnAttachStateChangeListener(this) } @Override public void onViewDetachedFromWindow(View view) { } }); } } 

call startAnimation for one or more animations

 startAnimation(view, new Runnable() { @Override public void run() { //the code inside toggleInformationView(view) } }); 
+1
Jul 17 '18 at 20:47
source share

I used a custom view, so I used the isAttachedToWindow() method to check if the view is attached, and to avoid reading until the view is connected.

0
Sep 16 '16 at 12:55
source share

Check if your layout is attached to the window or not using rootLayout.isAttachedToWindow() .

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (rootLayout!= null) { if(rootLayout.isAttachedToWindow()) { ViewTreeObserver viewTreeObserver = drawerLayout.getViewTreeObserver(); if (viewTreeObserver.isAlive()) { viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { startRevealAnimation(rootLayout); rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } } } 
0
Apr 04 '18 at 7:47
source share



All Articles