Parçalar arasındaki geçişi canlandırın


284

Parçalar arasındaki geçişi canlandırmaya çalışıyorum. Aşağıdaki Android Parçalarından ve animasyondan yanıt aldım

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

DetailsFragment newFragment = DetailsFragment.newInstance();

ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");

// Start the animated transition.
ft.commit();

Ve benim R.anim.slide_in_left

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
       <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

Ama bunu denediğimde gösterdi

02-08 16:27:37.961: ERROR/AndroidRuntime(1717): FATAL EXCEPTION: main
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): java.lang.RuntimeException: Unknown animator name: translate
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:129)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:126)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:93)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.java:72)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.loadAnimator(FragmentManager.java:621)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:733)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.BackStackRecord.run(BackStackRecord.java:578)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717):     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1217)

Herhangi bir fikir? Kontrol ettiğimde Honeycomb API referansı translatevar. Ne kaçırdım?
Parçalar arasındaki geçişi canlandırmanın başka bir yolu var mı? teşekkür ederim


ANİMATÖR kullanın --- Animasyon değil! android.R.ANIMATOR.fade_in çalışır, android.R.ANIM.fade_in kullanmayın - BUGS davranışı var
user1269737

Yanıtlar:


347

Yeni android.animationçerçeveyi (nesne animatörleri) ile FragmentTransaction.setCustomAnimationsde kullanmanız gerekir FragmentTransaction.setTransition.

setCustomAnimationsApiDemos'un FragmentHideShow.java uygulamasının kullanımına ilişkin bir örnek :

ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);

ve res / animator / fade_in.xml dosyasından ilgili animatör XML'si :

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:interpolator/accelerate_quad"
    android:valueFrom="0"
    android:valueTo="1"
    android:propertyName="alpha"
    android:duration="@android:integer/config_mediumAnimTime" />

Birden çok animatörü <set>, tıpkı eski animasyon çerçevesiyle yapabileceğiniz gibi birleştirebileceğinizi unutmayın .


EDIT : Millet slayt-in / slayt-out hakkında sorduğu için, ben burada bunu yorumlayacağım.

İçeri itme ve dışarı itme

Sen elbette canlandırabilirsiniz translationX, translationY, x, ve yözelliklerini, ancak genelde slaytlar ve ekran dışı içerik animasyon içerir. Bildiğim kadarıyla göreli değerler kullanan herhangi bir geçiş özelliği yoktur. Ancak bu, bunları kendiniz yazmanızı engellemez. Özellik animasyonlarının, animasyon uyguladığınız nesnelerde (bu durumda görünümler) alıcı ve ayarlayıcı yöntemleri gerektirdiğini unutmayın, böylece görünüm alt sınıfınızda aşağıdaki gibi kendi getXFraction ve setXFractionyöntemlerinizi oluşturabilirsiniz :

public class MyFrameLayout extends FrameLayout {
    ...
    public float getXFraction() {
        return getX() / getWidth(); // TODO: guard divide-by-zero
    }

    public void setXFraction(float xFraction) {
        // TODO: cache width
        final int width = getWidth();
        setX((width > 0) ? (xFraction * width) : -9999);
    }
    ...
}

Şimdi 'xFraction' özelliğini aşağıdaki gibi canlandırabilirsiniz:

res / animatör / slide_in.xml :

<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:valueFrom="-1.0"
    android:valueTo="0"
    android:propertyName="xFraction"
    android:duration="@android:integer/config_mediumAnimTime" />

Animasyon yaptığınız nesne üst nesnesi ile aynı genişlikte değilse, işlerin tam olarak doğru görünmeyeceğini, bu nedenle kullanım durumunuza uyacak şekilde mülk uygulamanızı değiştirmeniz gerekebileceğini unutmayın.


8
Fade_in ve fade_out çalışmak için var, ancak / res / animator diğerleri hata veriyor. Ve bunların hiçbiri içeri kaymak ve dışarı kaymak için bile görünmüyor. Bunu yapmak için kendi xml yazmak için çalıştım, ama ben sonuçta tüm parçaları üstüne parçaları. Biraz daha yardım lütfen?
Dave MacLean

