likes
comments
collection
share

Flutter

作者站长头像
站长
· 阅读数 29

一. Dart声明类型

Dart是一个强类型语言,完全面向对象的一种编程语言

所以它跟js不同的是,dart在声明变量时,需要先声明类型

1. Object类型

dart也具有var的声明方式(虽然没有声明类型,但是var会自动根据后面内容,自动生成类型)

对dart来讲,所有的对象都是继承于object类型

import 'package:Dart_study/Dart_study.dart' as Dart_study;

void main(List<String> arguments) {
  print('Hello world!');
  // dart声明变量
  var str= 'hello';
  //var 的声明方式,会自动识别后面的类型
  //所以再赋值别的类型是不可以的
  //str=123;
  print(str);

  //显示声明了这个password是个object类型
  //所以给它赋值成字符串或数字或其他就都是可以的
  //因为这些都属于object的子类型
  Object password =123;
  password='obj';
}

上面只是举个例子

  • 但其实,你声明object其实是没什么意义的,因为你把类型声明的这么大,其实也就相当于没有声明类型

2. dynamic动态类型

跟object有点像的是,它也是一个很大的类型

但是与object不同的是:

  • object变量在点属性的时候,只有object拥有的方法
  • 但是dynamic可以推断出所有可能的属性或方法(点属性)
    • 它避免了一些编译器在编译阶段的检查,但是也就存在会引入bug的情况
    • 因为有可能你点出来的这个方法它并不具备
    • 所以一般还是不用这个
Object a='obj';
dynamic b='dynamic';
print(a.length);//会有提示表示object没有这个属性
print(b.length);

3. 常量的声明方式

  • final
  • const

区别:(看需求使用)

  • const叫做编译时常量
    • 意思是它在编译时就已经存在了,即使还没有运行到它,但是它已经存在了
    • 在编译阶段就已经申请好内存了
  • final是只有运行到时才会被初始化
    • 也就是它什么时候用,什么时候才会申请一段内存空间

4. 变量类型

Number类型——int、double

import 'package:Dart_study/Dart_study.dart' as Dart_study;

// List<String> arguments
void main() {
int a=111;
double b=222.333;

// 把字符串转成整型
int c =int.parse("333");
// 把字符串转成double型
double d =double.parse("444.555");

print(a);
print(b);
print(c);
print(d);
}

String

//toString可以转成字符串
String a=123.toString();
//四舍五入
// 保留两位小数
String b=123.666.toStringAsFixed(2);
print(a);
print(b);

Bool

bool result=123 > 110;
bool result2=1 =='1'; // 如果类型不相同,直接就是false,不会再进行值的比较了
print(result);
print(result2);

List数组类型

List list=[1,3,5,7,9];

//也可以声明一个空数组
List newList=new List();
newList.add(1);
newList.addAll([2,3,4]);

print(newList);
print(newList.length);//数组长度
print(newList.first);//第一个元素
print(newList.last);//最后一个元素
print(newList[2]);//根据下标打印出某个值
// 其他还有很多,不一一列举,直接点可以看到

Map对象类型

本质上就是key value的键值对

有两种声明方式:

  1. 字面量的形式,直接大括号
    • (书写上比较严格的是,需要用单引号或双引号包裹key)
  2. 直接实例化一个(也就是new一个)
//1. 字面量的形式声明
Map obj={'x':1,'y':2,'z':3};

//2. 或者直接实例化一个(也就是new一个)
Map obj2=new Map();
obj2['x']=1;
obj2['y']=2;

print(obj);
print(obj2);
print(obj.containsKey('x'));// 判断是否包含某一个key值
obj.remove('x');// 删除某个键值对
print(obj);

function

函数

例如 :

  • main是入口函数,void是这个函数的返回类型(而void意思是不需要返回值的类型)
  • String是需要返回的是字符串类型,里面参数意思是需要传递一个整型参数
  • int addAge(int age1,[int age2]){}这个中括号意思是,这个参数是可传可不传的(可选参数)
    • 但是并不建议这样写,因为如果这样写然后函数里又用到了这个参数,就必须给这个参数加三目运算
    • 所以可以把中括号的方式替换成 赋初值 的方式(但是这种给初始值的方式,需要额外做的是,给参数外面括上大括号,不然报错)int addAge({int age1,int age2=0}){}
    • 建议用赋初值(默认值) 而不是中括号
void main() {
  String userName=getUserName();
  String personInfo=getPersonInfo(111);

  print(userName);
  print(personInfo);
}

