3、Flutter项目搭建

news2024/11/17 10:53:37

一、搭建项目

1.1 搭建空壳项目

  • 接上篇的项目搭建、本篇将继续搭建各个界面.
  • 当BottomNavigationBar搭建起来后,在各个界面,没有显示对应的元素,因此我们在包含它的Scaffold中,添加body,这样让每个界面撑起来.每次点击就切换对应的界面.
    • 那么我们创建一个_RootPageState中的私有成员列表_pages,用来存放每个界面的Scaffold界面视图.
    • 在取值时通过currentIndex,获取列表中每个界面的视图._pages[_currentIndex] ;填充在总的Scaffold中.
class _RootPageState extends State<RootPage> {
    final List<Widget>_pages = [Scaffold(
      appBar: AppBar(title: Text("微信"),),
      body: const Center(child: Text("微信页面"),),
    ), Scaffold(
      appBar: AppBar(title: Text("通讯录"),),
      body: const Center(child: Text("通讯录界面"),),
    ), Scaffold(
      appBar: AppBar(title: Text("发现"),),
      body: const Center(child: Text("发现界面"),),
    ), Scaffold(
      appBar: AppBar(title: Text("我"),),
      body: const Center(child: Text("我的界面"),),
    )];
    //6.设置当前BarItems的默认选中Item, 当某一个被选中的时候,这个index值会发生变化.
    int _currentIndex = 0;
    @override
    Widget build(BuildContext context) {
      return  Container(
        child: Scaffold(
          body: _pages[_currentIndex],
          //2.bottomNavigationBar相当于iOS中的TabBar
          bottomNavigationBar: BottomNavigationBar(...),              
          ),
        );
    }
}
  • 填充之后,效果大概如下

1.2 替换填充的界面

  • 在lib文件夹下创建一个pages文件夹Directory,用来存放各个界面.
    • 依次创建chat_page、friends_page、discover_page、mine_page文件.为四个主界面
  • 在chat_page文件中创建一个ChatPage组件
import 'package:flutter/material.dart';

class ChatPage extends StatefulWidget {
  const ChatPage({Key? key}) : super(key: key);
  @override
  State<ChatPage> createState() => _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("通讯录"),
      ),
      body: const Center(child: 
        Text("通讯录界面"),
      ),
    );
  }
}
  • 来到rootpage中, 首先导入chat_page文件,
  • 然后将_pages中的第一个界面"微信"界面替换为ChatPage.
import 'package:wechat_demo/page/chat_page.dart';
....
final List<Widget>_pages = [ChatPage(),...];
....

按照上述方法、依次替换_pages中的其他界面

final List<Widget>_pages = [ const ChatPage(), const FriendsPage(), const DiscoverPage(), const MinePage() ];

1.3 遗留问题

1. 当我们点击NavigationBarItem的时候会存在灰色的水波纹动画,以及高亮的颜色问题

 

    • 这个问题属于Material中主题自带的控件特性.那么就需要来到main.dart中,设置主题的地方修改它的特性.
import 'package:flutter/material.dart';
import 'rootpage.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter Demo",
      theme: ThemeData(
          primarySwatch: Colors.blue,
          //1.高亮颜色问题
          highlightColor: Color.fromRGBO(1, 0, 0,0.0),
          //2.点击后水波纹动画颜色.
          splashColor: Color.fromRGBO(1, 0, 0,0.0),
      ),
      home: RootPage(),
    );}
}

2.点击后字体变大

    • 这个问题属于NavigationBar中的选中文字大小,来到rootpage中,修改选中文字大小属性.默认12.0
   bottomNavigationBar: BottomNavigationBar(
    //选中的文字大小
    selectedFontSize: 12.0,
    //4.如果没有设置相应的type、那么默认情况下BarItem设置的都为白色.设置BarType之后默认为蓝色
    type: BottomNavigationBarType.fixed,
    //5.设置fixed类型后,需要添加一个填充色.这样一个TabBar就设置完毕了.
    fixedColor: Colors.green,
    ...),

