Flutter入门篇(二)- 第一个APP

在上一篇文章中以简单的方式对Flutter自己提供的演示进行了一个简单的分析,当然那是远远不够。本来打算为大家带来官网上的无限下拉刷新的案例,但是发现这里的有些东西实在是太超前了,作为Flutter入门篇,当然不能这么随意,以为了让大家都能够学有所得,所以今天给大家带来了自己手撸的一个登录。

简单分析布局

我们都知道,一个简单的登录需要至少需要3步:

  • 输入账号
  • 输入密码
  • 点击登录

那么我们的布局也就至少需要3个widget,为什么说至少呢?因为往往布局使用的widget都是大于操作步骤的。这里跟大家分享我的布局大概有这么几个:

  • 整个外层框框,就是那个淡红色的渐变底色,是一个容器widget,可以包裹里面的所有内容。
  • 在这里面是一个纵向的布局widget,让所有的内容成纵向排列。
  • 里面输入手机号和输入密码那里都是=容器,可以包裹输入框。为什么要使用这个容器呢,直接使用输入widget不好吗?这里容许我先买个关子~~
  • 接下来就是一个按钮
  • 最后就是显示文字的布局

Scaffold

为什么要讲解这个呢?这是因为它是实现了Mataril Design的一种简单的“脚手架”,有些也叫“支架”,通过这个翻译也就知道了,其实它就是向我们提供了简单的框架,我们直接使用它就行了。那么问题来了,我们可不可以不使用它呢?当然是可以的,但是不建议这样做,因为我们后面需要使用的很多widget(比如TextField)必须要在它的支持下才能运行,不然就会报错了。

class Scaffold extends StatefulWidget {
  /// Creates a visual scaffold for material design widgets.
  const Scaffold({
    Key key,
    this.appBar, //横向水平布局,通常显示在顶部(*)
    this.body, // 内容(*)
    this.floatingActionButton, //悬浮按钮,就是上图右下角按钮(*)
    this.floatingActionButtonLocation, //悬浮按钮位置
    //悬浮按钮在[floatingActionButtonLocation]出现/消失动画
    this.floatingActionButtonAnimator,
    //在底部呈现一组button,显示于[bottomNavigationBar]之上,[body]之下
    this.persistentFooterButtons,
    //一个垂直面板,显示于左侧,初始处于隐藏状态(*)
    this.drawer,
    this.endDrawer,
    //出现于底部的一系列水平按钮(*)
    this.bottomNavigationBar,
    //底部持久化提示框
    this.bottomSheet,
    //内容背景颜色
    this.backgroundColor,
    //弃用,使用[resizeToAvoidBottomInset]
    this.resizeToAvoidBottomPadding,
    //重新计算布局空间大小
    this.resizeToAvoidBottomInset,
    //是否显示到底部,默认为true将显示到顶部状态栏
    this.primary = true,
    //
    this.drawerDragStartBehavior = DragStartBehavior.down,
  }) : assert(primary != null),
       assert(drawerDragStartBehavior != null),
       super(key: key);

从这里面,我们可以看出Scaffold提供了很多的方式方法,去实现Mataril Design的布局:

AppBar

一般就用于Scaffold.appBar,是一个置于屏幕顶部的横向布局,为什么是横向呢?可以如下中看出:

我在它其中的anctions属性中设置了多个widget,然后就向这样后面那三就一溜的按顺序排好了。

 AppBar(
    title: Text(‘Sample Code‘),
    leading: IconButton(
        icon: Icon(Icons.view_quilt),
        tooltip: ‘Air it‘,
        onPressed: () {},
    ),
    bottom: TabBar(tabs: tabs.map((e) => Tab(text: e)).toList(),controller: _tabController),
    actions: <Widget>[
        IconButton(
        icon: Icon(Icons.playlist_play),
        tooltip: ‘Air it‘,
        onPressed: () {},
        ),
        IconButton(
        icon: Icon(Icons.playlist_add),
        tooltip: ‘Restitch it‘,
        onPressed: () {},
        ),
        IconButton(
        icon: Icon(Icons.playlist_add_check),
        tooltip: ‘Repair it‘,
        onPressed: () {},
        )
    ],
)

对于上述中leading需要说明一下,一般我们用它来显示一个按钮去关闭当前页面或者打开一个drawer。有兴趣的可以去试试~~

AppBar众多的属性中,还有一个是我们比较常用的,那就是bottom,这个显示于工具栏的下方,注意不是屏幕底部哦!一般使用TabBar来实现一个页面包含中多个不同页面的切换。

当然还有其他一些方式方法,这里就不多占用篇幅了,就简单聊聊:

  • title就是标题
  • drawer抽屉,一般左侧打开,默认初始隐藏
  • centerTitle 是否标题居中

    如果想看完整的实现方式,就跟我来吧

    BottomNavigationBar

这个属性也是相当重要的,如果我们想要实现多个,不同页面的切换,就可以使用这个。咦?这个不是说过了么?



BottomNavigationBar与AppBar里面的TabBar是不同的,一个是用来显示于顶部,一个用来显示与底部



在我们国内的应用中很少向这样出现可以浮动选择项,所以如果想让你的App不进行浮动的话,可以使用里面的一个type属性。

type: BottomNavigationBarType.fixed,

BottomNavigationBarType有两值,就是fixed,还有一个就是shifting,默认是shifting。这样设置之后仍然存在一个问题:就是选中的按钮的字体仍然会比未选中的大一点,有兴趣的可以自己去验证一下。


那么这个问题改怎么办呢?很遗憾,在最新稳定版(Flutter Stable 1.2.1)SDK中并没有处理这个问题的方式方法。如果想要解决这个问题的话,更换Flutter SDK到最新的开发版本(Flutter Dev 1.3.8),就可以使用它的属性去解决这个问题。

selectedItemColor: colorRegular, //选中颜色
unselectedItemColor: colorBlack,//未选择颜色
selectedFontSize: 12,//选中字体大小
unselectedFontSize: 12,//未选中字体大小

FloatingActionButton

个人觉得这个FloatingActionButton还是需要说明一下的,毕竟用的时候还是比较多的。FloatingActionButton是一个浮动按钮,也就是上面那个带“+”的按钮,这个可以用来添加,分享,或者是导航。可以与Scaffold中两个属性配合使用

  • FloatingActionButtonLocation
  • FloatingActionButtonAnimator

FloatingActionButtonLocation属性可以移动浮动按钮的位置,有如下几个位置可以移动:

FloatingActionButtonLocation.endDocked //右侧bottomNagivationBar遮盖
FloatingActionButtonLocation.centerDocked //居中bottomNagivationBar上遮盖
FloatingActionButtonLocation.endFloat //bottomNagivationBar上方右侧显示
FloatingActionButtonLocation.centerFloat //bottomNagivationBar上方居中显示

自己可以试一试,这里就不一一演示,只演示一下这个centerDocked

FloatingActionButtonAnimator就是FloatingActionButton在出现位置FloatingActionButtonLocation的动画效果~~

需要注意以下几点:

  • 如果一个页面有多个FloatingActionButtonLocation,那么就需要让每一个浮动按钮都有自己且唯一的heroTag
  • 如果onPressed返回了null,那么它将不会对你的触摸进行任何反应,不推荐这样去展示一个无任何响应的浮动按钮。

SnackBar

经常在我们的应用中会使用到信息提示,那么我们就可以使用showSnackBar的方式去显示一个简短的提示,默认显示4s。

class SnackTest extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text(‘Demo‘)
      ),
      body: Center(
        child: RaisedButton(
          child: Text(‘SHOW A SNACKBAR‘),
          onPressed: () {
            Scaffold.of(context).showSnackBar(SnackBar(
              content: Text(‘Hello!‘),
            ));
          },
        ),
      )
    );
  }
}

一般我们会向如上方式处理,但是可能会抛出一个Scaffold.of() called with a context that does not contain a Scaffold.的异常,也不会显示出snackBar
这是因为,Scaffold.of()所需的context是Scaffold的,并不是Scaffold上方的build(BuildContext context)中的,这两个并不是一个。

正确的方式是,创建自己的context:

