Android开发 学习Flutter 入门

Android开发 学习Flutter 入门

一、前言

最近项目准备用Flutter混合开发,写写学习的笔记吧,学习Flutter首先需要了解Dart语言,(当然安全上网推荐一个Chrome插件(SetupVpn)),了解Dart相关语法之后,可以到Flutter中文网学习Flutter啦。

二、Flutter 环境搭建

Flutter中文网有详细的教程,我在Mac和Windows上都已经成功安装。

  • Flutter SDK 获取
    去flutter官网下载其最新可用的安装包,转到下载页 。下载后将其解压,当前目录将为环境变量需要配置的。

    image.png

  • mac 环境变量设置:

alias br="flutter packages pub run build_runner build" # br 快捷键
alias rmlock="rm -rf /Users/ningzhen942/app/flutter/bin/chche/lockfile" #删除lockfile 快捷键
export PATH=/Users/ningzhen942/app/flutter/bin:$PATH
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
image.png
  • 配置好环境变量 运行flutter --version 查看版本


    image.png
  • 运行 flutter doctor 查看环境状态


    image.png

三、Flutter 工程目录结构

四、Flutter Widget 与Android 控件联想

image.png

五、Demo(ListView)

168336246614882_result.gif
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:vscodeflutter/home.dart';
import 'package:vscodeflutter/muti_phote_page.dart';
import 'package:vscodeflutter/phote_view_page.dart';
import 'package:vscodeflutter/widght/gradient_text.dart';
import 'package:cached_network_image/cached_network_image.dart';

void main() {
  runApp(new MyApp(
    items: new List.generate(1000, (i) {
      if (i % 8 == 0) {
        return new HeadingItem("Heading I am No.$i");
      } else if (i % 8 == 1) {
        return new ImageItem(
            "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2572170802,3058063046&fm=26&gp=0.jpg",
            "Message body $i");
      } else if (i % 8 == 2) {
        List urls = new List.generate(8, (i) {
          return "https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3806557979,3233516071&fm=27&gp=0.jpg";
        });
        return new ListImageItem(urls, "多图片浏览");
      } else {
        return new MessageItem("Sender $i", "Message body $i");
      }
    }),
  ));
}

class MyApp extends StatelessWidget {
  final List items;

  MyApp({Key key, @required this.items}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final title = 'Flutter List';

    return new MaterialApp(
      title: title,
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text(title),
          backgroundColor: Colors.green,
        ),
        body: new ListView.builder(
          // Let the ListView know how many items it needs to build
          itemCount: items.length,
          // Provide a builder function. This is where the magic happens! We'll
          // convert each item into a Widget based on the type of item it is.
          itemBuilder: (context, index) {
            final item = items[index];
            if (item is HeadingItem) {
              return getTitleItem(item, context);
            } else if (item is MessageItem) {
              return new ListTile(
                title: new Text(item.sender),
                subtitle: new Text(item.body),
              );
            } else if (item is ImageItem) {
              return getImageItem(item, context);
            } else if (item is ListImageItem) {
              return new Container(
                  height: 220,
                  width: double.infinity,
                  padding: EdgeInsets.fromLTRB(10, 10, 0, 10),
                  child: ListView.builder(
                    itemBuilder: (context, index) {
                      return getListItem(context, item, index);
                    },
                    itemCount: item.urls.length,
                    scrollDirection: Axis.horizontal,
                  ));
            }
          },
        ),
      ),
    );
  }

  ListTile getTitleItem(HeadingItem item, BuildContext context) {
    return new ListTile(
        title: new GestureDetector(
      child: new GradientText(
        item.heading,
        textAlign: TextAlign.left,
        gradient: LinearGradient(colors: [Colors.redAccent, Colors.green]),
        style: TextStyle(
          fontSize: 30.0,
        ),
      ),
      onTap: () {
        Navigator.push(
          context,
          new MaterialPageRoute(builder: (context) => new HomePage()),
        );
      },
    ));
  }

  Widget getImageItem(ImageItem item, BuildContext context) {
    return new Container(
      height: 100,
      margin: EdgeInsets.only(left: 10),
      child: Stack(
        children: [
          new GestureDetector(
            /*child: ClipRRect(
              borderRadius: BorderRadius.circular(10),
              child: new CachedNetworkImage(
                imageUrl: item.url,
                height: 100,
              ),
            ),*/
            child: new ClipOval(
              child: new CachedNetworkImage(
                imageUrl: item.url,
                height: 100,
              ),
            ),
            onTap: () {
              Navigator.push(
                  context,
                  new MaterialPageRoute(
                      builder: (context) => new PhoteViewPage(item.url)));
            },
          ),
        ],
      ),
    );
  }

  Container getListItem(BuildContext context, ListImageItem item, int index) {
    return new Container(
        width: 220,
        height: 220,
        padding: new EdgeInsets.only(right: 10),
        child: GestureDetector(
          onTap: () {
            Navigator.push(
                context,
                new MaterialPageRoute(
                    builder: (context) => new MutiPhotePage(item.urls, index)));
          },
          child: ClipRRect(
            borderRadius: BorderRadius.circular(6),
            child: new CachedNetworkImage(
              imageUrl: item.urls[index],
              fit: BoxFit.cover,
              placeholder: (context, url) => new CircularProgressIndicator(),
              errorWidget: (context, url, error) => new Icon(Icons.error),
            ),
          ),
        ));
  }
}

