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<ListItem>.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<String> urls = new List<String>.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<ListItem> 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: <Widget>[
          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<String> 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<PhoteViewPage> {

  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<String> urls;

  int postion;

  MutiPhotePage(this.urls, this.postion);

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

class MutiPhotePageState extends State<MutiPhotePage> with SingleTickerProviderStateMixin{
  List<String> urls;

  int postion;

  TabController tabController;

  MutiPhotePageState(this.urls, this.postion);

  List<Widget> 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,
        ),
      ),
    );
  }
}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 表单 一、 表单的基本应用 (一) 表单典型的应用场景 1. 登录、注册 2. 网上订单 3. 调查问卷 4. 网...
    拾起_518阅读 1,796评论 0 0
  • 第一次打比较正式的比赛,也看到了自己有多么菜。 Web easy_parse 考察prase_str()变量覆盖漏...
    NoelleMu阅读 5,401评论 0 0
  • 抖音的产品分析 概述 本文尝试通过结合整个文娱和短视频行业的发展,将抖音产品本身的结构和特色置于行业环境中,分析抖...
    青尼罗河阅读 5,161评论 0 1
  • 距离上次晕倒已经好久了。晕倒的原因也是很有特色,比如食物中毒,比如泡温泉,再比如跑步。 想来自己也是一直在强壮边缘...
    姑娘玉秋阅读 1,886评论 2 0

友情链接更多精彩内容