class SnackTest extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text(‘Demo‘)
      ),
      body: Builder(
        // Create an inner BuildContext so that the onPressed methods
        // can refer to the Scaffold with Scaffold.of().
        builder: (BuildContext context) {
          return Center(
            child: RaisedButton(
              child: Text(‘SHOW A SNACKBAR‘),
              onPressed: () {
                Scaffold.of(context).showSnackBar(SnackBar(
                  content: Text(‘Hello!‘),
                ));
              },
            ),
          );
        },
      ),
    );
  }
}

当然还可以使用GlobalKey的方式:

class ScaffoldTestState extends State<ScaffoldTest> {
  final _scaffoldKey = GlobalKey<ScaffoldState>();

  void showSnackBar() {
    _scaffoldKey.currentState
        .showSnackBar(new SnackBar(content: Text("SnackBar is Showing!")));
  }

  return new Scaffold(
        key: _scaffoldKey,
        body: Center(
        child: RaisedButton(
          child: Text(‘SHOW A SNACKBAR‘),
          onPressed: () {
            showSnackBar(),
            ));
          },
        ),
      )
    }
}

还有另一种也可以作为提示,就是bottomSheet:

这个与snackBar的区别就是,虽然弹出了提示,但是不会自动消失,需要手动下拉才会消失。

class SnackTest extends StatelessWidget{

  void showBottomSheet(BuildContext context) {
    Scaffold.of(context).showBottomSheet((BuildContext context) {
      return new Container(
        constraints: BoxConstraints.expand(height: 100),
        color: Color(0xFFFF786E),
        alignment: Alignment.center,
        child: new Text(
          "BottomSheet is Showing!",
          style: TextStyle(color: Color(0xFFFFFFFF)),
        ),
      );
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
          title: Text(‘Demo‘)
      ),
      body: Builder(
        // Create an inner BuildContext so that the onPressed methods
        // can refer to the Scaffold with Scaffold.of().
        builder: (BuildContext context) {
          return Center(
            child: RaisedButton(
              child: Text(‘SHOW A SNACKBAR‘),
              onPressed: () {
                showBottomSheet(context);
              },
            ),
          );
        },
      ),
    );
  }
}

实现登录

前面讲了那么多都是为我们接下来的演示做准备的,那先来看看登录代码:

class LoginPageState extends State<LoginPage> {
  Color colorRegular = Color(0xFFFF786E);
  Color colorLight = Color(0xFFFF978F);
  Color colorInput = Color(0x40FFFFFF);
  Color colorWhite = Colors.white;

  TextStyle defaultTextStyle =
  TextStyle(color: Colors.white, fontWeight: FontWeight.bold, fontSize: 16);

  BorderRadius radius = BorderRadius.all(Radius.circular(21));

