dart是一个强大的脚本类语言,可以不预先定义变量类型,会自动推导
var str='hello';
String str='this is var';
var a;
a = 'afas';
a = {};
a = 1;
//这样不会报错
var a=1;
a = 'afas';
a = {};
//报错
// main(){
// print('你好dart')
// }
//表示main方法没有返回值
// void main(){
// }
main(List<String> args) {
var str='hello dart';
String str1='hello dart';
int num=129;
var num1=129;
print(str);
final t=new DateTime.now();//正确,final具有惰性初始化的特性
// const t1=new DateTime.now();//错误
}
main(List<String> args) {
//可以正常修改
final a = [1, 2];
a[0] = 20;
print(a[0]);//20
//下面修改const的值报错
const a1 = [1, 2];
a1[0] = 20;
}
main(List<String> args) {
//多行定义:三引号(单或者双都行)
String s1='''
this is
hello
world
''';
//原样输出:能正常输出\n而不换行
String s11=r"hello \n dart";
print(s1);
//字符串拼接
String s2='dart';
print("$s1 $s2");
print(s1+s2);
//数值类型
int n1=123;
double n2=3.14;
//布尔类型
bool b=true;
//数组类型
//方式一
List l1=['a',1];
print(l1.length);
print(l1[0]);
//方式二
List l2=new List();
l2.add('1');
l2.add(123);
List l3=new List<String>();
// l3.add(1); 不行,如果约定了类型,则必须类型符合
//字典
//方式一
Map m1={
'name':'zq',
'age':20,
'work':['1',20],
};
print(m1); //{name: zq, age: 20}
print(m1['name']); //zq 只能通过该种方式访问,不能通过点方式
//方式二
var p=new Map();
p['age']=20;
print(p);
//判断数据类型: is
var b2=m1['work'][0] is String;
print(b2); //true
}
main(List<String> args) {
var c1='\u{1f44f}';
Runes c2=new Runes('\u2665 \u{1f605} \u{1f60e} \u{1f47b} \u{1f596} \u{1f44d}');
print(c1);
print(c1.codeUnits);
print(c1.runes.toList());
print(new String.fromCharCodes(c2));
}
#radix
#bar
main(List<String> args) {
int a=13;
int b=5;
print(a~/b);//2
print(a%b);//3
int b1; //如果b1在初始化时候赋值,则下面的??=无效
b1??=23; //表示如果b为空的话把23赋值给b
print(b1);//23
}
main(List<String> args) {
bool flag=true;
if(flag){
}else{
}
int a=flag?10:20;
print(a);
var a1=22;
var b=a1??10;
print(b);//22
}
main(List<String> args) {
String s1 = '1213.2';
try {
int i1 = int.parse(s1);
double i2=double.parse(s1);
} catch (e) {
print(e);
}
print(s1.isEmpty); //false
print(s1==null);//判断是否为空
}
main(List<String> args) {
for (var i = 0; i < 10; i++) {
print(i);
}
while (true) {
//break只能跳出一层循环
break;
}
do {
break;
} while (true);
}
switch(sex){
case 0:
break;
default:
break;
}
常用属性:
常用方法:
main(List<String> args) {
List l1 = [1, 2, 3, "hello"];
List l2 = const [1, 2, 3];
// l2[0] = 5;//不能修改
List l3 = <int>[1, 2, 3];
// l3[0] = 'a';赋值不能修改类型
List l4 = new List();//输出[]
}
常用属性:
常用方法:
main(List<String> args) {
var b = 12;
Map m1 = {"a": 1, b: 12};
//不可变Map
Map m2 = const {"f1": "a"};
//构造创建
Map m3 = new Map();
}
main(List<String> args) {
var s = new Set();
s.add(1);
s.add(11);
s.add(1);
print(s.toList()); //[1, 11]
List l = ['测试', 1];
s.addAll(l);
print(s.toList()); //[1, 11, 测试]
var m = {'age': 12, 'name': 'zs'};
print(m.keys.toList()); //[age, name]
//遍历list可以用for in
for (var item in l) {}
//通用方法
l.forEach((value){
print(value);
});
var nl=l.map((value){
return value*2;
});
print(nl); //(测试测试, 2)
print(nl.toList()); //[测试测试, 2]
var t1=[1,2,3,4,5,6];
var b=t1.any((value){
return value>3;
});
print(b); //true
}
main(List<String> args) {
var i=test(10);
print(i);
//命名函数要这样传值
test1('zq',age:30);
test2(hello);
}
/**
* 【】内部是可选参数,可不传入
* 可选参数内部可以默认赋值
可选参数可以是被[]包裹或者{}也是等效
*/
int test(int num,[int sex=30,String name]){
if(name==null||sex==null){
return -1;
}
print('自定义方法');
return num;
}
/**
* 命名参数
*/
void test1(String name,{int age,String sex='男'}){
print(sex);
}
/**
* 把方法当作参数
*/
void test2(fn){
fn();
}
void hello(){
print('hello');
}
main(List<String> args) {
List l = ['平', '香蕉'];
l.forEach((value)=>{
//箭头函数
});
//匿名方法
var prin=(){
print('123');
};
prin();
//自执行
((){
print('这里是自执行方法');
})();
//闭包
fn(){
var a=1;
return(){
a++;
print(a);
};
}
var b=fn();
b();//2
b();//3
b();//4
}
main(List<String> args) {
List l1 = ["a", "b", "c"];
l1.forEach(print); //输出 a b c print是系统内置的输出函数
print(strPepeat("lll")); //lllllllll
List l11 = ["h", "e", "l"];
print(listTimes(l11, strPepeat)); //[hhh, eee, lll]
}
String strPepeat(str) => str * 3;
//传递回到函数,依然可以为传递的回调函数返回值定义类型
//可以添加String s也可以var也可以不写类型
//List listTimes(List list, String fn(String s))
List listTimes(List list, String fn(s)) {
for (var i = 0; i < list.length; i++) {
list[i] = fn(list[i]);
}
return list;
}
Dart是以们使用类和单继承的面向对象语言,所有的对象都是类的实例,并且所有的类都是Object的子类。
//引入
import 'person.dart';
main(List<String> args) {
//调用默认构造函数
var p = new Person('男');
print(p);
p.getInfo(); //zq--30
//调用命名构造函数:这种方式不会触发默认构造函数的sex初始化
var p1 = new Person.test();
p1.getInfo(); //打印的sex为null;
}
class Person {
String sex;
//构造函数-也被称为类的重写
// Person(String sex){
// this.sex=sex;
// }
//构造函数简写
Person(this.sex);
//命名构造函数可以有多个
Person.test() {
print('命名构造函数');
}
String name = 'zq';
int age = 30;
void getInfo() {
print("${this.name}--${this.age}--${this.sex}");
//如果是单个字符,省略{}大括号
print("a$a");
}
}
main(List<String> args) {
var p = new Person();
print(p.sum(1, 2)); //3
}
class Person {
//主要:可以这么定义类中的方法
Function sum = (a, b) {
return a + b;
};
}
class Person {
//加上下划线就是私有属性,但是必须定义私有属性
//和使用私有属性不在同一个文件,例如此时如果main
//方法和当前类再一个文件,则私有属性其实还是公有
String _sex;
Person(this._sex);
void _getInfo() {
print("${this._sex}");
}
}
import 'person.dart';
main(List<String> args) {
var p = new Person('男');
// print(p._sex); 私有属性无法使用
// p. _getInfo();私有方法无法使用
}
java中一般都是定义方法,使用get/set,dart中有内置属性,直接在前面添加set/get 即可
import 'person.dart';
main(List<String> args) {
var p = new Person(1);
print( p.chengyi);//20
//注意set虽然有()但是还是赋值
p.haha=20;
print(p.chengyi);//400
}
class Person {
//注意此时,可以是num类型
num age;
Person(this.age);
set haha(value){
this.age=value;
}
get chengyi{
return this.age*20;
}
}
class Person {
num age;
//Dart中我们也可以再构造函数运行之前初始化实例,如下
Person():age=20{
}
// Person():age=20;这样也行
}
class Person {
static num age=30;
static void show(){
print(age);
}
}
import 'person.dart';
main(List<String> args) {
//静态属性
print(Person.age);
//静态方法
Person.show();
}
? 条件运算符
as 类型转换
is 类型判断
.. 级联操作
import 'person.dart';
main(List<String> args) {
Person p;
//正常情况下,此时p没有初始化调用方法肯定报错加上?
//代表p不为Null才执行,否则不执行
p?.show();
var p1=new Person(30);
//判断p对象是否属于person类
if(p1 is Person){}
// var p2='';这种会直接定义类型,下面赋值person报错
var p2;//但是这种不会报错
p2='';
p2=new Person(30);
p2.show();//老版本这样调用报错,新版本直接使用即可
(p2 as Person).show();//老版本这样调用,相当于强转
//级联操作,省略代码
var p3=new Person(30);
p1..age=50
..show();
}
class Person {
num age=30;
Person(this.age);
show(){
print(this.age);
}
}
main(List<String> args) {
var s = new Student('asd',20);
s.show();
}
class Person {
String name;
Person(this.name);
show() {
print(this.name);
}
Person.now(this.name);
}
class Student extends Person {
int age;
// Student(String name) : super(name);
//也可以继承父类的命名构造
// Student(String name) : super.now(name);
Student(String name,int age) : super(name){
this.age=age;
}
@override //可写可不写但是建议加上
show(){
//super.show(); 子类可以通过这种方式调用父类的方法
print('子类重写父类的方法');
}
}
main(List<String> args) {
//多态
Person p = new Student();
Person p1 = new Teacher();
p.show();
p1.show();
}
abstract class Person {
show();//抽象方法
printInfo(){
print('抽象类可以有非抽象方法');
}
}
class Student extends Person {
@override
show() {
print('子类实现父类的抽象方法');
}
}
class Teacher extends Person {
@override
show() {
print('haha');
}
}
dart中的接口没有interface关键字定义接口,都是普通类或者抽象类,同样使用implements关键字实现。dart接口如果实现的类是普通类,会将普通类和抽象中的属性的方法全部重写一遍。因为抽象类可以定义抽象方法,普通类不可以,所以一般如果要实现java接口那样的方法,一般都是使用抽象类。
main(List<String> args) {
var s= new Student('zq');
s.show();
}
abstract class Person {
String name;
show();
printInfo() {
print('抽象类可以有非抽象方法');
}
}
class Student implements Person {
@override
String name;
Student(this.name);
@override
show() {
print('子类实现父类的抽象方法');
}
@override
printInfo() {
print('hehe');
}
}
main(List<String> args) {
var s= new Student();
s.show();
s.run();
}
abstract class Person {
show();
}
abstract class Boy {
run();
}
class Student implements Person,Boy {
@override
show() {
print('show');
}
@override
run() {
print('run');
}
}
使用with关键字
main(List<String> args) {
var c= new C();
c.show();
c.run();
c.eat();
print(c is C); //true
print(c is B); //true
print(c is D); //true
}
class A {
show(){
print('show');
}
}
class B {
run(){
print('eun');
}
}
class D {
eat(){
print('eat');
}
}
class C extends A with B,D {
@override
show() {
print('showc');
}
@override
run() {
print('runc');
}
}
> A不是minix类可以有构造函数,B,D不能有构造函数是minix类。
而且不论是继承还是minix都不见得需要重写父级的方法。
如果A,B,D出现同名属性或者方法,使用D,所以是有顺序优先级的。
main(List<String> args) {
var p = new Person();
p.getData<String>('asda');
p.getData<num>(123);
}
class Person {
//范型方法
T getData<T>(T data) {
return data;
}
}
main(List<String> args) {
var p = new Person<String>();
p.add('asdas');
}
class Person<T>{
List list=new List<T>();
add(T value){
this.list.add(value);
}
}
main(List<String> args) {
var f=new FileCache<String>();
f.getByKey('asd');
}
class FileCache<T> implements Cache<T> {
@override
getByKey(String key) {}
@override
void setByKey(String key, T value) {}
}
abstract class Cache<T> {
getByKey(String key);
void setByKey(String key, T value);
}
main(List<String> args) async{
var r=await test();
print(r);
}
test() async{
return 'Hello';
}
name: test
description: A new test
dependencies:
dependencies:
http: ^0.12.0+2
粘贴到pubspec.yaml文件中
import 'dart:convert' as convert;
import 'package:http/http.dart' as http;
main(List<String> arguments) async {
var url = "https://api.douban.com/v2/movie/imdb/tt0111161?apikey=0df993c66c0c636e29ecbb5344252a4a";
var response = await http.get(url);
if (response.statusCode == 200) {
var jsonResponse = convert.jsonDecode(response.body);
print("请求成功---$jsonResponse");
} else {
print("请求失败: ${response.statusCode}.");
}
}
import 'lib/Persion1' as P1;
import 'lib/Persion2' as P2;
在两个文件中都是Person对象,则下面使用的时候
直接new Person就不知道用的是那个,所以通过别名导入
var pp1=new P1();
var pp2=new P2();
import 'lib/Methods' show f1,f2;
只导入f1 f2两个函数
import 'lib/Methods' hide f1;
除了f1其他函数都导入
flutter run 需要按r/R 很麻烦
热重载不是全能的:(替代方式是flutter run)
1. 全局变量初始化器
2. 静态字段初始化器
3. app的main()方法
所以一般调试界面UI才使用热重载
但是可以通过vscode调试的时候的restart按钮实现R同样效果,所以flutter run可以直接放弃
//引入material组件库,里面规定了很多组件,还规定了移动端UI渲染的一些规范
import 'package:flutter/material.dart';
//定义入口函数
//runApp是系统函数,用来执行组件渲染
void main() => runApp(
//MyApp是一个组件,命令是系统规定好的,修改起来比较麻烦,所以按照约定来即可
MyApp());
//所有组件都是一个类,类型是Widget
//StatefulWidget:有状态组件/动态组件
//StatelessWidget:无状态组件/静态组件
class MyApp extends StatelessWidget {
//每一个静态组件都需要传递一个build函数
//build是系统规定好的渲染函数,返回值一个组件
@override
Widget build(BuildContext context) {
//引入了material.dart那么此处必须是MaterialApp开始
return MaterialApp(
//不会显示在app上面,页面收起来时候可以看到
title: 'Flutter Demo',
//规定当前组件的默认颜色
theme: ThemeData(
primarySwatch: Colors.blue,
),
//传递自定义组件
home: MyHomePage(title: '这是一个测试'),
);
}
}
//每个组件类,首字母必须大写
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
//Scaffold:脚手架工具,可以调用很多的组件
return Scaffold(
//导航
appBar: AppBar(
title: Text(widget.title),
),
//Center也是一个组件,相当于内容居中
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.display2,
),
],
),
),
//右侧悬浮按钮
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
Scaffold,没有这个界面一片漆黑,当然也可以一点点排列但是不方便,而且不适宜复用
import 'package:flutter/material.dart';
class SelfText extends StatelessWidget {
@override
Widget build(BuildContext context) {
//不用脚手架黑色一片
// return Container(
// child: Text('Hello'),
// );
return Scaffold(
appBar: AppBar(
title: Text("Hello"),
),
body: Center(
child: Text(
"Hello Flutter",
style: TextStyle(
fontSize: 20.0, color: Colors.pink, fontWeight: FontWeight.w700),
overflow: TextOverflow.ellipsis, //溢出点点点
maxLines: 1,
),
),
);
}
}
import 'package:flutter/material.dart';
class SelfImage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
// child: Image(
// image: NetworkImage(
// "https://www.freesion.com/images/13/6cae05cf64b85fca7a5f207b7a4159cd.png")),
//对宽高不满意使用Container
child: Container(
width: 200,
height: 100,
child: Image(
//图片伸展方式
fit: BoxFit.cover, //图片完全伸展开,不拉伸,但是可能会裁切
// image: NetworkImage(
// "https://www.freesion.com/images/13/6cae05cf64b85fca7a5f207b7a4159cd.png")),
//引入本地图片
//1. 在项目根目录建立文件夹 images
//2. 在项目yaml这个文件里面进行一些配置,本地图片都需要在yml文件里面一个个添加
// assets:
// - images/1.png
image: AssetImage("images/1.png")), //必须和配置文件里面路径一致
),
),
);
}
}
当组件需要修改的属性没法直接在组件内部提示修改的时候,则外层包裹一层Container,例如边距,背景色什么的。
import 'package:flutter/material.dart';
class TextSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
child: Text(
'Abroad: Thought and ability is the key, the domestic: relationship and can run.The teacher said to hear and fine, I know hes salary.The man called the romantic love rich, rich in the coquettish woman.',
textAlign: TextAlign.justify, //左右对齐
//height: 1.1 类似于行高
style: TextStyle(height: 1.1),
),
);
}
}
import 'package:flutter/material.dart';
class SelfContainer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
//盒子容器-一般是添加内容
body: Container(
// child: ,
//装饰器:可以传递背景色/图,边框等等
decoration: BoxDecoration(color: Colors.pink),
width: 100,
height: 100,
margin: EdgeInsets.all(30),
padding: EdgeInsets.all(20),
),
//Container的child可以传递任何组件,一般自定义组件的时候,系统组件不支持传值,我们就在外层套上Container盒子
);
}
}
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
class SelfHttpRequest extends StatefulWidget {
@override
_SelfHttpRequestState createState() => _SelfHttpRequestState();
}
class _SelfHttpRequestState extends State<SelfHttpRequest> {
List _list = [];
//重点:该函数其实相当于页面还未加载时候自动执行,类似于vue中的create
@override
void initState() {
getMovieList();
super.initState();
}
void getMovieList() async {
try {
// Dio d = Dio(); 在flutter中new对象可以省略new直接使用,Dio库也可以这样
Response response =
await Dio().get("http://www.liulongbin.top:3005/api/getlunbo");
//相当于json序列化为对象,接收值根据情况而定,如果是数组则是List
Map responseData = jsonDecode(response.toString());
_list = responseData['message']; //取对象里面的某个属性
// print(responseData['message']);
} catch (e) {
print(e);
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView.builder(
itemCount: _list.length,
itemBuilder: (BuildContext context, int i) {
// Map _item = _list[i];
return Text(
'${_list[i]["url"]}',
style: TextStyle(fontSize: 30),
);
}),
);
}
}
动态组件一般针对渲染之后还需要修改的组件,例如点击操作逻辑或者网络请求渲染
//调用的时候传参如此: home: Increase(title: 'flutter')
import 'package:flutter/material.dart';
//动态组件 statefulWidget
class Increase extends StatefulWidget {
//动态组件传参 @required使成为必传项
Increase({Key key, @required this.title}) : super(key: key);
final String title;
//每一个动态组件里面都需要一个createState函数:生成状态
@override
_IncreaseState createState() => _IncreaseState();
}
//每一个动态组件都需要一个控制器,用来对组件内部的状态进行控制,并且渲染被控组件的UI结构
//控制器有命名要求,_被控制组件名State
class _IncreaseState extends State<Increase> {
//页面当中的数字需要增加,定义一个状态值
int _counter = 0;
//数字自增函数
void _increaseCounter() {
//不使用setState虽然数据变化但是UI不会更新
setState(() {
_counter++;
});
}
//控制器内部的build函数,用来渲染被控组件的UI结构
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
//重点: flutter中widget代表被控制的组件,widget可以获取所有Increase组件的属性
title: Text(widget.title),
),
body: Center(
//从上到下排列的组件的盒子
child: Column(
//从上到下排列组件,这个是排列的方式
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('请点击按钮'),
Text(
'$_counter',
style: TextStyle(fontSize: 30),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _increaseCounter,
//按住时候的提示信息
tooltip: 'increase button',
child: Icon(Icons.add),
),
);
}
}
//静态函数传参
/*
class Abc extends StatelessWidget {
Abc({Key key, this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context) {
return Container();
}
}
*/
其实就是行和列,但是和ListView不同的是,ListView内容不会溢出会出现滚动,而行列内容超出则会报警告而且不会显示
import 'package:flutter/material.dart';
import 'package:flutter_app/lakes/IconSection.dart';
import 'package:flutter_app/lakes/TextSection.dart';
import 'package:flutter_app/lakes/TitleSection.dart';
class Lakes extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Image(image: AssetImage('images/1.png')),
TitleSection(),
IconSection(),
TextSection()
],
),
);
}
}
//Column 纵向排版
//Row 横向排版
//给它们两个传递参数,都有一个children属性,后面跟一个数组,里面的每一项都是一个widget组件
import 'package:flutter/material.dart';
class IconSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Row(
//重点:主轴副轴排列方式一般用于对齐,主轴就是当前组件如果是列主轴就是竖向,副轴就是横向
//其他组件也是依此类推
//在主轴上均匀排列
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
// crossAxisAlignment: CrossAxisAlignment.center, 副轴排列方式
children: <Widget>[
_IconItem(title: 'CALL', icon: Icons.call),
_IconItem(title: 'ROUTE', icon: Icons.near_me),
_IconItem(title: 'SHARE', icon: Icons.share)
],
);
}
}
class _IconItem extends StatelessWidget {
_IconItem({Key key, @required this.title, @required this.icon})
: super(key: key);
final IconData icon;
final String title;
@override
Widget build(BuildContext context) {
return Column(children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 5),
child: Icon(
icon,
color: Colors.blue,
)),
Text(
'$title',
style: TextStyle(color: Colors.blue),
)
]);
}
}
如果一行里面多个text组件然后长度不确定,则可能导致溢出,这时候明显overflow是无法有效显示省略号的,因为行里面没有这个属性,此时可以通过弹性布局(Expanded)实现
弹性布局-会自动占据空余部分
import 'package:flutter/material.dart';
class TitleSection extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(20),
margin: EdgeInsets.only(bottom: 15),
child: Row(
children: <Widget>[
//弹性布局-会自动占据空余部分
Expanded(
child: Column(
//主轴(此时是从上到下)和副轴(左右)
//使靠左对齐
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(bottom: 5),
child: Text("Oeschinen Lake Campground",
style: TextStyle(fontWeight: FontWeight.w700))),
Text(
"Kandersteg, Switzerland",
style: TextStyle(color: Colors.grey),
)
],
),
),
//星星图标
Icon(Icons.star, color: Colors.red),
Text("41")
],
),
);
}
}
import 'package:flutter/material.dart';
class Detail extends StatelessWidget {
Detail({Key key, this.url}) : super(key: key);
final String url;
@override
Widget build(BuildContext context) {
//特别注意,该脚手架一定要在路由跳转去的组件有,因为可能main.dart里面有根组件,根组件里面有
//这个脚手架,但是如果是路由跳转去页面,是和之前组件无关系的,如果不加可能导致
return Scaffold(
appBar: AppBar(
title: Text("电影详情"),
),
body: Center(
child: Column(
children: <Widget>[
Image(image: NetworkImage('$url')),
GestureDetector(
//手势识别器有很多种事件,此处只演示最简单的点击事件
onTap: () {
//返回上一级页面
Navigator.of(context).pop('49亿');
},
child: Text(
'49亿',
style: TextStyle(fontSize: 30),
),
)
],
),
),
);
}
}
不会溢出会,多出来的会显示滚动条;动态操作需要ListView.builder
import 'package:flutter/material.dart';
class MoveScroll extends StatelessWidget {
final List imgLit = [
{
"name": '哈哈哈1',
"url": "http://api.cms.liulongbin.top/images/lunbo1-min.jpg"
},
{
"name": '哈哈哈2',
"url": "http://api.cms.liulongbin.top/images/lunbo2-min.jpg"
}
];
final List imgLit1 = [
"http://api.cms.liulongbin.top/images/lunbo1-min.jpg",
"http://api.cms.liulongbin.top/images/lunbo2-min.jpg",
"http://api.cms.liulongbin.top/images/lunbo3-min.jpg"
];
@override
Widget build(BuildContext context) {
//一个排列的组件盒子,可以纵向排版,也可以横向排版
return Scaffold(
body: Center(
child: Container(
height: 130,
child: ListView.builder(
itemCount: imgLit.length,
scrollDirection: Axis.horizontal,
itemBuilder: (BuildContext context, int i) {
return _ImgItem(url: imgLit[i]["url"]);
})
// child: ListView(
// //横向排版
// scrollDirection: Axis.horizontal,
// children: <Widget>[
// _ImgItem(url: imgLit[0]),
// _ImgItem(url: imgLit[1]),
// _ImgItem(url: imgLit[2])
// ],
// ),
)),
);
}
}
class _ImgItem extends StatelessWidget {
_ImgItem({Key key, @required this.url}) : super(key: key);
final String url;
@override
Widget build(BuildContext context) {
return Container(
width: 350,
child: Image(
image: NetworkImage('$url'),
fit: BoxFit.cover, //展开图片
),
);
}
}
//Column和Row的排版上的简单区别
//会溢出,类似于一个盒子,横着放或者是竖着放,放多了溢出
//ListView和ListView.Builder 不会溢出,会有滚动条滑动
import 'package:flutter/material.dart';
import 'package:flutter_app/moviesscroll/Detail.dart';
class MoveScroll2 extends StatelessWidget {
final List imgLit = [
"http://api.cms.liulongbin.top/images/lunbo1-min.jpg",
"http://api.cms.liulongbin.top/images/lunbo2-min.jpg",
"http://api.cms.liulongbin.top/images/lunbo3-min.jpg"
];
@override
Widget build(BuildContext context) {
//一个排列的组件盒子,可以纵向排版,也可以横向排版
return Scaffold(
body: Center(
child: Container(
height: 130,
child: ListView.builder(
scrollDirection: Axis.horizontal,
//遍历数组渲染
itemBuilder: (BuildContext context, int i) {
return _ImgItem(url: imgLit[i]);
},
//遍历次数
itemCount: imgLit.length,
),
)),
);
}
}
class _ImgItem extends StatelessWidget {
_ImgItem({Key key, @required this.url}) : super(key: key);
final String url;
@override
Widget build(BuildContext context) {
//如果需要在组件上添加事件,那么就要调用一个组件GestureDetector
return GestureDetector(
//点击事件
onTap: () {
//跳转路由
//MaterialPageRoute 路由组件
// Navigator.of(context).push 是我们路由跳转的方法
Navigator.of(context)
.push(MaterialPageRoute(builder: (BuildContext context) {
return Detail(url: url);
})).then((val) {
//接收子页面返回的时候传递回来的数据
print(val);
});
},
child: Container(
width: 350,
child: Image(
image: NetworkImage('$url'),
fit: BoxFit.cover, //展开图片
),
),
);
}
}
//Column和Row的排版上的简单区别
//会溢出,类似于一个盒子,横着放或者是竖着放,放多了溢出
//ListView和ListView.Builder 不会溢出,会有滚动条滑动
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。