String getUserName(){
   return 'hello world!';
}

String getPersonInfo(int useId){
   Map userInfo={
      '111':'zhangsan',
      '222':'lisi'
   };
   //return userInfo[useId];易错,类型不匹配
   return userInfo[useId.toString()];
}
匿名函数

不具备方法名的函数,往往在某个方法里的回调里经常被使用

比如:

var list=[123,456,789];
list.forEach((number){
  print(number);
});

二. Dart 类

1. 继承——单继承

  1. 类——接收参数
void main() {
  var a=new Person(18,'zhangsan');
  // 可以像下面这样写,但是我们希望实例化的时候就已经传好了,而不是实例化完再传
  //所以就用到了构造函数
  // a.age=123;
   print(a.age);
}
// 类
class Person{
  int age;
  String name;

  // 构造函数,也就是跟类同名的一个方法
  Person(int age,String name){
    //this指向的就是实例,person实例化之后的实例
    this.age=age;
    this.name=name;
  }
  
}
  1. 类——成员函数
void main() {
  var a=new Person(18,'zhangsan');
  // 直接调方法
   a.sayHello();
}
// 类
class Person{
  int age;
  String name;

  // 构造函数,也就是跟类同名的一个方法
  Person(int age,String name){
    //this指向的就是实例,person实例化之后的实例
    this.age=age;
    this.name=name;
  }
  // 成员函数
  void sayHello() {
    print('my name is' + this.name);
  }
}
  1. 继承
void main() {
  //父
  var a=new Person(18,'zhangsan');
  // 直接调方法
   a.sayHello();

   //子
   var b=new Worker(18, 'lisi', 3500);
   b.sayHello();
}
// 类
class Person{
  int age;
  String name;

  // 构造函数,也就是跟类同名的一个方法
  Person(int age,String name){
    //this指向的就是实例,person实例化之后的实例
    this.age=age;
    this.name=name;
  }
  // 成员函数
  void sayHello() {
    print('my name is ' + this.name);
  }
}

// 继承
class Worker extends Person{
  // 构造器
  // 相当于woker这个构造函数,调了一个super,就是一个父类构造器
  int salary;// 我们扩展的成员变量
  Worker(int age, String name,int salary) : super(age, name){
    // 这里面是我们要扩展的一些方法体
    this.salary=salary;
  }

  //如果想写一个同名的方法的话,默认意思是重写(覆盖)
  // 这里为了增强可读性,可以在前面写一个@override
  @override
  void sayHello(){
    // 在子类里也可以调父类的
    super.sayHello();
    print("重写了");
    print('my salart is '+ this.salary.toString());
  }
}

注意:

  • dart里面只有单继承,也就是说extends不能同时继承多个父类
  • 如果想实现多继承的话,就要用到混合mixin (with)👇

2. mixin混合——多继承

混合:可以同时具备多个类的方法

class Eat {
  void eat(){
    print('eat');
  }
}
class Sleep{
  void sleep(){
    print('sleep');
  }
}

class Person with Eat,Sleep{
  
}

注意:

  • 如果类里面本身就有方法,混合中也有同名方法的话,优先执行类里面的,其他就不执行了
  • 如果类里面没有,多个混合里有,优先混合的执行最后一个的这个方法

3. 抽象类 abstract

就是在类的前面加上一个关键词

abstract class Animal{
  // 只定义而没有实现,是抽象方法(也就是先把想法定义出来)
  void baby();
  // 方法实现了,所以不是抽象方法
  void have_a_baby(){
    print('have a baby');
  }
}

定义好抽象方法后,可以交给继承这个的类去实现

...
class Person extends Animal with Eat,Sleep{
  //(baby按住tab键可以补全)
  @override
  void baby() {
    // TODO: implement baby
  }
}

abstract class Animal{
  // 只定义而没有实现,是抽象方法(也就是先把想法定义出来)
  void baby();
}

注意:

  • 抽象类不能被实例化
    • 原因:因为它里面还有没实现的方法,调用的话会报错

三. Dart 使用库

1. 使用自己的库

Flutter

main.dart

import 'package:Dart_study/Dart_study.dart' as Dart_study;


import 'ku/Calc.dart';
void main() {

  int result=add(3,4);
  print(result);

  var c=new Calc(4,3);
  c.minus();
}

ku/Calc.dart

int add(int x,int y){
  return x+y;
}

class Calc{
  int x;
  int y;
  Calc(int x,int y){
    this.x=x;
    this.y=y;
  }
  minus(){
    print(this.x-this.y);
  }
}

