Android Jetpack BottomNavigationView 如何应用自定义 Fragment Transition

Android Jetpack BottomNavigationView how to apply custom Fragment Transition

我想在 BottomNavigationView 更改其当前片段时添加新的片段转换。 我想从左到右进入下一个片段

我没有看到 Jetpack BottomNavigationView 添加自定义片段过渡动画,因为 BottomNavigationView 没有可用的操作。

根据this issue

NavigationUI follows the material design guidelines, which specifically calls [see the 'Transitions' section] for a cross fade animation between BottomNavigationView items.

Setting your own listener is indeed the correct approach if you want to deviate from the guidelines and what NavigationUI provides.

因此,您需要查看 NavigationUI source codeonNavDestinationSelected() 方法,并制作您自己的版本,传递您想要的自定义动画,从您自己的 OnNavigationItemSelectedListener.

我已经发布了这个问题,并且从ianhanniballake(我接受的答案)的回答中得到了很大的帮助,以满足我的期望。对于以后参考这个问题和答案的人,我进一步添加一些代码如下,以进一步参考和理解。 如果您在完成代码后需要任何帮助,请随时发表评论。

以下是我在 MainActivity.java" OnCreate() 方法

中的源代码
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final BottomNavigationView bottomNavigationView=findViewById(R.id.bottomNavigationView);
    final NavController navController= Navigation.findNavController(this,R.id.nav_host_fragment);
    selectedItem=R.id.firstFragment1;
    bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()){
                case R.id.firstFragment1:

                    if(selectedItem != R.id.firstFragment1){
                        selectedItem = R.id.firstFragment1;
                        navController.popBackStack();
                    }
                    break;
                case R.id.secondFragment1:
                    if(selectedItem != R.id.secondFragment1) {
                        selectedItem= R.id.secondFragment1;
                        Log.d("palvision.dev", "action to first fragment");
                        navController.navigate(R.id.action_firstFragment_to_secondFragment2);
                    }
                    break;
            }
            return true;
        }
    });
}

以下是我在nav_graph.xml中的源代码,它是导航图。

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/firstFragment">
<fragment
    android:id="@+id/firstFragment"
    android:name="com.dehan.myapplicationnavtest.FirstFragment"
    tools:layout="@layout/fragment_first" >
    <action
        android:id="@+id/action_firstFragment_to_secondFragment2"
        app:destination="@+id/secondFragment"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_left"
        app:popEnterAnim="@anim/enter_from_left"
        app:popExitAnim="@anim/exit_to_right" />
</fragment>
<fragment
    android:id="@+id/secondFragment"
    android:name="com.dehan.myapplicationnavtest.SecondFragment"
    tools:layout="@layout/fragment_second" />

以下是 FirstFragment.java

的代码
public class FirstFragment extends Fragment {

public FirstFragment() {
    // Required empty public constructor
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_first, container, false);
}

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

    Toolbar toolbar=view.findViewById(R.id.toolbar);
    NavController navController= Navigation.findNavController(getActivity(),R.id.nav_host_fragment);
    AppBarConfiguration appBarConfiguration =new AppBarConfiguration.Builder(navController.getGraph()).build();

    NavigationUI.setupWithNavController(toolbar,navController,appBarConfiguration);
}
}

以下是 SecondFragment.java

的代码
public class SecondFragment extends Fragment {

public SecondFragment() {
    // Required empty public constructor
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.fragment_second, container, false);
}
}

以下是 enter_from_right.xml 的代码,它位于 anim 文件夹中。 所有其他动画文件也放在 anim 文件夹中。

<?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="400" />

以下是 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="400"/>

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="400"/>

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="400" />