Заменить два фрагмента друг с другом с помощью анимации
Я только новичок в разработке Android. У меня есть приложение, в котором у меня есть фрагмент внутри действия. Этот фрагмент имеет заголовок, нижний колонтитул и посередине FrameLayout для отображения других фрагментов XML фрагмента:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:orientation="vertical"
tools:context=".fragments.Fragment1">
<!-- Dummy item for focus at startup -->
<LinearLayout
android:id="@+id/dummy_id"
android:orientation="vertical"
android:layout_width="0px"
android:layout_height="0px"
android:focusable="true"
android:focusableInTouchMode="true" />
<FrameLayout
android:id="@+id/header_section"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="@string/vehicle"
android:textAlignment="center"
android:textColor="@color/dark_grey_text"
android:textSize="@dimen/title_size" />
<ImageButton
android:id="@+id/closeBT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_margin="6dp"
android:background="@drawable/close_button_icon" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="top"
android:layout_marginTop="52dp"
android:background="@android:color/darker_gray" />
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/area_for_fragments"
android:layout_below="@+id/header_section"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp">
</FrameLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/white">
<LinearLayout
android:id="@+id/footerLL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_below="@+id/bottom_separator_line"
android:layout_marginTop="10dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="30dp"
android:visibility="gone">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="10dp"
android:text="@string/titular_infractor"
android:textColor="@color/grey_text"
android:textSize="@dimen/text_size"
android:textStyle="bold" />
</LinearLayout>
<ImageButton
android:id="@+id/accept_button"
android:visibility="visible"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_alignRight="@+id/bottom_separator_line"
android:layout_below="@+id/bottom_separator_line"
android:layout_marginBottom="10dp"
android:layout_marginLeft="3dp"
android:layout_marginRight="33dp"
android:layout_marginTop="-50dp"
android:background="@drawable/accept_button_selector" />
<ImageButton
android:id="@+id/cancel_button"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_below="@+id/bottom_separator_line"
android:layout_marginBottom="10dp"
android:layout_marginRight="3dp"
android:layout_marginTop="-50dp"
android:layout_toLeftOf="@+id/edit_vehicle_accept_button"
android:background="@drawable/cancel_button_selector"
android:visibility="gone"/>
<View
android:id="@+id/bottom_separator_line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentTop="true"
android:layout_marginBottom="55dp"
android:background="@android:color/darker_gray" />
</RelativeLayout>
Чтобы показать первый фрагмент, я использую childFragmentManager:
final FragmentTransaction ft = getChildFragmentManager().beginTransaction();
TestSearchFragment elf = new TestSearchFragment();
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.replace(R.id.area_for_fragments, elf);
ft.addToBackStack(null);
ft.commit();
Этот фрагмент должен быть просто размещен там в начале. После того, как я нажал на кнопку "Принять", первый фрагмент должен выскользнуть за пределы экрана, а новый, второй фрагмент должен соскользнуть снизу. Сейчас я использую этот код для их замены:
FragmentTransaction ft2 = getChildFragmentManager().beginTransaction();
TestDetailFragment elf2 = new TestDetailFragment();
ft2.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up);
ft2.replace(R.id.area_for_fragments, elf2);
ft2.addToBackStack("TEST FRAGMENT TAG")
.commit();
Но по любой причине фрагменты заменяются, и после этого начинается анимация. В то время как анимация продолжается, новый фрагмент выскальзывает за пределы экрана, а старый фрагмент скользит из нижней части экрана. После завершения анимации новый фрагмент отображается.
Мой код для анимации:
Slide_in_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate
android:duration="5000"
android:fromXDelta="0%"
android:toXDelta="0%"
android:fromYDelta="0%"
android:toYDelta="-100%"/>
</set>
slide_out_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate
android:duration="5000"
android:fromXDelta="0%"
android:toXDelta="0%"
android:fromYDelta="100%"
android:toYDelta="0%"/>
</set>
Я не знаю, как это исправить или какова причина этой сумасшедшей замены. Надеюсь, кто-нибудь может помочь. Спасибо
2 ответа
Вот правильное решение:
FragmentTransaction fragmentTransactionSearch = getChildFragmentManager().beginTransaction();
fragmentTransactionSearch.add(childSearchFragment, "SEARCH");
fragmentTransactionSearch.replace(R.id.area_for_fragments, childSearchFragment);
fragmentTransactionSearch.commit();
Это начало, чтобы поместить первый фрагмент в определенный <FrameLayout>
Если вы хотите заменить этот childFragment другим childFragment, используйте:
FragmentTransaction fragmentTransactionDetail = getChildFragmentManager().beginTransaction();
fragmentTransactionDetail.setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up, R.anim.slide_out_down, R.anim.slide_in_down);
fragmentTransactionDetail.remove(childSearchFragment);
fragmentTransactionDetail.add(childDetailFragment, "DETAIL");
fragmentTransactionDetail.replace(R.id.area_for_fragments, childDetailFragment);
fragmentTransactionDetail.addToBackStack("ShowDetail");
fragmentTransactionDetail.commit();
И как Экстра. Если вы хотите управлять функцией BackButtonFunction, вам необходимо перезаписать функцию OnBackPressed в parentFragment следующим кодом:
if(parentFragment.getChildFragmentManager().getBackStackEntryCount() > 0)
{ this.getChildFragmentManager().popBackStack(); }
Этот метод заменит фрагменты пользовательской анимацией,
private void flipToFragment(Fragment showFragment, Fragment hideFragment){
getFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.anim.card_flip_right_in, R.anim.card_flip_right_out,
R.anim.card_flip_left_in, R.anim.card_flip_left_out)
.hide(hideFragment)
.show(showFragment)
.commit();
}
Ниже будут размещены ресурсы анимации в res / anim,
- card_flip_left_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Before rotating, immediately set the alpha to 0. --> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:duration="0" /> <!-- Rotate. --> <objectAnimator android:valueFrom="-180" android:valueTo="0" android:propertyName="rotationY" android:interpolator="@android:interpolator/accelerate_decelerate" android:duration="@integer/card_flip_time_full" /> <objectAnimator android:valueFrom="0.0" android:valueTo="1.0" android:propertyName="alpha" android:startOffset="@integer/card_flip_time_half" android:duration="1" /> </set>
- card_flip_left_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Rotate. --> <objectAnimator android:valueFrom="0" android:valueTo="180" android:propertyName="rotationY" android:interpolator="@android:interpolator/accelerate_decelerate" android:duration="@integer/card_flip_time_full" /> <!-- Half-way through the rotation (see startOffset), set the alpha to 0. --> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:startOffset="@integer/card_flip_time_half" android:duration="1" /> </set>
- card_flip_right_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Before rotating, immediately set the alpha to 0. --> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:duration="0" /> <!-- Rotate. --> <objectAnimator android:valueFrom="180" android:valueTo="0" android:propertyName="rotationY" android:interpolator="@android:interpolator/accelerate_decelerate" android:duration="@integer/card_flip_time_full" /> <!-- Half-way through the rotation (see startOffset), set the alpha to 1. --> <objectAnimator android:valueFrom="0.0" android:valueTo="1.0" android:propertyName="alpha" android:startOffset="@integer/card_flip_time_half" android:duration="1" /> </set>
- card_flip_right_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Rotate. --> <objectAnimator android:valueFrom="0" android:valueTo="-180" android:propertyName="rotationY" android:interpolator="@android:interpolator/accelerate_decelerate" android:duration="@integer/card_flip_time_full" /> <!-- Half-way through the rotation (see startOffset), set the alpha to 0. --> <objectAnimator android:valueFrom="1.0" android:valueTo="0.0" android:propertyName="alpha" android:startOffset="@integer/card_flip_time_half" android:duration="1" /> </set>