二、本地资源文件配置

2.1 安卓中应用名称的修改

  • 来到android文件夹下 app --> src --> main --> AndroidManifest.xml

android:label="微信"

2.2 安卓中图片资源放在哪里?

  • 如图所示:

  • mdpi: 对应1x 像素的图片
  • hdpi: 对应 1.5x像素的图片
  • xhdpi: 对应 2x像素图片
  • xxhdpi: 对应3x像素图片
  • xxxhdpi: 对应4x像素图片

2.3 将Demo的应用图标放入Android指定位置

  • 将App图标的2x和3x图片分别拖入两个文件夹中.并且改名为app_icon

  • 在AndroidManifest.xml文件中配置图标名称

2.4 安卓的启动图

  • 在drawable中,launch_background.xml是启动图的配置,将启动图放入1x文件夹下,打开注释.修改xml中启动图的名字与图片名称匹配

  • 因为放在drawable中不显示,猜测版本问题,放在drawable-21中正常显示.

2.5 在安卓模拟器上验证

  • 打开项目目录对应的终端,执行 flutter run,选择安卓模拟器设备
~/wechat_demo2 $ flutter run
Multiple devices found:
sdk gphone x86 (mobile)    • emulator-5554                        • android-x86    • Android 11 (API 30)
(emulator)
iPhone 14 Pro Max (mobile) • 8702647C-F052-4CA5-A758-C7BD3CD49057 • ios            •
com.apple.CoreSimulator.SimRuntime.iOS-16-2 (simulator)
macOS (desktop)            • macos                                • darwin-x64     • macOS 12.6.3 21G419
darwin-x64
Chrome (web)               • chrome                               • web-javascript • Google Chrome
112.0.5615.137
[1]: sdk gphone x86 (emulator-5554)
[2]: iPhone 14 Pro Max (8702647C-F052-4CA5-A758-C7BD3CD49057)
[3]: macOS (macos)
[4]: Chrome (chrome)
Please choose one (To quit, press "q/Q"): 1

Using hardware rendering with device sdk gphone x86. If you notice graphics artifacts, consider enabling
software rendering with "--enable-software-rendering".
Launching lib/main.dart on sdk gphone x86 in debug mode...
Running Gradle task 'assembleDebug'...    
✓  Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app-debug.apk...         93.0s⣯
Syncing files to device sdk gphone x86...                        1,848ms
💪 Running with sound null safety 💪
....             
  • 如果看不到安卓模拟器、就选择左下角拓展,选择Running Devices

  • 从下往上拉安卓模拟器界面、可以看到替换成功的项目图标

  • 安卓启动图

  • 运行完毕与iOS设备对比,样式一致.

  • 存在一个标题居左一个标题居中的问题
    • 这个是和系统默认样式有关系.我们需要特意设置 AppBar的标题居中默认值.

2.6 pubspec.yaml文件

  • 在这个文件中是导入我们需要的package的.

dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2

  • 也就是可以导入在新建项目时,创建的那种package包
dependencies:
  flutter:
    sdk: flutter
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2

  • 浏览这个文件,我们可以看到关于图片设置这一块.
assets:
  - images/a_dot_burr.jpeg
  - images/a_dot_ham.jpeg
  • assets在这里也就是资源的意思.下面表示images文件夹下添加的图片资源.
  • 添加我们的images图片资源放进项目

  • 所以我们的目的是在这里引用我们导入的图片资源.将NavigationBarItem上配置上我们的图片.
assets:
   - images/
    • 注意:当assets报错时,表示放开注释的时候,多占用了空格.与其他配置项对齐即可.

2.7 配置NavigationBarItem的图片

  • 这个时候回到rootpage中.我们将对应的图片资源依次加载上去. 形如:
