得意犹堪夸世俗,诏黄新湿字如鸦。这篇文章主要讲述Android Navigation使用相关的知识,希望能为你提供帮助。
简介
Navigation导航编辑器旨在简化android开发中导航的实现,可以帮助我们很好的处理Activity和fragment之间通过FragmentTransaction交互的复杂性,也可以很好的处理页面的转场效果;Deeplink的支持,绕过activity直接跳到fragment;并且传递参数更安全。在Android Studio3.2可以使用。
基本使用
- 引用相关依赖
implementation "
android.arch.navigation:navigation-fragment:1.0.0-rc01"
// use -ktx for Kotlin
implementation "
android.arch.navigation:navigation-ui:1.0.0-rc01"
- 创建资源文件
- 创建Fragment文件
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}页面"
}
}
- 创建navigation导航图
<
?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=https://www.songbingjia.com/android/"
主页"
/>
<
!--跳转动作-->
<
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>
- Activity布局文件添加fragment
<
?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>
【Android Navigation使用】在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()
}
}
- 配置Fragment的跳转
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) }//点击跳转时间
}
- 配置Fragment回退事件
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:startDestination
<
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>
- fragment/activity
- argument
<
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=https://www.songbingjia.com/android/"
足球"
/>
<
/fragment>
视图之间的参数传递属性,argType可以支持string、integer、reference,long,float,boolean和Parcelable对象等。增加属性之后需要Rebuild一下,IDE会生成相关视图的Args类。如:
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)
}
获取传递参数值
var args = arguments?.let { BallFragmentArgs.fromBundle(it) }
top_bar_title.text = args!!.topBarTitle
- action
<
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
<
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=https://www.songbingjia.com/android/"
@navigation/nav_graph2"
/>
<
/activity>
NavHostFragment
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中的应用程序导航。
推荐阅读
- Android BrocastReceiver解析
- 46 What Is Real Happiness ? 什么是真正的幸福 ()
- Android 各种进程
- Android Activity 生命周期
- Android Intent传递对象为什么要序列化()
- Android超时机制的处理(很不错)
- Appscanner实验还原code3
- 微服务之springboot 自定义配置Application.properties文件
- Android资源收集