Flutter组件

282 阅读7分钟

组件

flutter的一个组件就是一个类

flutter可以分为两种 一种是无状态组件(静态组件) 可以使用stl输出组件结构

另一种是有状态组件(动态组件) 可以使用stf输出组件结构

使用组件时 规定是new +类名() 一般都把new省略

静态组件

一个静态组件必须有一个build方法

class 组件名字 extends StatelessWidget{
    @override
    Widget build(BuildContext context) {
        return null
    }
}

动态组件

分为两部分

一部分是处理状态 要重写createState方法 利用这个函数可以管理state 类似vuex 它的返回值类型是下面函数的名字 返回下面的实例(名字+()) 继承StatefulWidgest

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

一个是写结构的(和无状态的一样 把结构写在build方法中) 继承上面的类的名字

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    
  }
}

MaterialApp

根组件 一般写在最顶层 类似vue中App 里面封装了一些必要的widget

它可以设置title theme home debugShowMaterialGrid

title 是不显示出来的 只是定义了这个属性

debugShowMaterialGrid是定义界面右上角出现的图标 false就不显示这个图标

home相当于渲染一个组件 可以在home后面直接写组件中的内容 也可以引入一个组件 在home后面输入这个组件的名字

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowMaterialGrid:false,
      title: 'flutter',
      theme: ThemeData(
        primarySwatch: Colors.yellow
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('hello flutter'),
        ),
        body: Center(
          child: Text('flutter'),
        ),
      ),
    );
  }
}

Scaffold

相当于脚手架 是一个路由页的骨架

里面有appBar body

appBar是用AppBar这个组件

body可以使用所有的组件

Scaffold(
    appBar: AppBar(
      title: Text('hello flutter'),
    ),
    body: Center(
      child: Text('flutter'),
    ),

AppBar

导航栏组件 它可以定义 title actions leading centerTitle(标题的对齐方式)

leading中可以放一个图片 也可以放一个icon

title:这个title是现实在导航栏上

actions:是按钮的点击动作

centerTitle是头部导航标题是不是处于居中 true为居中

backgroundColor 头部导航的背景颜色

bottomNavigationBar:底部导航 是使用BottomNavigationBar

drawer:左侧抽屉式导航 是使用Drawer

AppBar(
  leading: Icon(Icons.search),
  centerTitle:true,
  title: Text('hello flutter'),
  actions: <Widget>[
    IconButton(
      onPressed: (){},
      icon: Icon(Icons.add),
    ),
  backgroundColor:Colors.red,
  ],
),
body: Center(
  child: Text('flutter'),
),
bottomNavigationBar: BottomNavigationBar(
  items: const<BottomNavigationBarItem>[
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      title: Text('首页')
      ),
    BottomNavigationBarItem(
    icon: Icon(Icons.search),
    title: Text('搜索')
    ),
    BottomNavigationBarItem(
    icon: Icon(Icons.add),
    title: Text('设置')
    ),
  ],
  
),
  ),

BottomNavigationBar

currentIndex:指定当前的索引 指定好之后 就会出现不一样的样式(一个按钮被选中的样式)

type:BottomNavigationBarType.fixed 如果底部按钮有超过3个时 使用这行就可以实现多个

onTap:点击下面的图标要执行的事情 是一个方法

backgroundColor 背景颜色

selectedItemColor 被选中后的背景颜色

unselectedItemColor 没有被选中的背景颜色

iconSize 组件的大小

items:用来放下面的控件 例如微信下面的 我的 发现 通讯录 是用BottomNavigationBarItem这个存放