BottomNavigationBarItem(
  //默认状态下的图片
  icon: Image(image: AssetImage("images/tabbar_chat.png"),),
  //选中状态下的图片
  activeIcon: Image(image: AssetImage("images/tabbar_chat_hl.png"),),
  label: "微信",
),
  • 全部修改完毕后,运行程序在iPhone14ProMax模拟器上.
    • 因为图片给的都是不带@2x和@3x的.也就是默认时1x倍像素.
    • 所以显示起来有些大.
  • 不改变图片的原则下,发现Image中有width和height属性.因此设置上宽高分别为25.这样看起来就适配了.

 

三、搭建发现界面Cell

  • 纵观要搭建的各个界面.发现界面看起来相对简便一些.因此我们由浅入深.先从发现界面开始.
  1. 首先设置发现界面的标题默认居中
centerTitle: true,
  1. 配置主题颜色
    1. 设置一个私有成员变量背景颜色,给AppBar配置上
    2. 去除导航条上的默认黑线
    3. 随便填充一些Text数据
class _DiscoverPageState extends State<DiscoverPage> {
  Color _themColor = Color.fromRGBO(220, 220, 220, 1.0);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        //2. 背景颜色
        backgroundColor: _themColor,
        //1.默认标题居中
        centerTitle: true,
        title: const Text("发现"),
        //3. 去除导航条上的默认黑线
        elevation: 0.0,
      ),
      body: Container(
        color: _themColor,
        height: 800,
        child: ListView( children: <Widget>[ Text('111111111'),Text('22222222'),Text('33333333'),],),
      ),);
   }
}
  1. 在page文件夹下新建一个discover文件夹,将discover_page拖入其中,再新建一个discover_cell.dart文件.
  • 在discover_cell上搭建UI.根据微信的UI,需要四个属性.
final String title;
final String? subTitle;
final String imageName;
final String? subImageName;
  • 其中的subtitle有值就显示,没有值就不显示.那么加上可选值设定标志 ?
  • 根据系统提示,可以得到规范的构造函数编写方式为:
const DiscoverCell({super.key,required this.title, this.subTitle,required this.imageName,this.subImageName});
  • 根据UI效果,cell高度固定,那么在discover_cell中的Container内容为
import 'package:flutter/material.dart';
class DiscoverCell extends StatelessWidget {
     final String title;
    final String? subTitle;
    final String imageName;
    final String? subImageName;
    const DiscoverCell({super.key,required this.title, this.subTitle,required this.imageName, this.subImageName});
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      height: 55,
      child: Row(

      ),
    );
  }
}
  1. 在discover_page调用discover_cell,在_DiscoverPageState中的ListView内容假定为
ListView(
  children: <Widget>[
    DiscoverCell(title: "111",imageName: '',),
  ],
),
  • 效果如图:

  1. UI分析,需要两个文本,两个图片.于是来到Cell中,定制我们的Cell展示样式
  • cell上放置控件的思路为
    • 整个cell为一个Row布局
      • 左边是一个放置image和title的Container,
      • 右边是一个放置subtilte、subImage、右箭头的Container.
    • 左边Container居左,右边Container居右.
    • 控件整体要有边距,背景为白色.
  • 因此Cell内容为
@override
Widget build(BuildContext context) {
  return Container(
    //2.边距
    padding: EdgeInsets.all(10),
    color: Colors.white,
    height: 55,
    child: Row(
      //5. 设置左边的Container靠左,右边的Container靠右,设置主轴属性
      mainAxisAlignment: MainAxisAlignment.spaceBetween,
      children: <Widget>[
          //left
          Container(
            //1.当前结构为 image和title在同一个Container上
            child: Row(
              children: [
                Image(image: AssetImage(imageName),width: 20,),//图标
                SizedBox(width: 15,),//间距
                Text(title),//标题
              ],
            ),
          ),
          //right
          Container(
            child: Row(
              children: <Widget>[
                //3. 设置子标题,如果不为空,强制解包
                Text(subTitle != null ? subTitle! : ''),
                //4. 设置子图标: 如果图片名称不为空,则设置图片,否则填充Container
                subImageName != null ? Image(image: AssetImage(subImageName!),) : Container(),
                Image(image: AssetImage('images/icon_right.png'),width: 15),
              ],
            ),
          )
      ],
    ),
  );
}
    • 1.当前结构为 image和title在同一个Container上
    • 2.边距padding: EdgeInsets.all(10)
    • 3. 设置子标题,如果不为空,强制解包
    • 4. 设置子图标: 如果图片名称不为空,则设置图片,否则填充Container
    • 5. 设置左边的Container靠左,右边的Container靠右,设置主轴属性
  • 将相关图片资源在pubspec.yaml全部加载上

  1. 细节增加, title和imageName不能为空,那么在构造函数后增加运行时的断言.其实不加也行,现在多了required限定,必然非空.
