Flutter开发(五):Flutter布局与列表

1.Flutter 中的线性布局(Android 中 LinearLayout)

在 Flutter 中,可以使用 Row (横向)和 Column (纵向) widget 来实现同样的效果:

void main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('1'),
        Text('2'),
        Text('3'),
        Text('4'),
      ],
    );
  }
}
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        Text('1'),
        Text('2'),
        Text('3'),
        Text('4'),
      ],
    );
  }
}

2.Flutter 中的相对布局(Android 中 RelativeLayout)

在 Flutter 中,可以通过 Column、Row 和 Stack 的组合来实现相对布局的效果。

3.使用 widget 定义布局属性

在 Flutter 中,布局主要由专门设计用于提供布局的小部件定义,并结合控件 widget 及样式属性。

如,行和列 widgets 控制一个数组中的条目,并且将它们分别垂直和水平对齐。Container widget 控制一个布局的样式和属性,Center widget 负责将它的子 widget 居中。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
        child: Column(
      children: <Widget>[
        Container(
          color: Colors.red,
          width: 100.0,
          height: 100.0,
        ),
        Container(
          color: Colors.blue,
          width: 100.0,
          height: 100.0,
        ),
        Container(
          color: Colors.green,
          width: 100.0,
          height: 100.0,
        ),
      ],
    ));
  }
}

4.分层布局

在 Flutter 中,使用 Stack widget 控制子 widget 在一层,子 widgets 可以完全或部分覆盖下面 widgets。

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Stack(
        alignment: const Alignment(0.6, 0.6),
        children: <Widget>[
          CircleAvatar(
            backgroundImage: NetworkImage(
              "https://avatars3.githubusercontent.com/u/14101776?v=4"
            ),
          ),
          Container(
            decoration: BoxDecoration(
              color: Colors.black45
            ),
            child: Text('Hello'),
          )
        ],
    );
  }
}

5.设置布局样式

通过 Padding、Center、Column、Row 来设置布局样式,这些都是 widget。

class MyApp extends StatelessWidget {
  var textStyle = TextStyle(
      fontSize: 20.0, color: Colors.cyan, fontWeight: FontWeight.w600);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        children: [
          Text(
            '你好',
            style: textStyle,
          ),
          Padding(
            padding: EdgeInsets.all(20.0),
            child: Icon(Icons.lightbulb_outline, size: 48, color: Colors.red),
          ),
        ],
      ),
    );
  }
}

6.Flutter 中的滑动组件(Android 中 ScrollView)

使用 ListView :

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ListView(
      children:[
        Center(
          child: Text('1'),
        ),
        Center(
          child: Text('1'),
        ),
        Center(
          child: Text('1'),
        ),
        Center(
          child: Text('1'),
        ),
      ],
    );
  }
}

7.Flutter中的列表组件(Android 中 ListView)

如下:


class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: _getListData(),
      ),
    );
  }

  _getListData() {
    List<Widget> widgets = [];
    for (int i = 0; i < 50; i++) {
      widgets.add(Padding(padding: EdgeInsets.all(10.0),child: Center(child: Text("第 $i 个")),));
    }
    return widgets;
  }
}

8.点击列表中的 item

添加手势即可,用 GestureDetector,如下:

void main() {
  runApp(MaterialApp(home: MyApp()));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        children: _getListData(),
      ),
    );
  }

  _getListData() {
    List<Widget> widgets = [];
    for (int i = 0; i < 50; i++) {
      widgets.add(
        GestureDetector(
            child: Padding(
              padding: EdgeInsets.all(10.0),
              child: Center(child: Text("第 $i 个")),
            ),
            onTap: () {
              print('点击 $i');
            },
            onDoubleTap: () {
              print('双击 $i');
            }),
      );
    }
    return widgets;
  }
}

9.动态更新 ListView

如果想通过 setState() 方法更新 widget 列表,会发现并没有更新,因为调用 setState() 方法,Flutter 会检查 widget 树什么地方改变了,得到 ListView 时,它用 == 判断,发现两个 ListView 是相同的,所以不会更新。

更新 ListView 的方法是,创建一个 ListView.builder 接受两个主要参数:列表的初始长度和一个 ItemBuilder 方法。

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Widget> widgets = [];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();

    for (int i = 0; i < 50; i++) {
      widgets.add(getRow(i));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView.builder(
        itemCount: widgets.length,
        itemBuilder: (BuildContext context,int position){
          return getRow(position);
        },
      ),
    );
  }

  getRow(int i) {
    return GestureDetector(
        child: Padding(
          padding: EdgeInsets.all(10.0),
          child: Center(child: Text("第 $i 个")),
        ),
        onTap: () {
          setState((){
            widgets.add(getRow(widgets.length + 1));
          });
        });
  }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值