Jectpack -- Navigation了解与简单使用

news2025/7/16 19:03:09

简介

Navigation是一个可简化的Android导航的库和插件,换句话说,Navigation是用来规范管理Fragment的切换的,并且是通过可视化的方式来进行管理的。

![[Pasted image 20230210083913.png]]在这里插入图片描述

正常的跳转方法(其实有kotlin以后,代码精简了不少, 代码量与navigation没有太大区别)

// 跳转 activity
val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", "value")
startActivity(intent)
// 跳转 fragment
supportFragmentManager.commit {
    addToBackStack(null)
    val args = Bundle().apply { putString("key", "value") }
    replace<WelComeFragment>(R.id.container, args = args)
}

曾经可能遇到的问题,在Navigation中可以清晰的解决

  1. 如何在每个界面快捷加上跳转动画?
  2. 当你接手一个较大的项目,如何能快速理清界面间的跳转关系?
  3. 在单 activity 的项目中,如何控制几个相关的 fragment 有着相同的 ViewModel 作用域,而不是整个 activity 共享的viewmodel ?

从基本使用来了解Navigation的各项优点

1.引入依赖

dependencies {
  def nav_version = "2.5.3"

  // Java
  implementation "androidx.navigation:navigation-fragment:$nav_version"
  implementation "androidx.navigation:navigation-ui:$nav_version"

  // Kotlin
  implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
  implementation "androidx.navigation:navigation-ui-ktx:$nav_version"

}

1.创建导航图

优势之一导航图,清晰理清页面之间联系
导航图是一种资源文件,其中包含所有目的地和操作。该图表会显示应用的所有导航路径。
示例:
![[navigation-graph_2x-callouts.png]]
在这里插入图片描述

1. “目的地”是指应用中的不同内容区域。
2. “操作”是指目的地之间的逻辑连接,表示用户可以采取的路径

如需向项目添加导航图,请执行以下操作:
1. 在Project窗口中,右键点击res目录,然后依次选择 New > Android Resource File。此时系统会显示 New Resource File 对话框。
2. 在 File name 字段中输入名称,例如“nav_graph”。
3. 从 Resource type下拉列表中选择 Navigation,然后点击 OK

我们创建三个Fragment来演示效果,并梳理跳转逻辑
- WelcomeFragment
- LoginFragment
- RegisterFragment

添加图表后,在 Navigation Editor 中,可以直观地修改导航图,或直接修改底层 XML代码。
![[nav-editor-2x.png]]
在这里插入图片描述

1.  **Component Tree**:列出了导航宿主和目前位于 **Graph Editor** 中的所有目的地。
2.  **Graph Editor**:包含导航图的视觉表示形式。可以在 **Design** 视图和 **Text** 视图中的底层 XML 表示形式之间切换。
3.  **Attributes**:显示导航图中当前所选项的属性。在此面板中可以进行多种操作:
	- 创建Fragment
	- 拖动设置跳转关系
	- 页面切换动画
	- 页面之间传递参数
	- 页面之间跳转关系与处理

xml代码中,创建的元素标签分别对应

** fragment > Fragment **
** activity > Activity **
** dialog > DialogFragment **

将某个屏幕指定为起始目的地

Navigation Editor 使用房子图标 表示起始目的地。

连接目的地

  1. Design 标签页中,将鼠标悬停在目的地的右侧,该目的地为希望用户从中导航出来的目的地。该目的地右侧上方会显示一个圆圈。

  2. 点击希望用户导航到的目的地,并将光标拖动到该目的地的上方,然后松开。这两个目的地之间生成的线条表示 "操作"

  3. 点击箭头以突出显示该操作。此时 Attributes 面板中会显示以下属性:

  • ID 字段包含该操作的 ID。
  • Destination 字段包含目的地 Fragment 或 Activity 的 ID。
  1. 同时还可以设置跳转时候的动画, 有一些默认的可以选择, 也可以自定义

2. 向 Activity 添加 NavHost

导航宿主是 Navigation 组件的核心部分之一。导航宿主是一个空容器,用户在应用中导航时,目的地会在该容器中交换进出。

导航宿主必须派生于 NavHost。Navigation 组件的默认 NavHost 实现 (NavHostFragment) 负责处理 fragment 目的地的交换。

通过 XML 添加 NavHostFragment

新建MainActivity的xml中创建如下代码