const DiscoverCell({super.key,required this.title, this.subTitle,required this.imageName, this.subImageName}) : 
assert(title != null, 'title 不能为空'), assert(imageName != null, 'imageName不能为空');

四、发现界面完善

  • 在发现界面除了cell之外,还有空白间距,打算用SizedBox设置空白间距.
SizedBox(height: 10,),
  • 两个Cell之间又有一条灰色的线,因此需要额外添加一条线: 左边50px白色,右边铺满灰色,高度0.5
Row(children: [
  Container(color: Colors.white, height: 0.5 , width: 50,),
  Container(color: Colors.grey, height:0.5),
],),
  • 在购物一栏、会有subTitle和subImageName,这个时候,需要我们完善Cell上这块的布局
    • 设置子标题文字样式
    • 设置小图片显示样式(添加边距)
Container(
  child: Row(
    children: <Widget>[
      //3. 设置子标题,如果不为空,强制解包
      Text(subTitle != null ? subTitle! : '',
        //6. 设置文字样式
        style: TextStyle(color: Colors.grey),
      ),
      //4. 设置子图标: 如果图片名称不为空,则设置图片,否则填充Container
      subImageName != null ?
      //7.这里是小红圆点
      Container(child: Image(image: AssetImage(subImageName!),width: 15,) ,margin: EdgeInsets.only(left: 10,right: 10),) : 
      Container(),
      Image(image: AssetImage('images/icon_right.png'),width: 15),
    ],
  ),
)
  • 综上discover_page中的ListView实现为
ListView(
  children: <Widget>[
    DiscoverCell(title: "朋友圈",imageName: 'images/朋友圈.png',),
    SizedBox(height: 10,),
    DiscoverCell(title: "扫一扫",imageName: 'images/扫一扫.png',),
    Row(children: [
      Container(color: Colors.white, height: 0.5 , width: 50,),
      Container(color: Colors.grey, height:0.5),
    ],),
    DiscoverCell(title: "摇一摇",imageName: 'images/摇一摇.png',),
    SizedBox(height: 10,),
    DiscoverCell(title: "看一看",imageName: 'images/看一看.png',),
    Row(children: [
      Container(color: Colors.white, height: 0.5 , width: 50,),
      Container(color: Colors.grey, height:0.5),
    ],),
    DiscoverCell(title: "搜一搜",imageName: 'images/搜一搜.png',),
    SizedBox(height: 10,),
    DiscoverCell(title: "附近的人",imageName: 'images/附近的人.png',),
    SizedBox(height: 10,),
    DiscoverCell(title: "购物",imageName: 'images/购物.png',subTitle: '618限时特惠',subImageName: 'images/badge.png',),
    Row(children: [
      Container(color: Colors.white, height: 0.5 , width: 50,),
      Container(color: Colors.grey, height:0.5),
    ],),
    DiscoverCell(title: "游戏",imageName: 'images/游戏.png',),
    SizedBox(height: 10,),
    DiscoverCell(title: "小程序",imageName: 'images/小程序.png',),
  ],
),

五、发现界面Cell点击切换界面

  1. 在cell中使用GestureDetector,用于监听点击事件.
    • onTap作为事件响应,写点代码用于测试点击的响应事件.