2. 用别人的库

从pub网站上拿我们需要的依赖包

配置文件👇

Flutter

网站👇

The official repository for Dart and Flutter packages. (pub.dev)

import 'package:Dart_study/Dart_study.dart' as Dart_study;

import 'package:http/http.dart'as http;

import 'ku/Calc.dart';
void main () async{

  int result=add(3,4);
  print(result);

  var c=new Calc(4,3);
  c.minus();


  var url = Uri.https('example.com', 'whatsit/create');
  var response = await http.post(url, body: {'name': 'doodle', 'color': 'blue'});
  print('Response status: ${response.statusCode}');
  print('Response body: ${response.body}');

  print(await http.read('https://www.baidu.com/'));
}

3. 使用dart自身的包

比如:

// 数学
import 'dart:math';

// 生成一个随机数
var r =new Random();
print(r.nextInt(10));

4. 延时加载(按需加载)

import 'dart:math' deferred as math;

// 告诉dart,开始加载这个库了
 math.loadLibrary();
 var r= new math.Random();
 print(r.nextInt(10));

四.Dart的异步处理

  1. Future
void main () {

  print("say hi");
  
  //异步
  Future.delayed(new Duration(seconds: 5),(){
    print('chibaole');
  });
  
  
  print('play game');
}
  1. 异步调用,同步写法——async await
void main () async{

  print("say hi");

  //异步
  //也就是会等待这个异步执行完成之后,才会继续往下执行
  await Future.delayed(new Duration(seconds: 5),(){
    print('chibaole');
  });


  print('play game');
}
  1. Future.wait([])的方法,可以让多个异步同时进行,都完成之后,才会继续往下
Future.wait([
  Future.delayed(new Duration(seconds: 1),(){
    print('001');
  }),
  Future.delayed(new Duration(seconds: 2),(){
    print('002');
   }),
  Future.delayed(new Duration(seconds: 3),(){
     print('003');
  })
]).then((List results){
  print('over');
});
  • 不加await,三个异步同时进行(例如下面代码:3s)
  • 加wait,一个执行完下一个(例如:6s)
  Future.delayed(new Duration(seconds: 1),(){
    print('001');
  }),
  Future.delayed(new Duration(seconds: 2),(){
    print('002');
   }),
  Future.delayed(new Duration(seconds: 3),(){
     print('003');
  })

五. Flutter——widgets

flutter中几乎所有的对象都是一个widgets

flutter系列之:widgets,构成flutter的基石_为什么根widget要使用stateless-CSDN博客

1. 组件——文本,字体

