美文网首页Flutter中文社区Flutter圈子
@_@小刘同学flutter基础——持续更新

@_@小刘同学flutter基础——持续更新

作者: dearjj | 来源:发表于2019-06-16 16:07 被阅读118次

Flutter widgets

stateful widgets

stateful widget 中可以通过传入的data(external data)参数重新渲染组件, 同时在组件内部改变数据(internal data)

class MyApp extends StatefulWidget {
  final String text;
  MyApp(this.text); // constructor
    State<StatefulWidget> createstate(){
        return _myapp()
    }
}

class _myapp extends State<MyApp>{
    List<String> texts = [];
    void iniState() {
        super.initState();
        this.texts.add(Widget.text);
    }// Widget 
    Widget build(BuildContext context) {
        return //return something
            ...
            onPressed(
            setState() {
                //do something
            }
        )
    }
}

stateless widget

stateless widget 用于渲染普通组件, 静态组件

class Product extends StatelessWidget {
  final List<String> products;
  Product(this.products);
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return Column(
      children: products
          .map(
            (element) => Card(
                  elevation: 6.0,
                  child: Column(
                    children: <Widget>[
                      Image.asset('assets/food.jpg'),
                      Text(element)
                    ],
                  ),
                ), //card
          )
          .toList(),
    );
  }
}

Create ListView

用来创建一个dynamic list

使用 ListView.builder

Widget build(BuildContext context){
return ListView.builder(
    itemBuilder: ,// how to create a widget
    itemCount: // how many times
)
}

假设我们定义了一个List<String>

itemCount 就是长度: products.length

itembuilder 对应了一个widget 带两个参数:

widget pattern(BuildContext context, int index) {
    return Card(
        child: Column(
            children: <Widget>[
                Image.asset('.../...'),
                Text(products[index])
            ]
        )
    )
}

这种方法更加节省资源, 只会创建在页面上能看见的widget ,未出现的不会创建后占用内存

然后, 当我们想在另一个文件中使用listview, 我们需要添加Expanded

Expanded(
    child: pattern()
)

Tabs & Drawers

添加tab bars, 用DefaultTabController 来wrap整个widget, 然后在body中最外层使用TabView

tabs

bottom

使用 bottonNavigationbars

bottomNavigationBar: 
          TabBar(
            labelColor: Theme.of(context).primaryColor,
            unselectedLabelColor: Colors.grey,
            tabs: <Widget>[
              Tab(
                icon: Icon(Icons.create),
                text: 'create product',
              ),
              Tab(
                icon: Icon(Icons.list),
                text: 'my products',
              )
            ],
          ),
top

在appbar 添加一个bottom 属性, 然后再用TabBar

appBar: AppBar(
    title: Text('title'),
    bottom:           
    TabBar(
            labelColor: Theme.of(context).primaryColor,
            unselectedLabelColor: Colors.grey,
            tabs: <Widget>[
              Tab(
                icon: Icon(Icons.create),
                text: 'create product',
              ),
              Tab(
                icon: Icon(Icons.list),
                text: 'my products',
              )
            ],
          ),
)

drawers

单独添加drawer组件

          drawer: Drawer(
            child: Column(
              children: <Widget>[
                AppBar(
                  automaticallyImplyLeading: false,
                  title: Text('choose'),
                ),
                ListTile(
                  title: Text('Manage Products'),
                  onTap: () {
                    Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                            builder: (BuildContext context) =>
                                ProductCenter()));
                  },
                ),
                ListTile(
                  title: Text('Home'),
                  onTap: () {
                    Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                            builder: (BuildContext context) => Home()));
                  },
                )
              ],
            ),
          ),

先在外层用Column,这样可以添加组件列表,
然后在组件列表里添加drawer里要显示的Appbar(automaticallyImplyLeading: false 默认为true的时候, 会在drawer的appbar中再添加一个) , 和 ListTiles(每个ListTile对应了一个按钮栏)

Container

padding

EdgeInsets

decoration

decoration: BoxDecoration(
color: //,
border: Border(
    bottom: BorderSide()
    Top://
    Left://
    Right://
)
)

Row / Column

mainAxisAlignment// x轴布局

crossAxisAlignment//y轴布局

Flutter navigation

向 stack 里pop and push 会销毁所有的数据,因此要保留数据的话 ,需要用到路由管理

push

onPressed: ()=>Navigator.push<returnType>(
    context,// contains the infomation of current widget
    MaterialPageRoute(
        build: (BuildContext buildcontext) => SomeWidget(param1, param2)
    )
).then(
    (returnType value) {
        print(value)
    }
)

pushReplacement

同push , 但是替代当前stack,表现为无返回按钮

pushReplacementNamed

flutter中的路由管理, 用路径名代替builder,需要用到Navigator. pushReplacementNamed方法
在main中设置:

MaterialApp{
theme: ,
home: Auth(),
routes: //添加routes属性
{
        '/admin': (BuildContext context) => ProductCenter(),
        '/Home': (BuildContext context) => Home(this.products, this.deleteProduct, this.addProduct),
}, // 注意’/‘ 路径默认分配给home属性, 所以Auth 对应 ’/‘
}

一种特殊情况, 假设有一个ListView, 我们知道要用ListView.builder{ } 来传入一个itemBuilder widget 带一个index参数, 和一个itemCount。那么我们如果要制作一个详情页, 要求把每一个Item单独传入, 那么我们用builder的时候 会写成:

onPressed: ()=>Navigator.push<returnType>(
    context,// contains the infomation of current widget
    MaterialPageRoute(
        build: (BuildContext buildcontext) => SomeWidget(List[index])
    )
).then(
    (returnType value) {
        print(value)
    }
)

但是怎么改成路由呢?
flutter不支持类似/home/{index} 类似的写法
instead,在main里, 可以在route后添加onGenerateRoute(RouteSettings settings)
Routesettings 包含了路径名

      onGenerateRoute: (RouteSettings settings) {
        final List<String> pathElement = settings.name.split('/');
        if (pathElement[0] != '') {
          return null;
        }
        if (pathElement[1] == 'product') {
          final int index = int.parse(pathElement[2]);
          return MaterialPageRoute<bool>(
              builder: (BuildContext context) => ProductPage(
                  products[index]));
        }
      },

pop

对自定义按钮:

onpressed: () => Navigator.pop(context, true/false)

对实体按钮/默认返回按钮:

wrap the widget with WillPopScope

如果要用navigator另外pop带数据返回, 则默认Future.value为false

WillPopScope(
...
,
    onWillPoped: () {
        Navigator.pop(context, false)
        return Future.value(false)
    }
)

Dart 语法

const and final

  • final 指代, 某一个variable 一旦在内存中创建之后, 不能再创建新的variable, 只能在原有基础上进行更改
  • const 使变量创建好之后 , 无法对其内容进行进一步更改

[] and {} in constructor

{} make param named params
[] make param optional

传参

使得不同页面之间传递参数非常方便

  • regular data type
  • function
  • map
class MyApp extends StatelessWidget(
    final String string;
    final int int;
    final Map<String ,dynamic> myMap;
    final function onDelete;
    MyApp(this.string, this.int, this.myApp, this.onDelete);
    Widget build(BuildContext context){
    return ...
    }
)

私有函数

私有函数以划线开头

相关文章

网友评论

    本文标题:@_@小刘同学flutter基础——持续更新

    本文链接:https://www.haomeiwen.com/subject/gtegfctx.html