<?xml version="1.0" encoding="utf-8"?>  
<androidx.constraintlayout.widget.ConstraintLayout    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:layout_width="match_parent"    
android:layout_height="match_parent"   
tools:context=".MainActivity">    

<androidx.fragment.app.FragmentContainerView     																																				   android:id="@+id/nav_host_fragment"        android:name="androidx.navigation.fragment.NavHostFragment"       
android:layout_width="0dp"   																																																																																													android:layout_height="0dp"        
app:layout_constraintLeft_toLeftOf="parent"        
app:layout_constraintRight_toRightOf="parent"        
app:layout_constraintTop_toTopOf="parent"        app:layout_constraintBottom_toBottomOf="parent"        																																																																																														 app:defaultNavHost="true"        																																																																																														app:navGraph="@navigation/nav_graph"/>
  
</androidx.constraintlayout.widget.ConstraintLayout>
  • android:name 属性包含 NavHost 实现的类名称, 使用NavHostFragment 就可以。
  • app:navGraph 属性将 NavHostFragment 与导航图相关联。
  • app:defaultNavHost="true" 确保 NavHostFragment 会拦截系统返回按钮。

3. 页面之间的跳转与传参

导航到目的地是使用 NavController 完成的, 如需检索 Fragment、Activity 或视图的 NavController,请使用以下某种方法:
Kotlin

  • Fragment.findNavController()
  • View.findNavController()
  • Activity.findNavController(viewId: Int)

Java

  • NavHostFragment.findNavController(Fragment)
  • Navigation.findNavController(Activity, @IdRes int viewId)
  • Navigation.findNavController(View)

例如在WelcomeFragment中,点击button跳转到LoginFragment

view.findViewById<Button>(R.id.go_login).setOnClickListener { 
	//携带参数跳转
    val args = Bundle()  
    args.putString("safeArg","dataFromWelComeFragment")  findNavController().navigate(R.id.action_welcomeFragment_to_loginFragment,args)
    
	// 普通跳转
	val action = WelcomeFragmentDirections.actionWelcomeFragmentToLoginFragment() 
	findNavController().navigate(action)


	//使用safe arg跳转
     val action = WelcomeFragmentDirections.actionWelcomeFragmentToLoginFragment(safeArg = "dataFromWelComeFragment")  
            findNavController().navigate(action)  
        }

元素共享

先看示例图,大家肯定见过这种效果,在页面切换时,一个动画使一个元素动画过渡到第二个页面

![[GIF.gif]]
在这里插入图片描述

起始页面和目标页面的xml中增加ImageView 增加transitionName参数

<ImageView  
    android:id="@+id/userAvatarIv"  
    android:transitionName="userAvatarTn"  
    android:layout_width="100dp"  
    android:layout_height="100dp"  
    android:src="@mipmap/ic_launcher"  
    android:layout_gravity="center"/>

在目标Fragment中的onCreate()中设置sharedElementEnterTransition

sharedElementEnterTransition = TransitionInflater.from(requireContext()).inflateTransition(R.transition.shared_image)

xml中新建transition文件夹与xml文件

<?xml version="1.0" encoding="utf-8"?>  
<transitionSet xmlns:android="http://schemas.android.com/apk/res/android">  
    <autoTransition android:duration="400"/>  
</transitionSet>

Fragment 目的地的共享元素过渡

val extras = FragmentNavigatorExtras(userAvatarIv to "userAvatarTn")  //首先创建一个extras
  
view.findNavController().navigate(    
R.id.confirmationAction,    
null, // Bundle of args    
null, // NavOptions    
extras)

Activity 目的地的共享元素过渡

import android.util.Pair as UtilPair  
...  
val options = ActivityOptionsCompat.makeSceneTransitionAnimation(activity,        UtilPair.create(userAvatarIv, "userAvatarTn"))  

val extras = ActivityNavigatorExtras(options)  
view.findNavController().navigate(    
R.id.details,    
null, // Bundle of args    
null, // NavOptions    
extras)

DeepLink

创建显式深层链接

通常用于闹钟,通知
显式深层链接是深层链接的一个实例,该实例使用 PendingIntent 将用户转到应用内的特定位置。例如,您可以在通知或应用 widget 中显示显式深层链接。

当用户通过显式深层链接打开您的应用时,任务返回堆栈会被清除,并被替换为相应的深层链接目的地。当嵌套图表时,每个嵌套级别的起始目的地(即层次结构中每个 <navigation> 元素的起始目的地)也会添加到相应堆栈中。也就是说,当用户从深层链接目的地按下返回按钮时,他们会返回到相应的导航堆栈,就像从入口点进入您的应用一样。