  void login() {

  }

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      body: Container(
        constraints: BoxConstraints.expand(),
        decoration: BoxDecoration(
            gradient: LinearGradient(
                colors: [colorLight, colorRegular],
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter)),
        child: Column(
          children: <Widget>[
            Container (
              margin: EdgeInsets.only(top: 110, bottom: 39, left: 24, right: 24),
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.all(Radius.circular(21)), color: colorInput),
              child: TextField(
                decoration: InputDecoration(
                    contentPadding: EdgeInsets.symmetric(horizontal: 15,vertical: 9),
                    border: InputBorder.none,
                    hintText: "输入手机号",
                    hintStyle: TextStyle(color: Colors.white, fontSize: 16),
                    labelStyle: TextStyle(color: Colors.black, fontSize: 16)),
                maxLines: 1,
                cursorColor: colorRegular,
                keyboardType: TextInputType.phone,
              ),
            ),
            Container(
              margin: EdgeInsets.only(bottom: 58, left: 24, right: 24),
              decoration: BoxDecoration(
                  borderRadius: radius,
                  color: colorInput),
              child: TextField(
                decoration: InputDecoration(
                    contentPadding: EdgeInsets.symmetric(horizontal: 15,vertical: 9),
                    border: InputBorder.none,
                    hintText: "输入密码",
                    hintStyle: TextStyle(color: Colors.white, fontSize: 16),
                    labelStyle: TextStyle(color: Colors.black, fontSize: 16)),
                maxLines: 1,
                cursorColor: colorRegular,
                keyboardType: TextInputType.number,
                obscureText: true,
              ),
            ),
            Container(
              height: 42, width: 312,
              margin: EdgeInsets.only(left: 24, right: 24),
              decoration: BoxDecoration (
                  borderRadius: radius,
                  color: colorWhite),
              child: RaisedButton(onPressed: login,
                  elevation: 1,
                  highlightElevation: 1,
                  textColor: colorRegular,
                  shape: RoundedRectangleBorder(
                      borderRadius: radius
                  ),
                  child: new Text("立即登录", style: TextStyle(
                      fontSize: 15,
                      fontWeight: FontWeight.bold),
                  )),
            ),
            Padding(
              padding: EdgeInsets.only(top: 10),
              child: Text(
                "登录/注册即代表您已同意《会员协议》",
                style: TextStyle(color: Colors.white, fontSize: 13),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

在上一章就讲过,如果在整个生命周期中,状态如果改变,那么我们就是用StatefulWidget来呈现,并且StatefulWidget的实现需要两步:一个是需要创建继承StatefulWidget的类;另一个就是创建继承State的类,一般在State中控制整个状态。所以此处就是如此:

class LoginPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => LoginPageState();
}

class LoginPageState extends State<LoginPage> {

  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return new Scaffold(
      body: Container(
      //省略代码
      ...
      )
    );
  }
}

并且当前登录界面是没有工具栏的,所以去掉了AppBar。将所有内容直接写在了body中。可以看到整个登录界面的背景是一个渐变,上面浅一点,下面深一点,所以就需要一个容器去包裹整个内容,并且这个容器可以实现背景颜色的渐变的,所以我选用了Container,因为它是所有容器布局中属性最全面的。

 Container({
    Key key,
    this.alignment,//子布局的排列方式
    this.padding,//内部填充
    Color color,//背景颜色
    Decoration decoration,  //用于装饰容器
    this.foregroundDecoration,//前景装饰
    double width, //容器宽
    double height, //容器高
    BoxConstraints constraints, //约束
    this.margin, //外部填充
    this.transform, //对容器进行变换
    this.child,
  })

提示:如果处于body下的container不论是否设置宽高,它将都会扑满全屏。

那么最外层的渐变我们就是使用BoxDecoration

const BoxDecoration({
    this.color,
    this.image, 图片
    this.border, //边框
    this.borderRadius, //圆角
    this.boxShadow, //阴影
    this.gradient, //渐变
    this.backgroundBlendMode, //背景模式,默认BlendMode.srcOver
    this.shape = BoxShape.rectangle, //形状
  }) : assert(shape != null),
       assert(
         backgroundBlendMode == null || color != null || gradient != null,
         ‘backgroundBlendMode applies to BoxDecoration\‘s background color or ‘
         ‘gradient, but no color or gradient was provided.‘
       );

提示:在对形状的处理中,以下是可以互换的:

  • CircleBorder === BoxShape.circle
  • RoundedRectangleBorder == BoxShape.rectangle

所以从上可以完成我们的渐变:

 decoration: BoxDecoration(
            gradient: LinearGradient(
                colors: [colorLight, colorRegular],
                begin: Alignment.topCenter,
                end: Alignment.bottomCenter)
        )

实现了渐变的过程,那么就是输入框,可以从设计上来说,这些内容都是纵向排列的,所以内容使用了布局Column,用于纵向布局,当然相对的横向布局Row

 Column({
    Key key,
    //主轴排列方式,这里的主轴就是纵向,实际就是纵向的布局方式
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    //Column在主轴(纵向)占有的控件,默认尽可能大
    MainAxisSize mainAxisSize = MainAxisSize.max,
    //交叉轴排列方式,那么就是横向
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    //横向子widget的布局顺序
    TextDirection textDirection,
    //交叉轴的布局对齐方向
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    List<Widget> children = const <Widget>[],
  })

Column中包含了三个Container,前两个中是输入布局TextField,最后一个是RaisedButton。这里回答在文章开始开始的时候提出的问题:为什么要用Container去包裹TextField

  1. 需要实现圆角 (decoration)
  2. 要实现间距 (marin 和 padding)

所有需要使用Container去完成这样的样式装饰。

TextField应该是我们比较常用的widget了:

TextField(
    decoration: InputDecoration(
        contentPadding: EdgeInsets.symmetric(horizontal: 15,vertical: 9),
        border: InputBorder.none,
        hintText: "输入手机号",
        hintStyle: TextStyle(color: Colors.white, fontSize: 16),
        labelStyle: TextStyle(color: Colors.black, fontSize: 16)
    ),
    maxLines: 1,
    cursorColor: colorRegular,
    keyboardType: TextInputType.phone,
),

这里只是使用可decoration,对TextField装饰,比如其中的contentPadding,对内容留白填补。
cursorColor光标颜色,输入类型keyboardType,这里是手机号类型。此外还有很多的属性,这里就不一一赘述,可以自行到官网去查看。

最后被container包裹是的RaisedButton:

RaisedButton(
    onPressed: login,
    elevation: 1,
    highlightElevation: 1,
    textColor: colorRegular,
    shape: RoundedRectangleBorder(
        borderRadius: radius
    ),
    child: new Text("立即登录", style: TextStyle(
        fontSize: 15,
        fontWeight: FontWeight.bold),
))

我也修饰一下

  • 到处登录界面的布局就算完成了,然后运行之后就会出现在文章开头的登录界面,但是当我们点击TextField进行输入的时候,会发现整个布局会被顶上去了,这是为什么呢?。



    答:这是因为Scaffold会填充整个可用空间,当软键盘从Scaffold布局中出现,那么在这种情况下,可用空间变少Scaffold就会重新计算大小,这也就是为什么Scaffold会将我们的布局全部上移的根本原因,为了避免这种情况,可以使用resizeToAvoidBottomInset并将其
    置为false就可以了。


  • 怎么去掉屏幕右上角的debug标签?

答:将MaterialApp中的debugShowCheckedModeBanner置为false

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: ‘Flutter Demo‘,
      theme: ThemeData(
        primaryColor: Color(0xFFFF786E),
        primaryColorLight: Color(0xFFFF978F),
        accentColor: Color(0xFFFFFFFF)
      ),
      home: LoginPage(),
      debugShowCheckedModeBanner: false,
    );
  }
}
  • 怎么让状态栏显示沉浸式,不出现灰蒙蒙的赶脚呢?
 runApp(new MyApp());
  if (Platform.isAndroid) {
    // 以下两行 设置android状态栏为透明的沉浸。
    //写在组件渲染之后,是为了在渲染后进行set赋值,
    //覆盖状态栏,写在渲染之前MaterialApp组件会覆盖掉这个值。
    SystemUiOverlayStyle systemUiOverlayStyle =
    SystemUiOverlayStyle(statusBarColor: Colors.transparent);
    SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
  }