children: <Widget>[
  const Text(
    'hello bodyhello bodyhello bodyhello bodyhello bodyhello bodyhello bodyhello bodyhello bodyhello bodyhello bodyhello bodyhello body',
    textAlign: TextAlign.right,
    maxLines: 2,// 最多显示两行
    overflow: TextOverflow.ellipsis,//ellipsis省略号
    textScaleFactor: 3 ,//字体放大三倍,
  ),

也可以设置统一的,可以多次使用

Flutter

分别设置的话,可以用Text.rich

Flutter

2. 组件——按钮

  • RaiseButton
  • FlatButton
  • OutlineButton
  • 自定义

3. 图片的使用和加载 和 图标

加载分为

  • 加载本地资源
  • 加载网络资源

本地资源

比如我们想放一个本地图片

body:Column(
  children:<Widget> [
    Image.asset("路径")
  ],
)

但是现在并不能实现,还需要加一个东西(在pubspec.yaml文件里)

相当于把本地资源在这里注册进去

// 把本地路径补充上去
assets:
  - images/a_dot_burr.jpeg

网络资源

Image.network("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png",
width: 150,)

属性

  • fit:BoxFit.cover
  • colorBlendMode:BlendMode.difference混合
  • ...

图标

  • icon:Icon(Icons....)这个可以选择自带的
  • 还可以使用iconfont图标库(学会使用字体库 p13集)

4. 下拉框

5. 单选框和多选框

6. 输入框

六. flutter——布局

1. 线性布局

例子:

body:Row(
  children: <Widget>[
    Container(
      width: 200,
      height: 350,
      color: Colors.blue,
    ),
    Container(
      width: 300,
      height: 400,
      color: Colors.red,
    )
  ],
),

效果:

Flutter

出错原因:

  • 盒子超出了row的范围
  • (如果想做等分——用弹性布局来做(后面会讲到))

横向对齐方式

// 首先关键
body:Row()


crossAxisAlignment:CrossAxisAlignment.start ,// 靠上对齐
crossAxisAlignment:CrossAxisAlignment.end,// 靠下对齐
crossAxisAlignment:CrossAxisAlignment.center ,// 默认状态,中线对齐

垂直对齐方式

// 首先关键
body:Column()

// 跟上面代码样子是一样的
crossAxisAlignment:CrossAxisAlignment.start ,// 靠左对齐
crossAxisAlignment:CrossAxisAlignment.end,// 靠右对齐
crossAxisAlignment:CrossAxisAlignment.center ,// 默认状态,中线对齐

2. 弹性布局

最常见的应用场景: n等分,一个宽度固定其它灵活分配

// 首先关键
body:Flex(
  direction:Axis.horizontal,// 是什么方向,flex布局必须要有的(horizontal这个是横向的)
)

举个例子:

Flutter

body:Flex(
  direction:Axis.horizontal,// 是什么方向,flex布局必须要有的(horizontal这个是横向的)
  children: <Widget>[
    Expanded(
      flex: 1,//占一份
      child: Container(
        height: 300,
        color: Colors.red,
      ),
    ),
    Expanded(
      flex: 1,//占一份
      child: Container(
        height: 300,
        color: Colors.blue,
      ),
    ),
    Expanded(
      flex: 1,//占一份
      child: Container(
        height: 300,
        color: Colors.yellow,
      ),
    )
  ],
)

下面代码多写了一个单独的Container,意思是这个盒子固定宽度占50,剩下区域三等分

Flutter

body:Flex(
  direction:Axis.horizontal,// 是什么方向,flex布局必须要有的(horizontal这个是横向的)
  children: <Widget>[
    Container(
      width: 50,
      height: 300,
      color: Colors.black,
    ),
    Expanded(
      flex: 1,//占一份
      child: Container(
        height: 300,
        color: Colors.red,
      ),
    ),
    Expanded(
      flex: 1,//占一份
      child: Container(
        height: 300,
        color: Colors.blue,
      ),
    ),
    Expanded(
      flex: 1,//占一份
      child: Container(
        height: 300,
        color: Colors.yellow,
      ),
    )
  ],
)

direction:Axis.vertical是垂直方向,同理

3. 流式布局

比如当我们在布局时,超过了最大行宽,但是我们并不想它报错,而是希望它超过后就换行,那么就要用到流式布局

body:Wrap(
)

流式布局中还有几个属性👇

// 比如
spacing:25 // 横向盒子与盒子之间的间距
runSpacing:10 // 垂直方向间距
alignment:WrapAlignment.center// 对齐方式

七. flutter——定位

有个特点:可以层叠覆盖

Flutter

// 这个SizedBox是修饰子组件大小的(也就是child)
body:SizedBox(
  // 这个宽高修饰的是这个Stack的大小
  width: 300,
  height: 300,
  child: Stack(
  
    children: <Widget>[
      // 定位
      Positioned(
        //  这个定位最多写两个!!
        left: 15,
        top: 30,
        // 需要定位的这个child盒子
        child: Container(
          height: 100,
          width: 100,
          color: Colors.yellow,
        ),
      ),
      Positioned(
        right: 10,
        top: 100,
        child: Container(
          width: 200,
          height: 200,
          color: Colors.blue,
        ),
      )
    ],
  ),

)

这个属性也可以设置定位👇

alignment:Alignment.topRight ,//设置左对齐还是右对齐

八. flutter——内边距

body:Container(
  width: 400,
  height: 400,
  color: Colors.red,
  //all代表四个方向都是一样的
  child: Padding(padding: EdgeInsets.all(30),
    child: Container(
      color: Colors.blue,
    )),
)
  • EdgeInsets.all(),是四个方向
  • .fromlTRB(),表示四个方向的值可以单独控制(顺时针,左上右下)
  • only(top:10),代表只有上边距,别的方向同理

九. flutter——布局限制类容器

就是用来限制他的子容器,也就是子元素的

body:ConstrainedBox(
  //expand默认填充整个剩余空间
  constraints:BoxConstraints.expand(),
  child: Container(
    color: Colors.red,
  ),
)
  • 也可以自己定义
body:ConstrainedBox(
  //expand默认填充整个剩余空间
  constraints:BoxConstraints(
    maxHeight: 200,
    maxWidth: 100,
  ),
  child: Container(
    color: Colors.red,
  ),
)
  • 想要一个方向占满

maxHeight:double.infinity,//意思是最大高度是无限大

十. flutter——集容器

1. 装饰容器 Decoration

在绘制内容之前,可以先绘制一些装饰的内容

相当于对child装饰

body:DecoratedBox(decoration: BoxDecoration(
  gradient: LinearGradient(colors: [Colors.yellow,Colors.greenAccent]),//渐变
  borderRadius: BorderRadius.all(Radius.circular(3.0)),//圆角
  boxShadow: [
  //阴影
    BoxShadow(
      color: Colors.black,
      offset: Offset(3,3),
      blurRadius: 4.0
    )
  ]
),
//FlatButton已经被弃用了
child:TextButton(onPressed:null,child:Text("hello"))

)

Flutter

2. 变换transform

改变的是表象的空间,内容实际占的还是原来的空间

拉伸skew

body: Column(
  children: <Widget>[
    Container(
      color: Colors.red,
      child: Transform(
        // 在x轴上进行拉伸
          transform: new Matrix4.skewY(0.5),
          child: Container(
            color: Colors.blue,
            child:Text("hello")
        )),
    )
  ],
),

放大scale

body: Column(
  children: <Widget>[
    Container(
      color: Colors.red,
      child: Transform.scale(
        // 放大
        // 但是所占的空间(大小)不变,放大的是里面的内容
        scale: 4,//1 就是原尺寸
          child: Container(
            color: Colors.blue,
            child:Text("hello")
        )),
    )
  ],
),

旋转routate

body: Column(
  children: <Widget>[
    Container(
      color: Colors.red,
      child: Transform.rotate(
        // 旋转
        angle: math.pi/2,//旋转90度,math需要import
          child: Container(
            color: Colors.blue,
            child:Text("hello")
        )),
    )
  ],
),

平移translate

body: Column(
  children: <Widget>[
    Container(
      color: Colors.red,
      child: Transform.translate(
        // 平移
        offset: Offset(200,50),//像右移动了200,向下移动了50
          child: Container(
            color: Colors.blue,
            child:Text("hello")
        )),
    )
  ],
),

3. Container

4. 可滚动的组件

  1. 内容超出容器后,它就会自动出现一个滚动条
body:Scrollbar(
  child: SingleChildScrollView(
    child: Container(
      height: 3000,
      color: Colors.red,
    ),
  ),
)
  1. 有固定表头,还有容器高度——ListView

Flutter

body: Column(
  children: <Widget>[
    ListTile(title: Text('固定的表头')),
    Container(
      height: 400,
      child: ListView.builder(
        itemCount: 50,
          itemExtent: 50,
          itemBuilder:(BuildContext context,int index){
            return Text("列表内容"+index.toString());
          }
      ),
    )
  ],
),
  1. 格子布局

Flutter

body:GridView(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
      crossAxisCount: 3,// 每行有几格
      childAspectRatio: 1 // 横纵比
  ),
  children: <Widget>[
    Text("1"),
    Text("2"),
    Text("3"),
    Text("4"),
    Text("5"),
    Text("6"),
    Text("7"),
    Text("8"),
    Text("9"),
  ],
)