@override
Widget build(BuildContext context) {
  //5.1 GestureDetector可以监听点击事件.
  return GestureDetector(
    onTap: (){
      print("hello cell");
    },
    child: Container(...),
    );  
}
  1. 发现点击无误,那么在点击的同时,我们想要跳转到下一个界面.
    1. 这个时候,创建一个发现的子界面discover_child_page.dart;
import 'package:flutter/material.dart';
class DiscoverChildPage extends StatefulWidget {
  //1.添加一个标题,对外暴露.
  final String title;
  const DiscoverChildPage({Key? key, required this.title}) : super(key: key);
  @override
  State<DiscoverChildPage> createState() => _DiscoverChildPageState();
}
class _DiscoverChildPageState extends State<DiscoverChildPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      //2.设置导航栏标题
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        //3.设置界面中显示一行标题名称.
        child: Text(widget.title),
      ),
    );
  }
}
  1. 回到discover_cell,当点击cell时,我们想要它跳转到discover_child_page中去.
    • 拿到Navigator对象.获取context,push到下一个界面
    • MaterialPageRoute:一种模式路线,它用平台自适应转换来替换整个屏幕。构造BuildContext
    • 返回值对象为:需要跳转到的界面
  • 因此cell中的跳转部分的实现为
@override
Widget build(BuildContext context) {
  //5.1 GestureDetector可以监听点击事件.
  return GestureDetector(
    onTap: (){
      //5.2 拿到Navigator对象.获取context,push到下一个界面
      Navigator.of(context).push(
        //5.3 MaterialPageRoute:一种模式路线,它用平台自适应转换来替换整个屏幕。构造BuildContext
        MaterialPageRoute(builder: (BuildContext context){
            //5.4 需要返回跳转到的界面作为返回值对象.
            return DiscoverChildPage(title: title);
        })
      );
    },
    child: Container(...),
    );
}
  1. 注释5.3与5.4部分可以采用箭头函数简写为
MaterialPageRoute(builder: (BuildContext context) => DiscoverChildPage(title: title)) //不带分号;
  1. 综上Cell的跳转交互就完成了.

六、发现界面Cell状态的设置

  • Cell点击时默认应该有置灰色状态的,当手势离开Cell时,灰色状态取消.现在我们实现的效果还没有状态的响应.
  • 因此需要我们添加一些特殊效果.首先这种点击离开对应的手势事件为onTapCancel
//5.5 点击取消时
onTapCancel: (){
   print("1222");
},
  • 牵扯到状态的改变,那么我们就需要将当前的StatelessWidget改为StatefulWidget.
    • 首先定义一个相同的StatefulWidget.然后将原先StatelessWidget的Widget build(BuildContext context) {} 剪切至StatefulWidget中完成替换.
    • 再将StatelessWidget设置的属性剪切至StatefulWidget中.
    • 在有状态组件中没法直接拿到之前无状态的属性,需要添加widget. 前缀
  • 汇总一下实现思路
    1. 定义一个私有成员变量:当前颜色 Color _currentColor = Colors.white;
    2. 在GestureDetector下的child里的Container:设置color:_currentColor
    3. 在onTap点击方法中通过有状态组件的setState设置当前颜色为白色
    4. 在onTapDown: (TapDownDetails details)点击下去的方法中通过setState设置当前颜色为灰色
    5. 在onTapCancel点击取消方法中通过setState设置当前颜色恢复为白色

综上.有状态的Cell就实现了.

七、回顾总结

  1. 本地资源文件在pubspec.yaml中配置.
  2. 由无状态组件改为有状态组件,访问属性时需要添加上widget.
  3. GestureDetector,用于监听点击事件.
  4. 点击cell时,我们想要它跳转到下一个界面去.
    1. Navigator对象.of获取context,push到下一个界面
    2. MaterialPageRoute:一种模式路线,它用平台自适应转换来替换整个屏幕。构造BuildContext
    3. 返回值对象为:需要跳转到的界面

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

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

相关文章

【Python】scikit-plot可视化模型(含源代码)