最后给大家推荐一本Flutter书,详细介绍了Flutter的使用方式方法,都提供了演示案例:Flutter实战:

原文地址:https://blog.51cto.com/10687520/2416857

时间: 2024-10-09 06:07:06

Flutter入门篇(二)- 第一个APP的相关文章

8.15_Linux之bash shell脚本编程入门篇(二)以及文件查找和压缩的使用

bash shell脚本编程入门篇(二) read命令的使用 作用: 使用read来把输入值分配给一个或多个shell变量: -p指定要显示的提示 -t TIMEOUT read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量 EX.read -p "Enter a filename:" FILE 条件选择之if的使用 if的作用:选择执行(注意:if语句可嵌套) 单分支 if 判断条件;then 条件为真的分支代码 fi EX.单分支案例 双分支 if

【SSRS】入门篇(二) -- 建立数据源

通过 [SSRS]入门篇(一) -- 创建SSRS项目 这篇,我们建立了一个SSRS项目: 接下来,我们以 AdventureWorks2012 示例数据库,讲下如何建立数据源:(AdventureWorks2012 下载) 1.解决方案资源管理器 ->右键选择共享数据源 ->添加新数据源: 2.在共享数据源属性窗口输入数据库名称:AdventureWorks2012:类型选择:Microsoft SQL Server:点击"编辑"按钮: 3.在连接属性窗口输入服务器名 -