十一. flutter——脚手架Scaffold

  • 基本结构
  • 顶部导航
  • 底部导航
  • 侧边抽屉

十二. flutter——事件

绑事件需要在最外层加个listener

1. 指针事件

绑事件需要在最外层加个listener

从子到父冒泡

(tip:在flutter中没有阻止冒泡这个功能)

body:Listener(
  onPointerDown: (e){
    print("down");
  },
  onPointerUp: (e){
    print("up");
  },
  onPointerMove: (e){
  print("move");
},
  onPointerCancel: (e){
    print("cancel");
  },

  child: Container(
    width:200,
    height: 200,
    color: Colors.red,
  ),
)

2. 手势事件

可用于交互

绑事件需要在最外层加个

body: GestureDetector(
  child: Container(
    width: 200,
    height: 200,
    color: Colors.greenAccent,
  ),
  //on找到事件
  // onTap
  onTap: (){
    print("tap");
  },
  // 双击
  onDoubleTap: (){
    print("doubleTap");
  },
  // 长按
  onLongPress: (){
    print("long press");
  },
  // 还有很多不一一列举,详情需要查询api
  // 拖动,缩放...
),

十二. flutter——网络请求

点击之后👇

Flutter

在flutter中如何访问一个HTTP接口

使用第三方库dio

  1. stf快捷创建一个有状态的组件
  2. 在pubspec.yaml文件里添加dio依赖,然后在命令行flutter pub get下载—— dio | Dart package (pub.dev)
  3. 然后页面中import