文章目录 一、前言二、功能1&#xff1a;评估指标可视化2.1 scikitplot.metrics.plot_confusion_matrix2.2 scikitplot.metrics.plot_roc2.3 scikitplot.metrics.plot_ks_statistic2.4 scikitplot.metrics.plot_precision_recall2.5 scikitplot.metrics.plot_silhouette2.6 sci…

操作系统学习01

1、什么是操作系统&#xff1f; 通过以下四点可以概括操作系统到底是什么&#xff1a; 操作系统&#xff08;Operating System&#xff0c;简称 OS&#xff09;是管理计算机硬件与软件资源的程序&#xff0c;是计算机的基石。操作系统本质上是一个运行在计算机上的软件程序 &a…

微前端 qiankun@2.10.5 源码分析(一)

微前端 qiankun2.10.5 源码分析&#xff08;一&#xff09; 前言 微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。 Techniques, strategies and recipes for building a modern web app with multiple teams that can ship feat…

Figma转换为sketch,分享这3款工具

在我们的设计工作中&#xff0c;我们经常会遇到各种各样的设计文件相互转换的问题。 你经常为此头疼吗&#xff1f;当你遇到Figma转换Sketch文件的问题时&#xff0c;你是如何解决的&#xff1f;Figma转换Sketch文件有工具吗&#xff1f; 根据众多设计师的经验&#xff0c;本…

在竞争激烈的移动应用市场中获得成功,掌握决胜Framework技术

为何要学习framework&#xff1f; Framework&#xff0c;指的是对应用程序开发所需的核心工具和组件的封装和提供。在Android开发中&#xff0c;Framework是整个开发过程中的核心组成部分&#xff0c;提供了许多功能和服务&#xff0c;包括UI组件、数据存储、网络通信、多媒体…

第二十四章 策略模式

文章目录 前言传统方式解决鸭子问题完整代码抽象鸭子类野鸭子类北京鸭子类玩具鸭子类 一、策略模式基本介绍二、策略模式解决鸭子问题完整代码飞翔接口 FlyBehavior飞翔接口的子类实现飞翔技术高超 GoodFlyBehavior不会飞翔 NoFlyBehavior飞翔技术一般 BadFlyBehavior其他行为接…

文献阅读 Meta-SR: A Magnification-Arbitrary Network for Super-Resolution

题目 Meta-SR: A Magnification-Arbitrary Network for Super-Resolution Meta-SR: 用于超分辨率的任何放大网络 摘要 由于DCNN的发展&#xff0c;最近关于超分辨率的研究取得了巨大成功。然而&#xff0c;任意比例因子的超分辨率长期以来一直被忽视。以往的研究者大多将不同…

Stable-Diffusion AI画画本地搭建详细步骤

ChatGPT出来后&#xff0c;第一次感觉到人工智能真的可能要来了&#xff0c;因此也顺便尝试了下开源AI画画的搭建。网络上写的教程总是不那么面面俱到&#xff0c;因此本文参考了3篇文章才成功把Stable-Diffusion 本地搭建搭建了起来。参考教程在文末。 本文是本地搭建AI画画&a…

C/C++内存泄露检查利器—valgrind

1、Valgrind概述 Valgrind是一套Linux下&#xff0c;开放源代码&#xff08;GPL V2&#xff09;的仿真调试工具的集合。 Valgrind由内核&#xff08;core&#xff09;以及基于内核的其他调试工具组成。内核类似于一个框架&#xff08;framework&#xff09;&#xff0c;它模拟…

Android中的GPS开发

GPS简介 Gobal Positioning System&#xff0c;全球定位系统&#xff0c;是美国在20世纪70年代研制的一种以人造地球卫星为基础的高精度无线电导航的定位系统&#xff0c;它在全球任何地方以及近地空间都能够提供准确的地理位置、车行速度及精确的时间信息&#xff1b;它是具有…

2023年房地产抵押贷款研究报告

第一章 概述 房地产抵押贷款是一种以房地产为抵押品的贷款形式&#xff0c;包括个人和企业两种情况。个人房地产抵押贷款是指个人将名下房产作为抵押品向银行或其他金融机构申请贷款&#xff0c;而企业房地产抵押贷款则是指企业将自己名下的商业房产作为抵押品向金融机构申请贷…