Peki ya çeviri? XML'de tanımlanmış bir objectAnimator'da yüzde değeri olan bir çeviri nasıl yapılır, lütfen? Ben xml içinde tanımlamak dikey slayt animasyonlar ile saygısız sırasında animasyon AdapterViewFlipper başarılı olmadı ...
GBouerat

6
11-19 10: 27: 50.912: W / PropertyValuesHolder (23107): Yöntem sınıfıXFraction () ile android.widget.FrameLayout hedef sınıf sınıfında bulunamadı. Ama benim XML benim özel görünüm MyFrameLayout var. Herhangi bir fikir?
barkside

13
Aslında Roma, tavsiye de başka bir yol gitmek gerekir: Destek Kitaplığı kullanırken, eski animasyon FragmentTransaction.setCustomAnimations ao ile çerçeve (android.R.anim) kullanmak gerekir
PJV

1
@RomanNurik bu cevap çoğu cihazda harika çalıştı, ancak bazı kullanıcılar için (özellikle bazı Samsung Galaxy S3 / 4 telefonlarda) animasyonlar sırasında genişlik herhangi bir nedenle rapor edilmedi ve parçanın asla görünmemesine neden oldu. Burada gösterildiği gibi bir OnPredrawListener kullanan kullanıcılar için çalışmayı başardım: mavyasoni9891.blogspot.com/2014/06/…
ajpolt

188

Bu şekilde yaptım:

Bunu ekle yöntemi ile parçaları yerine sahip Animasyonlar :

public void replaceFragmentWithAnimation(android.support.v4.app.Fragment fragment, String tag){
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
    transaction.replace(R.id.fragment_container, fragment);
    transaction.addToBackStack(tag);
    transaction.commit();
}

Yapmak zorunda eklemek dört animasyonlar içinde anim klasörün ilişkilendirmek ile kaynak :

enter_from_left.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromXDelta="-100%" android:toXDelta="0%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="700"/>
</set>

exit_to_right.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromXDelta="0%" android:toXDelta="100%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="700" />
</set>

enter_from_right.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromXDelta="100%" android:toXDelta="0%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="700" />
</set>

exit_to_left.xml :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">
    <translate
        android:fromXDelta="0%" android:toXDelta="-100%"
        android:fromYDelta="0%" android:toYDelta="0%"
        android:duration="700"/>
</set>

Çıktı:

resim açıklamasını buraya girin

Yapıldı .


14
Harika bir çözüm. Ancak yol tariflerini neden RTL'ye değiştirdiğinizden emin değilim. .setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right)
Yöntemim

2
Müthiş bir çözüm. Benzer yaklaşım ve aynı animasyon dosyaları, etkinlikler arasındaki geçişler için çalışır.
Stan

1
@MikeZriel, res -> anim -> xml'nizi buraya koyun
Hiren Patel

3
Teşekkürler Hiren, hızı (700) (300) olarak daha iyi ve daha çok iOS gibi değiştiriyorum
Mike Zriel

3
LOL, çözümle geri döndüm. Her java sınıfında android.app.fragment ve FragmentManager'ı içe aktarıyordum. Bazı materyalleri kontrol ettikten sonra, 'setCustomAnimations ()' kullanmanın içe aktarılması için android.support.v4 kütüphanesine ihtiyacı olduğunu gördüm. 'support.v4.app' olması gerektiğini söylemek önemlidir! Tüm yöntemleri 'getFragmentManager ()' ile 'getSupportFragmentManager ()' ve 'android.sapport.v4.app ....' 'ye aktardı. animasyon çarpışma olmadan iyi çalışmaya başladı ... Eğer benzer durumlarda sıkışıp kalırsanız, benim çözüm okuyun.
Teşekkürler

58

Kendinizi sadece Lollipop'a ve daha sonra bağlayabiliyorsanız, bu hile yapar gibi görünüyor:

import android.transition.Slide;
import android.util.Log;
import android.view.Gravity;
.
.
.
f = new MyFragment();
f.setEnterTransition(new Slide(Gravity.RIGHT));
f.setExitTransition(new Slide(Gravity.LEFT));
getFragmentManager()
    .beginTransaction()
    .replace(R.id.content, f, FRAG_TAG)  // FRAG_TAG is the tag for your fragment
    .commit();