int _current = 1;
void _onItemTapped(){
  setState((int index) {
     _current = index;
   });
}
 bottomNavigationBar: BottomNavigationBar(
    type:BottomNavigationBarType.fixed
    current:_current;
    onTap: _onItemTapped;
    items: const <BottomNavigationBarItem>[
    BottomNavigationBarItem(
      icon: Icon(Icons.home),
      title: Text('Home'),
    ),

BottomNavigationBarItem

里面有 icon title

BottomNavigationBarItem(
      icon: Icon(Icons.home),
      title: Text('Home'),
    ),

Drawer

drawer: Drawer(
    child: Column(
      children: <Widget>[
        ListTile(
          leading: CircleAvatar(
            child: Icon(Icons.home),
            
          ),
          title: Text('我的'),
    ),

Text

用于显示简单样式文本,它包含一些控制文本显示样式的一些属性

可以直接放文本

Text('文本')

style(用来设置文本的样式) 是使用TextStyle类

Text(
    style:TextStyle()
)

overFlow 用来设置文本溢出时,如果有多余的文本,可以通过overflow来指定截断方式,默认是直接截断,本例中指定的截断方式TextOverflow.ellipsis,它会将多余文本截断后以省略符“...”表示;

Text(
    overFlow:TextOverFlow.ellipsis
)

textAlign 文本的对齐方式 是用TextAlign

Text(
    textAlign:TextAlign.center
)

maxLines 文本最多占用多少行,指定文本显示的最大行数,默认情况下,文本是自动折行的,如果指定此参数,则文本最多不会超过指定的行。

Text(
    maxLines:1  //只能占一行
)

textScaleFactor 放大字体

Text(
    textScaleFactor:2
)

TextStyle

设置文本的样式 如颜色、字体、粗细、背景等

color 可以使用Color 也可以使用Colors进行设置

style:TextStyle(
    color:Colors.red,
    color:Color.fromRGBO(r, g, b, opacity)
)

fontSize 设置文本的大小 是一个固定的值

style:TextStyle(
    fontSize:40
)

fontWeight 设置文本的粗细 使用FontWeight

 style:TextStyle(
    fontWeight:FontWeight.w800 //数字可以变
)

fontFamily 设置文本字体

 style:TextStyle(
    fontFamily:'Courier'
)

decoration 文本的装饰器 decorationColor 修饰线的颜色 decorationStyle修饰线的类型

style:TextStyle(
    decoration:TextDecoration.lineThrough,
    decorationColor:Colors.red,
    decorationStyle:TextDecorationStyle.dashed
)

letterSpacing 字母之间的间距

style:TextStyle(
    letterSpacing:2
)

Image

设置图片 图片分为网络的图片和本地的图片

网络图片

Image(
    image:NetworkImage('图片的路径'),
    width:200,
)
Image.network('图片的路径',width:200)

本地图片

在根路径创建一个image文件夹 用来放图片

在pbspec.yaml中的flutter添上

 assets:
- images/avatar.png

注意: 由于 yaml 文件对缩进严格,所以必须严格按照每一层两个空格的方式进行缩进,此处assets前面应有两个空格

使用该图片也有两种方式 1.

Image(
    image:AssetImage('images/avatar.png')
)
Image.asset('images/avatar.png')

设置图片

width height

fit(缩放模式)

    Image(
        fit:BoxFit.fill
    )

repeat(重复方式) 默认是不重复的 使用ImageRepeat

Image(
    repeat:ImageRepeat.repeat //重复
)

alignment(对齐方式)

Image(
    alignment:AlignMent.center
)

Container

相当于html中的div

可以设置 width height

decoration 使用BoxDecoration

Container(
    width:100,
    height:100,
    decoration:BoxDecoration(
        color:Colors.red,
        border:Border.all(
            width:2,
            color:Colors.green
        ),
        borderRadius: BorderRadius.all(
            Radius.circular(10)
      )
    )
)

padding margin allignment

Container(
    padding: EdgeInsets.all(20),
    padding: EdgeInsets.fromLTRB(10, 20, 30, 40),
    margin: EdgeInsets.all(20),
    alignment: Alignment.bottomRight,
)

BoxDecoration

image div中的图片 类似于背景颜色 使用Image.network() 或者 Image.asset()

color div的颜色 使用Colors.颜色名或者Color.fromRGBA(0,0,0,0)

border div的边框 使用Border.all(width:) Border(top:BorderSide(width:))

borderRadius div边框的圆度 使用BorderRadius.circular(10)

按钮组件

RaisedButton

普通的按钮

color:这个按钮的颜色

textColor:按钮中的文本的颜色

Text:设置按钮中的文字

elevation:设置按钮的阴影

onPressed(){} 设置点击按钮发生的事情

textTheme:设置按钮的主题 使用ButtonTextTheme来进行设置 它还必须和color一起设置时才有效果 这个color和平常设置的不一样 看下面的案例

shape:设置按钮的形状

RaisedButton(
    child:Text('按钮'),
    color:Colors.blue,
    textColor:Colors.white,
    elevation:10
    
)
自定义按钮

设置自定义按钮时 需要外面包一个container 这样就可以设置按钮的大小

Container(
    width:100,
    height:60,
    RaisedButton(
        child:Text('按钮'),
        color:Colors.blue,
        textColor:Colors.white
    )
)

如果想设置一个自适应的按钮(宽度占满在整个屏幕),就在外面再设置一个Expanded

圆角按钮
ResiedButton(
    shape:RoundedRectangleBorder(
        borderRadius:BorderRadius.circular(10)
    )
)
圆形按钮

设置圆形按钮时 最好外面包一个Container 这样可以设置高度和宽度

Container(
    height:60,
    child:ResiedButton(
    shape:CircleBorder(
        side:BorderSide(color:Colors.blue) 
        //设置圆形按钮的边框 不设置这个时 也会出现一个圆形按钮
    )
)
)
带主题的按钮
RaisedButton(
    theme:ButtonTheme.primary,
    color:Theme.of(context).accentColor
)

Row

mainAxisAlignment:MainAxisAlignment.center

Column

 mainAxisAlignment:MainAxisAlignment.center

SizeBox

SizeBox(width:10)
SizeBox(height:10)

弹出框

提示信息框

AlterDialog()

void _alertDialog() async {
var result = await showDialog(
    barrierDismissible: false,
    context: context,
    builder: (context) {
      return AlertDialog(
        title: Text('提示信息'),
        content: Text('你确定删除吗'),
        actions: <Widget>[
          FlatButton(
            child: Text('取消'),
            onPressed: () {
              print('取消');
              Navigator.pop(context, 'cancel');
            },
          ),
          FlatButton(
            child: Text('确定'),
            onPressed: () {
              print('确定');
              Navigator.pop(context, 'ok');
            },
          )
        ],
      );
    });

}

SimpleDialog 点击这个弹出框的底部和这个界面的底部一致

  void _simpleDialog() async {
var result = await showDialog(
    barrierDismissible: false,
    context: context,
    builder: (context) {
      return SimpleDialog(
        title: Text('选择内容'),
        children: <Widget>[
          SimpleDialogOption(
            child: Text('选择A'),
            onPressed: () {
              Navigator.pop(context, 'A');
            },
          ),
          Divider(),
          SimpleDialogOption(
            child: Text('选择B'),
            onPressed: () {
              Navigator.pop(context, 'B');
            },
          )
        ],
      );
    });

}

还有第三方的 可以百度pub.dev 搜索

Divider()

是用来加一条横线

Stack()

用来实现定位的 在这里的第一个Container()相当于Stack 后面的都是依据第一个进行定位 里面可以放children alignment

 // Stack坐标轴的原点第一个容器中心点
return Stack(
    // alignment: Alignment(.5, .5),
    // alignment: Alignment(0, 0),
    alignment: Alignment(1, 1),
    // alignment: Alignment.bottomLeft,
    // alignment: Alignment.centerLeft,
    children: <Widget>[
      Container(
        width: 300,
        height: 400,
        color: Colors.red,
      ),
      Container(
        width: 80,
        height: 80,
        color: Colors.yellow,
      ),
      // Text("hello"),
      // Text("word")
    ],
  );

Wrap

看电视时第几集第几集 wrap就是把把他们包括起来

return Scaffold(
  appBar: AppBar(title: Text('wrap组件'),),
  body: Wrap(
  spacing: 10,
  
  children: <Widget>[
    RaisedButton(
      child: Text('第1集'),
      onPressed: (){},
    ),
    RaisedButton(
      child: Text('第1集'),
      onPressed: (){},
    ),
    RaisedButton(
      child: Text('第1集'),
      onPressed: (){},
    ),
    RaisedButton(
      child: Text('第1集'),
      onPressed: (){},
    ),
    RaisedButton(
      child: Text('第1集'),
      onPressed: (){},
    ),
    RaisedButton(
      child: Text('第1集'),
      onPressed: (){},
    ),
    RaisedButton(
      child: Text('第1集'),
      onPressed: (){},
    ),
  ],
),
);