202309读书笔记|《野性之美:非洲野生动物初窥》——走进自然界的野性之美

《野性之美: 非洲野生动物初窥》微读的一本书&#xff0c;图片居多&#xff0c;非常有视觉上的震撼。拍摄者也是我们孙姓的一员&#xff0c;孙长智。正如作者所说&#xff0c;与自然对话&#xff0c;你会感悟到生命之美、竞争之美、进化之美、和谐之美&#xff01; 我喜欢自然…

SPSS如何绘制常用统计图之案例实训?

文章目录 0.引言1.绘制简单条形图2.绘制分类条形图3.绘制分段条形图4.绘制简单线图5.绘制多重线图6.绘制垂直线图7.绘制简单面积图8.绘制堆积面积图9.绘制饼图10.绘制直方图11.绘制简单散点图12.绘制重叠散点图13.绘制矩阵散点图14.绘制三维散点图15.绘制简单箱图16.绘制分类箱…

【markdown工具配合图床】PicGo图床配置教程,一秒读懂配置

前言 看到这篇文章的大佬&#xff0c;我默认大家都会配置git&#xff0c;已经配置好ssh公钥。 此时你看到的这篇文章就是基于markdown工具&#xff08;VSCode&#xff0c;Typora&#xff09;编写的。 PicGo作为图床转换工具&#xff0c;并配合gitee作为图片服务器&#xff0…

java元注解和自定义注解的区别

Java的元注解和自定义注解是两个不同的概念。 元注解是Java内置的一组用于修饰其他注解的注解&#xff0c;包括Retention、Target、Inherited和Documented。它们可以控制被修饰的注解的保留策略、目标范围、是否继承等属性&#xff0c;并且可以在编写自定义注解时使用。 Retent…

国考省考结构化面试:综合分析题,社会现象(积极消极政策)、名言哲理(警句观点启示)、漫画反驳题等

国考省考结构化面试&#xff1a;综合分析题&#xff0c;社会现象&#xff08;积极消极政策&#xff09;、名言哲理&#xff08;警句观点启示&#xff09;、漫画反驳题等 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&…

【Java数据结构】优先级队列(堆)

优先级队列&#xff08;堆&#xff09; 概念模拟实现堆的概念堆的存储方式堆的创建向下调整堆的创建建堆的时间复杂度 堆的插入和删除堆的插入堆的删除 用堆模拟实现优先级队列 常用接口PriorityQueue的特性PriorityQueue常用接口介绍构造方法插入/删除/获取优先级最高的元素 P…

孙溟㠭篆刻,红木上的‘’椎凿稚趣‘’

了解中国传统篆刻的人&#xff0c;一定知道篆刻作品中追求的“金石气”。作为拥有3700多年历史的中国传统艺术&#xff0c;篆刻艺术是将书法&#xff08;主要是篆书&#xff09;和镌刻&#xff08;包括凿、铸&#xff09;相结合&#xff0c;制作印章&#xff0c;亦是汉字独有的…

Vivado 仿真器中以批处理或脚本模式(Batch or Scripted Mode)进行仿真

以下说明来自ug900:在 Vivado 仿真器中以批处理或脚本模式进行仿真 具体可以内容可自行查找 其中代码运行截图为自己实践的实例 Note: xelab, xvlog and xvhdl are not Tcl commands. The xvlog, xvhdl, xelab are Vivado-independent compiler executables. Hence, there is…

20230505使用amazon来批量翻译SRT格式的日语字幕为简体中文

20230505使用amazon来批量翻译SRT格式的日语字幕为简体中文 2023/5/5 19:03 百度搜索&#xff1a;使用 amazon 批量翻译 请严重注意&#xff1a;可能会扣费的&#xff01; https://aws.amazon.com/cn/blogs/china/translating-documents-with-amazon-translate-aws-lambda-and…