// The base class for the different types of items the List can contain
abstract class ListItem {}

// A ListItem that contains data to display a heading
class HeadingItem implements ListItem {
  final String heading;

  HeadingItem(this.heading);
}

// A ListItem that contains data to display a message
class MessageItem implements ListItem {
  final String sender;
  final String body;

  MessageItem(this.sender, this.body);
}

// A ListItem that contains data to display a message
class ImageItem implements ListItem {
  final String url;
  final String title;

  ImageItem(this.url, this.title);
}

// A ListItem that contains data to display a message
class ListImageItem implements ListItem {
  final List urls;
  final String title;

  ListImageItem(this.urls, this.title);
}

六、Demo直接贴代码(图片浏览放大)

  • 首先在pubspec.yaml引用phote_view 和网络图片加载库


    image.png
  #https://github.com/renefloor/flutter_cached_network_image
  cached_network_image: ^0.7.0

  #https://github.com/renancaraujo/photo_view
  photo_view: ^0.2.2
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
import 'package:cached_network_image/cached_network_image.dart';
// ignore: must_be_immutable
class PhoteViewPage extends StatefulWidget {

  String url;


  PhoteViewPage(this.url);

  @override
  PhoteViewPageState createState() => new PhoteViewPageState(this.url);
}

class PhoteViewPageState extends State {

  String url;


  PhoteViewPageState(this.url);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('图片浏览'),
        backgroundColor: Colors.green,
      ),
      body: new Container(
        color: Colors.white,
        child: PhotoView(imageProvider: new CachedNetworkImageProvider(url),
           backgroundDecoration: new BoxDecoration(color: Colors.white),
        ),
      ),
    );
  }
  @override
  void initState() {
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  void didUpdateWidget(PhoteViewPage oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }
}

七、多图片浏览

使用TabbarView 与PhoteView 实现多图片的浏览

import 'package:flutter/material.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:photo_view/photo_view.dart';

class MutiPhotePage extends StatefulWidget {
  List urls;

  int postion;

  MutiPhotePage(this.urls, this.postion);

  @override
  MutiPhotePageState createState() => new MutiPhotePageState(urls, postion);
}

class MutiPhotePageState extends State with SingleTickerProviderStateMixin{
  List urls;

  int postion;

  TabController tabController;

  MutiPhotePageState(this.urls, this.postion);

  List getTabView() {
    return urls.map((url) {
      return new Container(
        child: PhotoView(
          imageProvider: new CachedNetworkImageProvider(url),
          backgroundDecoration: new BoxDecoration(color: Colors.white),
        ),
      );
    }).toList(growable: true);
  }

  @override
  void initState() {
    super.initState();
    this.tabController =
        new TabController(length: urls.length, initialIndex: postion,vsync: this);
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  void didUpdateWidget(MutiPhotePage oldWidget) {
    super.didUpdateWidget(oldWidget);
  }

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("查看多张图片"),
        backgroundColor: Colors.green,
      ),
      body: new Container(
        child: new TabBarView(
          children: getTabView(),
          controller: tabController,
        ),
      ),
    );
  }
}

你可能感兴趣的:(Android开发 学习Flutter 入门)