wake-up-neo.com

Dieser Animator kann nicht in einer separaten Ansicht gestartet werden! Wirkung zeigen

Ich versuche, den enthüllenden Effekt in meiner Anwendung zu erzeugen, jedoch ohne Erfolg. Was ich will, ist ein Cardview, wenn ich ein Fragment öffne. Was ich bisher ausprobiert habe, ist:

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

und in der onCreateView habe ich die Methode gestartet:

toggleInformationView(view);

dies ist die Kartenansicht:

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

und das 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)

Bei der Überprüfung scheint getWidth() und getHeight() 0 zu liefern. Aber ich weiß nicht, ob es das eigentliche Problem ist. Vielen Dank

59
End.Game

So habe ich das Problem gelöst: Ich habe der Ansicht in onCreateView-Callback einen onLayoutChange-Listener hinzugefügt. Wenn also die Ansicht an die Ansicht angehängt wird und gezeichnet werden kann, wird sie sichtbar

@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

Sie können Run ausführen, um das Tier zu machen. Dieses Run läuft nach der Erstellung der Ansicht.

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

Eine kleine Ergänzung zu Hiteshhs Antwort . Es ist besser, https://developer.Android.com/reference/Android/support/v4/view/ViewCompat.html#isAttachedToWindow(Android zu verwenden. view.View)

Android.support.v4.view.ViewCompat

boolean isAttachedToWindow (View view)

Beispiel:

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

Wie wäre es, wenn Sie die Methode einfach in die onViewCreated () -Methode einfügen:

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

es klappt 

6
Ziv Kesten

außerhalb des Rahmens der Frage vereinfacht

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

            }
        });
    }
}

rufen Sie startAnimation für eine oder mehrere Animationen auf

startAnimation(view, new Runnable() {
        @Override
        public void run() {
          //the code inside toggleInformationView(view)
        }
    });
2
Juan Mendez

ach !!!, hier ist endlich die Lösung für diesen Fehler. Tatsächlich besteht das Problem darin, dass wir der Animation eine Ansicht mit ihrer Höhe und Breite zuweisen, und plötzlich haben wir nicht bemerkt, dass ein Fall vorliegt. Diese Ansicht wird nicht richtig geladen, wenn wir sie der Animation zuweisen. Deshalb müssen wir warten, bis die Ansicht ordnungsgemäß geladen wird.

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

Versuchen Sie es mit der onViewCreated-Methode aufzurufen

1

Verwenden Sie einen 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
josedlujan

Ich habe die benutzerdefinierte Ansicht verwendet, also habe ich die isAttachedToWindow()-Methode verwendet, um zu prüfen, ob die Ansicht angehängt ist, und zu vermeiden, dass die Anzeige angezeigt wird, während die Ansicht nicht angehängt ist.

0
Hitesh Sahu

Überprüfen Sie, ob Ihr Layout mit dem Fenster verbunden ist oder nicht, indem Sie die rootLayout.isAttachedToWindow()-Methode verwenden.

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