Bu yardımcı olur umarım.


1
Bu Lollipop'ta başaracak olsa da, Lollipop'u çalıştıran cihazın yüzdesi ihmal edilebilir olduğundan (şu anda Android cihazların% 1.6'sı Lollipop kullanıyor) neredeyse hiç pratik değil.
Eran Goldin

1
new Slide(...): çağrı API düzey 21 gerektirir
Chintan Soni

getKey () ne anlama geliyor?
Alvaro

13
@EranGoldin Hiçbir şey sonsuza kadar sürmez .. Bugün sadece Android 2.0 ve üstü bir çözümde alay eder misiniz?
Tom

@Tam bir noktan var. Ancak uygulamanız geniş bir kullanıcı tabanına sahip olduğunda, yalnızca API düzeyini çarpamazsınız. Kullanıcılarınızın çoğu artık uygulamanızı artık çalıştıramazsa, bu hiç bir çözüm değildir.
Eran Goldin

47

Nurik bireyin cevabı çok yardımcı oldu, ama ben bulana kadar çalışmaya alamadım bu . Kısacası, uyumluluk kütüphanesini (örneğin, FragmentManager yerine SupportFragmentManager) kullanıyorsanız, XML animasyon dosyalarının sözdizimi farklı olacaktır.


28

İşte fragmanlar arasında bir slayt giriş / çıkış animasyonu:

FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.animator.enter_anim, R.animator.exit_anim);
transaction.replace(R.id.listFragment, new YourFragment());
transaction.commit();

Bir objectAnimator kullanıyoruz.

İşte animatör alt klasöründeki iki xml dosyası .

enter_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set>
     <objectAnimator
         xmlns:android="http://schemas.android.com/apk/res/android"
         android:duration="1000"
         android:propertyName="x"
         android:valueFrom="2000"
         android:valueTo="0"
         android:valueType="floatType" />
</set>

exit_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set>
    <objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:duration="1000"
        android:propertyName="x"
        android:valueFrom="0"
        android:valueTo="-2000"
        android:valueType="floatType" />
</set>

Umarım bu birisine yardım eder.


37
görünümü 2000 piksel için taşımak, çok çirkin bir çözümdür.
carlo.marinangeli

4
Exit_anim benim için sadece ekranın "açılır", ekran boyunca geri canlandırmaz. Herhangi bir fikir? Ben kullanıyorum.setCustomAnimations(R.animator.slide_in_left, R.animator.slide_out_right, R.animator.slide_in_left, R.animator.slide_out_right)
Bay Pablo

@MrPablo, muhtemelen yukarıdaki kodu kopyalamamış olmanızdır. replace yönteminden önce setCustomAnimations çağrılmalıdır.
Galya

Bu durumda, diğer parçayı animasyonla değiştirirsem ve animasyonu zaman aşımı veya tekrar tekrar uygulamaya dönmeden hemen önce uygulamayı en aza indirirsem, önceki parçayı ve geçerli parçayı paralel olarak görüntüler.
Prens

23

Yakalanan herkes için, işlemi oluştururken değiştirme / ekleme çağrısından önce setCustomAnimations'ın çağrıldığından emin olun.


12

FragmentTransaction'ın Android SDK uygulaması bir Animatorsüre destek kütüphanesi istiyor Animation, nedenini sorma ama strangeluk'un yorumundan sonra android 4.0.3 kod ve destek kütüphanesine baktım. Android SDK kullanımları loadAnimator()ve destek kitaplığı kullanımlarıloadAnimation()


7

Bu basit ve oruçlu çözümü kullanmayı deneyin. Android bazı varsayılan animationayarlar sağlar.

fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

Çıktı:

resim açıklamasını buraya girin


Vay be .. Bu kabul edilen cevap olmalı !! Basit ve zarif bir çözüm. Diğerlerine göre çok pürüzsüz cevaplar gösteriyor
Chathura Buddhika
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.