Flutter入门篇(一)

距离Google发布Flutter已经有很长一段时间了,又是一门新的技术,那么我们到底是学呢还是学呢还是学呢?不要问我,我不知道,鬼特么知道我这辈子还要学习多少东西.其实新技术的出现也意味着,老技术会面临淘汰危机,而你将面临着失业危机.用一句话来说:你永远不知道意外和惊喜哪个先来~~ 环境搭建 Flutter的安装就不在这里演示了,可以从下面几个网站上学习安装. Flutter官网 Flutter中文网 Flutter社区 这些网站也通过丰富的Flutter学习资料 Flutter的第一个应用

Flutter入门篇(三)- 如何实现登录动画效果

在上一篇的时候,我们讲解了怎么做一个登录界面,但是之后呢?完全是草草结尾的感觉嘛,这不,接下来就是给大家详细说说,这个登录里面不得鸟的故事.先来看一个登录的过程~~ 分析 可能上面的gif图不是很真切,这上面展示了两个功能: 颜色变换的闪屏页面 动画效果的登录页面 有没有感觉这样的登录好像还不错呢,哈哈哈,接下来就详细分析一下这其中的玄机~~ 路由 一般我们的页面跳转都会涉及到路由,路由就是从一个页面跳转到另一个页面的过程,就比如Android中的Activity或IOS中的ViewContro

Flutter入门篇

环境搭建 Flutter的安装就不在这里演示了,可以从下面几个网站上学习安装. Flutter官网 Flutter中文网 Flutter社区 这些网站也通过丰富的Flutter学习资料 Flutter的第一个应用 在创建一个Flutter应用后,我们可以看到如下的demo代码.(其中注释是个人翻译,如有不正确请谅解) import 'package:flutter/material.dart'; //应用启动 void main() => runApp(MyApp()); class MyApp

GitHub入门之二 参与一个项目编写

接上文:大多数时候我们也需要把别人的代码进行整合和修改,而不是简单的修改,这时就需要对一个项目进行修改. 注意,本系列文章主要说明在github网站上的操作,更多高级操作请使用git控制台 一.fork一个项目 打开一个项目,点击界面右上角的的“fork”,就会在你自己的项目库里创建一个代码的拷贝. 这份代码的主人就是你,你可以对代码进行任何修改.比如在此我fork了一个比特币的项目 https://github.com/bitcoin/bitcoin 进入自己的主页后看到有了一份项目的拷贝,而

无废话MVC入门教程二[第一个小Demo]

mvc技术交流,欢迎加群: 本文目标 1.了解"模型"."视图"."控制器"的创建.调试和使用过程. 本文目录 1.创建模型 2.创建视图 3.创建控制器 4.调试 5.使用模型.视图.控制器 1.创建模型 在文件夹"Models"中创建新类,如下图所示: 1.命名:Model的命名规则一般以Model结尾,如:以业务为主的命名UserModel或以页面为主的命名LoginModel. 2.作用:开发过三层的朋友都知道,我们在

lintcode入门篇二

一. 最大子数组 给定一个整数数组,找到一个具有最大和的子数组,返回其最大和. 样例 样例1: 输入:[−2,2,−3,4,−1,2,1,−5,3] 输出:6 解释:符合要求的子数组为[4,−1,2,1],其最大和为 6. 样例2: 输入:[1,2,3,4] 输出:10 解释:符合要求的子数组为[1,2,3,4],其最大和为 10. 挑战 要求时间复杂度为O(n) 注意事项 子数组最少包含一个数 输入测试数据 (每行一个参数)如何理解测试数据? 第一种解法:O(n)时间复杂度 class Sol

Theano入门神经网络(二) 实现一个XOR门

与非门的图片如下 示意图 详细解释: 1 定义变量的代码,包括了输入.权值.输出等.其中激活函数采用的是sigmod函数 1 # -*- coding: utf-8 -*- 2 __author__ = 'Administrator' 3 4 import theano 5 import theano.tensor as T 6 import random 7 import numpy as np 8 from itertools import izip 9 10 11 #定义网络结构 12 #