import 'package:dio/dio.dart';
  1. 添加mypage
 @override
 Widget build(BuildContext context) {
   return Scaffold(
     appBar: AppBar(

       backgroundColor: Theme.of(context).colorScheme.inversePrimary,

       title: Text(widget.title),
     ),
     //这里添加MyPage
     body: MyPage(),

   );
 }
}
  1. 完整stful
// 一个有状态的组件
//这样在初始化的时候就会显示这个组件
class MyPage extends StatefulWidget {
  const MyPage({super.key});

  @override
  State<MyPage> createState() => _MyPageState();
}

class _MyPageState extends State<MyPage> {
  String _data="";
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children:<Widget> [
          TextButton(onPressed:()async{
            Dio dio=new Dio();
            //async await 处理了这句的报错,相当于异步处理变成了同步调用
            Response res= await dio.get('https://www.baidu.com');
            print("result"+res.data.toString());

            // 通知页面刷新
            setState(() {
              _data=res.data.toString();
            });

          },
            child: Text("发起http请求"),
            style: ButtonStyle(
              backgroundColor: MaterialStateProperty.all<Color>(Colors.red),
            ),
          ),
          Scrollbar(
              child: Container(
            height: 400,
                child: SingleChildScrollView(
                  child: Text(_data),
                ),
          ))
        ],
      ),
    );
  }
}
上面是以get距离,请求的是百度的地址

当然也可以传参

p33 实战

十三. flutter——路由

1. 从A页面跳转到B页面

    1. 快捷创建两个stl
    1. 分别写....

Flutter

Flutter

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(

        backgroundColor: Theme.of(context).colorScheme.inversePrimary,

        title: Text(widget.title),
      ),
      //这里添加MyPage
      body: FirstPage(),

    );
  }
}
//1. ————————————————————————————————————————
class FirstPage extends StatelessWidget {
  const FirstPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("第一个页面"),
      ),
      body: Column(
        children: <Widget>[
          TextButton(
            onPressed: (){
              // 跳(第一个参数:上下文,第二个参数:往哪跳)
              Navigator.push(context, new MaterialPageRoute(builder: (route)=>new SecondPage()));
            },
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all<Color>(Colors.red),
              ),
              child:Text("跳转到第二个页面"))
        ],
      ),
    );
  }
}

//2. ——————————————————————————————————————————
class SecondPage extends StatelessWidget {
  const SecondPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("第二个页面"),
      ),
      body: Column(
        children: <Widget>[
          TextButton(
              onPressed: (){
                Navigator.pop(context);
              },
              style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all<Color>(Colors.blue),
              ),
              child:Text("返回到第一个页面"))
        ],
      ),
    );
  }
}

2. 页面间传递数据

  • 页面向另一个页面传递参数
  • 另一个页面还可以返回给第一个页面

Flutter

Flutter

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(

        backgroundColor: Theme.of(context).colorScheme.inversePrimary,

        title: Text(widget.title),
      ),
      //这里添加MyPage
      body: ListPage(),

    );
  }
}
class ListPage extends StatelessWidget {
  // const ListPage({super.key});
  List _data=[
    {"id":1,"name":"oppo"},
    {"id":2,"name":"huawei"},
    {"id":3,"name":"xiaomi"},
  ];
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Container(
        height: 400,
        child: ListView.builder(
          itemCount: _data.length,
            itemBuilder: (context,index){
            return new ListTile(
              title:Text(_data[index]["name"]),
              onTap: ()async{
                String result=await Navigator.push(context, new MaterialPageRoute(builder: (context)=>new DetailPage(_data[index]["id"],_data[index]["name"])));
                print("接收到的返回值:"+result);
                },
            );
            }
        ),
      ),
    );
  }
}
class DetailPage extends StatelessWidget {
  // const DetailPage({super.key});
  int goods_id=0;
  String goods_name="";

  // 第二个页面通过构造函数来请求参数
  DetailPage(this.goods_id,this.goods_name);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Text("id"+this.goods_id.toString()),
          Text("name"+this.goods_name),
          TextButton(
              onPressed: (){
                Navigator.pop(context,"这是来自第二个页面的问候"+this.goods_name);
              },
              child: Text("返回"))
        ],
      ),
    );
  }
}

十四. flutter——调用原生native代码

  1. 引两个包
import 'dart:async';
import 'package:flutter/services.dart';
转载自:https://juejin.cn/post/7367009718835920931
评论
请登录