No se puede iniciar este animador en una vista separada! Revelar efecto

Estoy tratando de crear el efecto de revelar en mi aplicación, pero sin éxito. Lo que quiero es revelar un cardview cuando abro un fragmento. Lo que he intentado hasta ahora es:

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(); } } 

Y en el onCreateView i inició el método:

 toggleInformationView(view); 

Este es el cardview:

 <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> 

Y el 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) 

Comprobación, parece que getWidth() y getHeight() devuelve 0. Pero no sé si es el problema real. Gracias

Así es como lo solucioné, añadí un oyente onLayoutChange a la vista en callback onCreateView, por lo que siempre que se adjunta a la vista y listo para dibujar, hace que la revelación

 @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; } 

Puede utilizar runnable para hacer el anim. El runnable se ejecutará después de la creación de la vista.

 view.post(new Runnable() { @Override public void run() { //create your anim here } }); 

¿Qué tal simplemente colocar el método en el método onViewCreated ():

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

funciona

Pequeña adición a la respuesta de Hitesh . Es mejor utilizar https://developer.android.com/reference/android/support/v4/view/ViewCompat.html#isAttachedToWindow(android.view.View)

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

Ejemplo:

 LinearLayout rootView = null; rootView = (LinearLayout) findViewById(R.id.rootView); boolean isAttachedToWindow = ViewCompat.isAttachedToWindow(rootView); 

Trate de llamar al método onViewCreated

Utilice un ViewTreeObserver.

  ViewTreeObserver viewTreeObserver = rootLayout.getViewTreeObserver(); if (viewTreeObserver.isAlive()) { viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { revealActivity(revealX, revealY); rootLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); } 

Utilizaba la vista personalizada así que isAttachedToWindow() método isAttachedToWindow() para comprobar si la vista se adjunta y evitar hacer revelar mientras que la vista no está unida.

  • ¿Por qué mis elementos de ListView no se pueden hacer clic?
  • Android - ¿Cómo añadir mi propio codec de audio a AudioRecord?
  • ¿Por qué son abstractas estas funciones, dónde encontrar el cuerpo (aplicación específica) de ellas?
  • Desaparecidos constructores por defecto
  • Android: ¿qué hace el método "setTextFilterEnabled"?
  • Sqlite - en rebaja
  • Vida útil de los objetos en Java vs .Net
  • Encontrar el modelo de dispositivo y hacer
  • Triangle opengl en android
  • Cómo encontrar la "última página" en un paginador de vista. O el número total de puntos de vista. Desarrollo de Android
  • Llamada AsyncTask desde receptor de difusión Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.