您可以使用 NavDeepLinkBuilder 类构造 PendingIntent,如以下示例所示。请注意,如果提供的上下文不是 Activity,构造函数会使用 PackageManager.getLaunchIntentForPackage() 作为默认 activity 启动(如有)。

val pendingIntent = NavDeepLinkBuilder(context)    
.setGraph(R.navigation.nav_graph)    
.setDestination(R.id.android)    
.setArguments(args)    
.createPendingIntent()

默认情况下,NavDeepLinkBuilder 会将显式深层链接启动到应用清单中声明的默认启动 Activity。如果您的 NavHost 在其他 activity 中,则您必须在创建深层链接建立工具时指定其组件名称:

val pendingIntent = NavDeepLinkBuilder(context)    
.setGraph(R.navigation.nav_graph)    
.setDestination(R.id.android)    
.setArguments(args)   
.setComponentName(DestinationActivity::class.java)   
.createPendingIntent()
创建隐式深层链接
  1. 进入导航图**Design > Deep Links** 点击 + 添加
  2. 填入对应参数,生成代码,注意参数可以对应<argument>标签
<fragment  
    android:id="@+id/registerFragment"  
    android:name="com.example.navigationdemo.normal.RegisterFragment"  
    android:label="fragment_register"  
    tools:layout="@layout/fragment_register">  
    <argument  
        android:name="name"  
        android:defaultValue="defaultValue name"  
        app:argType="string" />  
    <argument  
        android:name="age"  
        android:defaultValue="defaultValue 1"  
        app:argType="string" />  
    <deepLink  
        app:mimeType="*/*"  
        app:uri="https://aa.bb.com/rgsFragment/{name}/{age}" />  
</fragment>
  1. Manifest.xml中,在添加设置的fragment所属的Activity下,增加代码<nav-graph android:value="@navigation/nav_graph"/>
<activity  
    android:name=".normal.LoginActivity"
    android:exported="true">  
    <intent-filter>  
        <action android:name="android.intent.action.MAIN" />  
  
        <category android:name="android.intent.category.LAUNCHER" />  
    </intent-filter>  
  
    <meta-data  
        android:name="android.app.lib_name"  
        android:value="" />  
    <nav-graph android:value="@navigation/nav_graph"/>  
</activity>

例如在html中可以跳转app相对应页面,并且保持返回时,按照设置的栈顺序返回

<!DOCTYPE html>
<html>
	<head>
		<title>跳转测试</title>
		<meta http-equiv="content-type" content="text/html;charset=utf-8">
	</head>
	<body>
		<a href="https://aa.bb.com/rgsFragment/tom/25" style="font-size: 60px;"> 点击跳转</a>
	</body>
</html>

ps:官网的介绍是这样,但是我没有跳转成功,没有找到问题点

全局操作

可以使用全局操作来创建可由多个目的地共用的通用操作。例如,您可能想要不同目的地中的多个按钮导航到同一应用主屏幕

在 Navigation Editor 中,全局操作由一个指向相关联目的地的小箭头表示,如图 1 所示。

创建全局操作

如需创建全局操作,请执行以下操作:

  1. Graph Editor 中,点击一个目的地,使其突出显示。
  2. 右键点击该目的地,以显示上下文菜单。
  3. 依次选择 Add Action > Global。此时系统会在该目的地左侧显示一个箭头 ()。
  4. 点击 Text 标签页,以转到 XML 文本视图。全局操作的 XML 文本大致如下所示:
    ![[Pasted image 20230209163701.png]]
    在这里插入图片描述

使用全局操作

view.findNavController().navigate(R.id.action_global_mainFragment)

就是调用这个最外层的action事件

返回

Android 会维护一个返回堆栈,其中包含您之前访问过的目的地。当用户打开您的应用时,应用的第一个目的地就放置在堆栈中。每次调用 navigate() 方法都会将另一目的地放置到堆栈的顶部。点按向上返回会分别调用 NavController.navigateUp()NavController.popBackStack() 方法,用于移除(或弹出)堆栈顶部的目的地。

会返回一个布尔值,表明它是否已成功返回到另一个目的地。当返回 false 时,最常见的情况是手动弹出图的起始目的地。

