Як слід реалізувати такий вид ковзання, який, наприклад, використовує клієнт Honeycomb Gmail?
Ви можете TransactionManager
впоратися з цим автоматично, додаючи та видаляючи фрагменти, це важко перевірити це через те, що емулятор є слайд-шоу :)
Як слід реалізувати такий вид ковзання, який, наприклад, використовує клієнт Honeycomb Gmail?
Ви можете TransactionManager
впоратися з цим автоматично, додаючи та видаляючи фрагменти, це важко перевірити це через те, що емулятор є слайд-шоу :)
Відповіді:
Щоб анімувати перехід між фрагментами або анімувати процес показу або приховування фрагмента, ви використовуєте Fragment Manager
для створення Fragment Transaction
.
У межах кожної фрагментальної транзакції ви можете вказати та вимкнути анімації, які будуть використовуватися для показу та приховування відповідно (або обох, коли використовується заміна).
Наступний код показує, як ви замінили б фрагмент, висунувши один фрагмент, а інший пересунувши на його місце.
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();
Щоб домогтися того ж, сховавши або показавши фрагмент, який ви просто зателефонували б ft.show
або ft.hide
, перейшовши у Фрагмент, який ви хочете відповідно показати або приховати.
Для довідки, для визначення анімації XML буде використано objectAnimator
тег. Приклад slide_in_left може виглядати приблизно так:
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:propertyName="x"
android:valueType="floatType"
android:valueFrom="-1280"
android:valueTo="0"
android:duration="500"/>
</set>
Якщо вам не потрібно користуватися бібліотекою підтримки, то подивіться на відповідь Романа .
Але якщо ви хочете використовувати бібліотеку підтримки, вам потрібно використовувати стару рамку анімації, як описано нижче.
Після консультацій з відповідями Рето та сліпого я отримав наступний код роботи.
Фрагменти виглядають ковзаючими праворуч і ковзаючи вліво при натисканні на спину.
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);
CustomFragment newCustomFragment = CustomFragment.newInstance();
transaction.replace(R.id.fragment_container, newCustomFragment );
transaction.addToBackStack(null);
transaction.commit();
Порядок важливий. Це означає, що ви повинні зателефонувати setCustomAnimations()
раніше, replace()
або анімація не набере чинності!
Далі ці файли потрібно розмістити у папці res / anim .
enter.xml :
<?xml version="1.0" encoding="utf-8"?>
<set>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="100%"
android:toXDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
exit.xml :
<set>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="-100%"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
pop_enter.xml :
<set>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="-100%"
android:toXDelta="0"
android:interpolator="@android:anim/decelerate_interpolator"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
pop_exit.xml :
<?xml version="1.0" encoding="utf-8"?>
<set>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0"
android:toXDelta="100%"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="@android:integer/config_mediumAnimTime"/>
</set>
Тривалість анімації можна змінити на будь-яке значення за замовчуванням, наприклад, @android:integer/config_shortAnimTime
або будь-яке інше число.
Зауважте, що якщо між замінами фрагментів відбувається зміна конфігурації (наприклад, обертання), дія зворотного погляду не анімується. Це задокументована помилка, яка все ще існує у версії 20 бібліотеки підтримки.
Я б радимо використовувати це замість створення файлу анімації, оскільки це набагато краще рішення. Android Studio вже пропонує за замовчуванням, який animation
ви можете використовувати, не створюючи жодного нового XML-файлу. Імена анімації - android.R.anim.slide_in_left та android.R.anim.slide_out_right, і ви можете використовувати їх наступним чином:
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();
Вихід:
Моя змінена бібліотека підтримки підтримує використання анімаційних зображень (тобто <translate>, <rotate>
) та аніматорів об'єктів (тобто <objectAnimator>
) для переходів фрагментів. Він реалізований разом з NineOldAndroids . Детальні відомості див. У моїй документації на github.
Щодо мене, мені потрібна диракація перегляду:
в -> проведіть праворуч
out -> проведіть пальцем вліво
Тут працює для мене код:
slide_in_right.xml
<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>
slide_out_left.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:fromXDelta="0" android:toXDelta="-50%p"
android:duration="@android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_mediumAnimTime" />
</set>
код транзакції:
inline fun FragmentActivity.setContentFragment(
containerViewId: Int,
backStack: Boolean = false,
isAnimate: Boolean = false,
f: () -> Fragment
): Fragment? {
val manager = supportFragmentManager
return f().apply {
manager.beginTransaction().let {
if (isAnimate)
it.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
if (backStack) {
it.replace(containerViewId, this, "Fr").addToBackStack("Fr").commit()
} else {
it.replace(containerViewId, this, "Fr").commit()
}
}
}
}
Я вирішую це внизу
Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment