tipos introduccion historia formato conclusion animacion java android android-animation

java - introduccion - ¡No se puede iniciar este animador en una vista separada! efecto revelador



introduccion a la animacion (10)

¿Qué tal si simplemente colocamos el método en el método onViewCreated ()?

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

funciona

Estoy tratando de crear el efecto revelador en mi aplicación pero sin éxito. Lo que quiero es revelar una vista de tarjeta cuando abro un fragmento. Lo que probé 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 comencé el método:

toggleInformationView(view);

Esta es la tarjeta de visita:

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

Comprobando, parece que getWidth() y getHeight() devuelven 0. Pero no sé si es el problema real. Gracias


Así es como lo resolví, agregué un oyente onLayoutChange a la vista en la devolución de llamada onCreateView, así que cada vez que se adjunta a la vista y está listo para dibujar, hace 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; }


Estaba usando la vista personalizada, así que isAttachedToWindow() método isAttachedToWindow() para verificar si la vista está adjunta y evitar hacer revelaciones mientras la vista no está adjunta



Puedes usar runnable para hacer la animación. El ejecutable se ejecutará después de la creación de la vista.

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


Simplificado fuera del alcance de la pregunta.

private void startAnimation(@NonNull final View view, @NonNull final OnAttachedToWindow onAttachedToWindow) { if (view.isAttachedToWindow()) { onAttachedToWindow.execute(); } else { view.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View view) { onAttachedToWindow.execute(); } @Override public void onViewDetachedFromWindow(View view) { } }); } } private interface OnAttachedToWindow { void execute(); }

llame a startAnimation para una o varias animaciones en mente

startAnimation(view, new OnAttachedToWindow() { @Override public void execute() { //the code inside toggleInformationView(view) } });


Trate de llamarlo en el 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); } }); }


Verifique que su Diseño esté adjunto a la ventana o no mediante el método 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); } }); } } }


ah !!!, así que finalmente aquí está la solución para este error. En realidad, el problema es que estamos asignando una vista a la animación con su altura y anchura, y de repente no notamos que puede haber un caso, esa vista no se cargará correctamente en el momento en que la asignamos a la animación. Así que para eso, tenemos que esperar hasta que la vista se cargue correctamente.

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