如果popBackStack()方法返回 false,不会保留栈内的信息,则 NavController.getCurrentDestination() 会返回 null
如果navigateUp()方法返回 false,会在栈内保留最后一个不清空,则 NavController.getCurrentDestination() 不会返回 null

popUpTo 和 popUpToInclusive

首先看图
![[navigation-getting-started-pop.png]]
在这里插入图片描述

这是一种使用场景,比如 ** 首页 > 登录 > 注册 > 再到首页**
在注册成功回到首页时, 需要干掉登录和注册页
但是正常的跳转会是堆栈堆叠, 对战中会有多个重复页面

这时可以这样操作

<fragment    
		  android:id="@+id/注册"    
		  android:name="com.example.myapplication.注册"    
		  android:label="fragment_注册"    
		  tools:layout="@layout/fragment_注册">    
		  <action        
		  android:id="@+id/action_注册_to_首页"        
		  app:destination="@id/首页"        
		  app:popUpTo="@+id/首页"        
		  app:popUpToInclusive="true"/> 
</fragment>

popUpTo 首页,也就是说我们会在导航过程中从堆栈中移除 登录 和 注册。利用 app:popUpToInclusive="true",我们还会将第一个 首页 从堆栈上弹出,从而有效地清除它。请注意,如果不使用 app:popUpToInclusive,则返回堆栈会包含目的地 首页 的两个实例。

safe Args

什么是 Safe Args?

定义

它是一个 Gradle 插件,可以根据 navigation 文件生成代码,帮助开发者安全地在 Destination(目的地) 之间传递数据

那么为什么要设计这样一个插件呢?

我们知道使用 bundle 或者 intent 传递数据时,如果出现类型不匹配或者其他异常,是在 Runtime 中才能发现的(传递了string,接收时误写成int)

Safe Args 把校验转移到了编译期

先看看简单的使用

使用 Safe Args 需要手动引入插件

buildscript {
    repositories {
        google()
    }
    dependencies {
        def nav_version = "2.3.0-alpha06"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}

并且需要加入
plugins {  
	//kotlin
   id 'androidx.navigation.safeargs.kotlin'  
   //java
   id 'androidx.navigation.safeargs'  
}

1.配置参数

<navigation>-<fragment>-<action>标签中配置,我们加入<argument> 标签

<argument  
    android:name="safe_arg"  
    android:defaultValue="123"  
    app:argType="string" />



argType支持以下类型

![[62a747e1aa77950de9f703c38fc96b30.png]]
在这里插入图片描述

<argument>也可以放在<fragment>标签下,也可以放在根标签下,但前提是根标签必须有id,放在根标签下通常认为是作为通用参数

2.发送方(WelcomeFragment)

val action = WelcomeFragmentDirections.actionWelcomeFragmentToLoginFragment("safeArg,success")  
findNavController().navigate(action)

3.接收方(LoginFragment)
可以使用getArgument(),像普通fragment一样接收参数

arguments?.let { 
    val safeArg = it.getString("safe_arg")  
}

如果使用的是-ktx依赖, 还可以使用 by navArgs() 属性委托来访问参数
需要在navigation.xml中配置一下接收方的argument数据

<fragment  
    android:id="@+id/loginFragment"  
    android:name="com.example.navigationdemos.LoginFragment"  
    android:label="fragment_login"  
    tools:layout="@layout/fragment_login">  
    <action  
        android:id="@+id/action_loginFragment_to_registerFragment"  
        app:destination="@id/registerFragment" />  
    <argument  
        android:name="safe_arg"  
        android:defaultValue="123"  
        app:argType="string" />  
</fragment>

接收:



val args: LoginFragmentArgs by navArgs()  
  
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 
		val safeArg = args.safeArg
}

