Navigation导航编辑器旨在简化Android开发中导航的实现,能够帮助咱们很好的处理Activity和fragment之间经过FragmentTransaction交互的复杂性,也能够很好的处理页面的转场效果;Deeplink的支持,绕过activity直接跳到fragment;而且传递参数更安全。在Android Studio3.2能够使用。android
implementation "android.arch.navigation:navigation-fragment:1.0.0-rc01" // use -ktx for Kotlin implementation "android.arch.navigation:navigation-ui:1.0.0-rc01"
class IndexFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.index_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { IndexFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle txt_desc.text = "${args!!.topBarTitle}页面" } }
class BallFragment : Fragment() { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.ball_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { BallFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle txt_desc.text = "${args!!.topBarTitle}页面" } }
<?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/indexFragment"> <!-- app:startDestination是起始Destination,必须指定 --> <fragment android:id="@+id/indexFragment" android:name="com.fomin.demo.bar.IndexFragment" android:label="IndexFragment" tools:layout="@layout/index_fragment"> <!--参数传递--> <argument android:name="topBarTitle" app:argType="string" android:defaultValue="主页"/> <!--跳转动做--> <action android:id="@+id/action_indexFragment_to_ballFragment" app:destination="@id/ballFragment"/> </fragment> <fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"> <argument android:name="topBarTitle" app:argType="string" android:defaultValue="足球"/> </fragment> </navigation>
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment android:id="@+id/nav_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph"/> </LinearLayout>
在Activity中添加以下代码安全
class MainActivity2 : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main2) } override fun onSupportNavigateUp(): Boolean { return Navigation.findNavController(this, R.id.nav_fragment).navigateUp() } }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { IndexFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle btn_goto_ball.setOnClickListener { Navigation.findNavController(it).navigate(R.id.action_indexFragment_to_ballFragment) }//点击跳转时间 }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) var args = arguments?.let { BallFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle top_bar_back.visibility = if (args!!.showBack == 1) View.VISIBLE else View.GONE txt_desc.text = "${args!!.topBarTitle}页面" top_bar_back.setOnClickListener { Navigation.findNavController(it).popBackStack() }//回退事件 }
好了,Navigation入门讲解完了,上面代码对于Fragment 并不是是经过原生的 FragmentManager 和 FragmentTransaction 进行控制的,而是经过如下Navigation.findNavController(params)进行的控制。接下来会对Navigation详细讲解。app
此属性位于navigation 根节点上,是导航器默认加载在Activity的视图,是必须设置的。编辑器
<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/indexFragment"> <fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"/> </navigation>
navigation能够添加fragment和activity的视图,须要关注的属性android:id和android:name,name是所在Fragmet/Activity类所在包名,id就不解释了,众所周知。ide
使用参数传递,须要module的build.gradle添加:apply plugin: 'androidx.navigation.safeargs'布局
<fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"> <argument android:name="topBarTitle" app:argType="string" android:defaultValue="足球"/> </fragment>
视图之间的参数传递属性,argType能够支持string、integer、reference,long,float,boolean和Parcelable对象等。增长属性以后须要Rebuild一下,IDE会生成相关视图的Args类。如:gradle
public class BallFragmentArgs implements NavArgs { 省略.... @NonNull public String getTopBarTitle() { return (String) arguments.get("topBarTitle"); } 省略.... }
参数传递动画
btn_goto_ball.setOnClickListener { val bundle = Bundle() bundle.putString("topBarTitle", "篮球") Navigation.findNavController(it).navigate(R.id.action_indexFragment_to_ballFragment, bundle) }
获取传递参数值ui
var args = arguments?.let { BallFragmentArgs.fromBundle(it) } top_bar_title.text = args!!.topBarTitle
动做,即跳转动做,从视图A跳转到视图B的动做this
<fragment android:id="@+id/indexFragment" android:name="com.fomin.demo.bar.IndexFragment" android:label="IndexFragment" tools:layout="@layout/index_fragment"> <!--跳转动做--> <action android:id="@+id/action_indexFragment_to_ballFragment" app:destination="@id/ballFragment"/> </fragment>
app:destination的属性,声明了这个行为导航的目的地id为ballFragment的视图
android:id 这个id做为Action惟一的 标识,在视图类的某个点击事件中,咱们经过id指向对应的行为
btn_goto_ball.setOnClickListener { Navigation.findNavController(it).navigate(R.id.action_indexFragment_to_ballFragment) }
日常页面跳转都会使用到相关的转场动画,action也为转场动画提供了enterAnim、exitAnim、popEnterAnim、popExitAnim四个动画属性,能够设置相关的anim动画资源。
此外,还提供了一个app:popUpTo属性,它的做用是声明导航行为将返回到id对应的Fragment。
使用deep-link能够建立深层连接,相似activity的自定义URL使用Scheme方式来跳转,能够直接跳转到指定fragment/activity
<fragment android:id="@+id/ballFragment" android:name="com.fomin.demo.bar.BallFragment" android:label="BallFragment" tools:layout="@layout/ball_fragment"> <deepLink app:uri="http://www.fomin.com/login"/> </fragment>
在Manifest.xml添加规则
<activity android:name=".login.LoginActivity"> <nav-graph android:value="@navigation/nav_graph2"/> </activity>
NavHostFragment在布局中提供了一个区域,用于进行Navigation。
<fragment android:id="@+id/nav_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="match_parent" android:layout_height="match_parent" app:defaultNavHost="true" app:navGraph="@navigation/nav_graph2"/>
android:name指定NavHostFragment包名,必填项;app:navGraph指定navigation的资源文件;app:defaultNavHost="true"可确保NavHostFragment拦截系统“后退”按钮。 也能够在代码上设置,如:
override fun onSupportNavigateUp(): Boolean { return Navigation.findNavController(this, R.id.nav_fragment).navigateUp() }
navigation提供了Navigation和NavController的类;Navigation此类提供了用于从应用程序中的各个常见位置查找相关NavController实例的实用程序,或用于执行导航以响应UI事件的实用程序;而NavController管理NavHost中的应用程序导航。