需要注意的一个小点 当跳转和目标不匹配时,起始Fragment的Directions会把两个参数都编译进去,但是目标Fragment的Directions还是只会编译自己有的`

归结到底,其实就是把<argument> 参数生成了一个类, 可以通过参数的方式来设置和获取,避免手写失误

至此一个简单的demo就完成了

PS: 一小些拓展问题

是否支持跳转后的callback(startActivityForResult)

目前在Navigation中没有支持,但是可以使用Fragment的方法
setFragmentResultsetFragmentResultListener

//起始
setFragmentResultListener("key") { key, bundle ->  
    Log.d(TAG, "setFragmentResultListener: $key ${bundle.getString("key123")}" ) 
}

//目标fragment
val bundle = Bundle()  
bundle.putString("key123","resultsuccessful")  
setFragmentResult("key",bundle)

嵌套Fragment

Navigation是一个可视化的逻辑清晰的"导航"依赖,不能做两个Fragment的嵌套操作

嵌套导航图

场景: 登录页面Activity需要有登录-注册-隐私协议等跳转逻辑,进入首页后,可能也希望在首页Activity可以做登录逻辑, 所以可以复用相关导航图

![[7ccbf594f7834fa6934733d71defbf91.png]]
在这里插入图片描述

也可以抽出来 用include标签包含此导航
![[2432cd1570ff444abcb2928801f0ecba.png]]
在这里插入图片描述

是否可以不使用replace方式切换

可以自己改,但是推荐使用ViewModel+LiveData来保存数据

ViewModel作用域

全局性参数

activityViewModels

局部性参数

navGraphViewModels
navGraphViewModels的ViewModel对应范围为 graph的范围,只要存在于图范围的Fragment未被销毁,viewmodel就不会被销毁

private val viewModel: ShareViewModel by navGraphViewModels(R.id.nav_graph)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/361673.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【性能测试基础】,从0到实战(手把手教,非常实用)

一、性能基础什么是性能测试--->本质?基于协议来模拟用户发送的请求&#xff08;业务模拟&#xff09;&#xff0c;对服务器形成一定负载。关注点&#xff1a;时间性能、空间性能与界面无关性能测试分类性能测试&#xff08;狭义&#xff09;性能测试方法是通过模拟生产环境…

【C++】多线程

多任务处理有两种形式&#xff0c;即&#xff1a;多进程和多线程。 基于进程的多任务处理是程序的并发执行。基于线程的多任务处理是同一程序的片段的并发执行 文章目录1. 多线程介绍2. Windows多线程1. 多线程介绍 每一个进程&#xff08;可执行程序&#xff09;都有一个主线…

AcWing1027. 方格取数

AcWing1027. 方格取数设有 NN 的方格图&#xff0c;我们在其中的某些方格中填入正整数&#xff0c;而其它的方格中则放入数字0。如下图所示&#xff1a;某人从图中的左上角 A 出发&#xff0c;可以向下行走&#xff0c;也可以向右行走&#xff0c;直到到达右下角的 B 点。在走过…

SpringBoot+Vue前后端分离管理系统02:前端

前端环境搭建 1、node环境 C:\Windows\system32>node -v v12.13.0C:\Windows\system32>npm -v 6.12.0 2、下载vue-admin-template 官网&#xff1a;介绍 | vue-element-admin 项目初始化 1、安装依赖 在刚才下载的vue-admin-template-4.4.0目录下以管理员方式运行c…

Robot Framework + Selenium2Library环境下,结合Selenium Grid实施分布式自动化测试

最近一段时间&#xff0c;公司在推行自动化测试流程&#xff0c;本人有幸参与了自定义通用控件的关键字封装和脚本辅助编写、数据驱动管理、测试用例执行管理等一系列工具软件的研发工作&#xff0c;积累了一些经验&#xff0c;在此与大家做一下分享&#xff0c;也算是做一个总…

SQL零基础入门学习(四)

SQL零基础入门学习&#xff08;三&#xff09; SQL INSERT INTO 语句 INSERT INTO 语句用于向表中插入新记录。 SQL INSERT INTO 语法 INSERT INTO 语句可以有两种编写形式。 第一种形式无需指定要插入数据的列名&#xff0c;只需提供被插入的值即可&#xff1a; INSERT …

ImageCombiner设计源码详解

前言在前面的博客中介绍了一款Java的海报生成器ImageCombiner,原文地址&#xff1a;拿来就用的Java海报生成器ImageCombiner&#xff08;一&#xff09;&#xff0c;在博文中简单介绍了一下代码以及一个真实的生成案例。但是对源码的介绍不多&#xff0c;本文就针对源码进行深入…

vs2022 x64 C/C++和汇编混编

vs2022环境x64 C/C和汇编混编vs64位程序不支持__asm内嵌汇编&#xff0c;需要单独编写汇编源文件示例如下1、新建空的win32项目&#xff0c;新建main.cpp&#xff0c;示例代码如下2、新建asm64.asm汇编源文件&#xff0c;示例代码如下3、编译器配置&#xff0c;选择x64&#xf…

【编程入门】应用市场(uni-app版)

背景 前面已输出多个系列&#xff1a; 《十余种编程语言做个计算器》 《十余种编程语言写2048小游戏》 《17种编程语言10种排序算法》 《十余种编程语言写博客系统》 《十余种编程语言写云笔记》 《N种编程语言做个记事本》 目标 为编程初学者打造入门学习项目&#xff0c;使…

华为OD机试 - 最短木板长度(C++) | 附带编码思路 【2023】

刷算法题之前必看 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12199283.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 华为OD机试题…

PowerJob容器的前世,容器是如何产生,如何上传到Server上去的

这不仅仅是一篇PowerJob源码分析的文章&#xff0c;还有很多的java基础知识&#xff0c;在实践中学习效果更好&#xff0c;感兴趣就留下来交流一下吧。 power容器虽然说是容器&#xff0c;但并不是docker容器&#xff0c;仅仅就是java的jar包 &#xff0c;可以通过框架下载一套…

手工测试混了5年,年底接到了被裁员的消息....

大家都比较看好软件测试行业&#xff0c;只是因为表面上看起来&#xff1a;钱多事少加班少。其实这个都是针对个人运气好的童人才会有此待遇。在不同的阶段做好不同阶段的事情&#xff0c;才有可能离这个目标更近&#xff0c;作为一枚软件测试人员&#xff0c;也许下面才是我们…

阿里5年,一个女工对软件测试的理解

成为一个优秀的测试工程师需要具备哪些知识和经验&#xff1f; 针对这个问题&#xff0c;可以直接拆分以下三个小问题来详细说明&#xff1a; 1、优秀软件测试工程师的标准是什么&#xff1f; 2、一个合格的测试工程师需要具备哪些专业知识&#xff1f; 3、一个合格的测试工程…

介绍Kadence Elements元素模板:按您的方式设计网站

随着 Kadence Pro 1.0.4 和 Kadence Blocks Pro 1.5.8 的发布&#xff0c;Kadence 团队很高兴地宣布推出最强大的新方法&#xff0c;帮助网站所有者使用 Kadence Elements Templates 创建动态和高度定制的 WordPress 网站。如果您曾经创建过 WordPress 网站&#xff0c;并且发现…

Fiddler的简单使用

目录 1.断点应用 2.网络限速测试 2.1.为什么需要弱网测试 2.2.Fiddler弱网测试配置 1.断点应用 通过断点功能&#xff0c;可以在测试时方便的篡改request&#xff0c;response以达到测试的目的&#xff0c;如果&#xff1a;在请求头中的参数修改成错误的&#xff0c;或在响应…

强化学习DQN之俄罗斯方块

强化学习DQN之俄罗斯方块强化学习DQN之俄罗斯方块算法流程文件目录结构模型结构游戏环境训练代码测试代码结果展示强化学习DQN之俄罗斯方块 算法流程 本项目目的是训练一个基于深度强化学习的俄罗斯方块。具体来说&#xff0c;这个代码通过以下步骤实现训练&#xff1a; 首先…

2023最新网络工程师HCIA-Datacom“1000”道题库,光速刷题拿证

HCIA认证是华为认证体系的初级认证&#xff0c;可以说是网工进入IT行业的一张从业资格证&#xff01; HCIA-Datacom考试覆盖数通基础知识 包括 TCP/IP 协议栈基础知识&#xff0c;OSPF 路由协议基本原理以及在华为路由器中的配置实现&#xff0c;以太网技术、生成树、VLAN 原…

【Java 面试合集】final 以及finally 不同

final 以及finally 不同 1. 概述 嗨&#xff0c;大家好【Java 面试合集】又来了。今天给大家分享的主题是final 以及finally 不同. 很简单&#xff0c;但是确实很细节哦&#xff0c;好了废话不多说&#xff0c;让我们开始吧 2. final 首先我们要知道final 是一个修饰符&#x…

WordPress主题:知更鸟Begin5.2免授权版

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 HTML5CSS3响应式设计兼容IE8、Firefox、Chrome等现代浏览器。杂志布局、图片布局和博客布局后台切换 Wordpress主题 知更鸟Begin主题 无授权无加密独立页面模板 博客布局、随机文章、友…

总结:电容在电路35个基本常识

1 电压源正负端接了一个电容&#xff0c;与电路并联&#xff0c;用于整流电路时&#xff0c;具有很好的滤波作用&#xff0c;当电压交变时&#xff0c;由于电容的充电作用&#xff0c;两端的电压不能突变&#xff0c;就保证了电压的平稳。 当用于电池电源时&#xff0c;具有交流…