移动互联技术与实践-实验一

实验一 环境搭建与界面设计

一、实验目的

1、掌握移动 APP 客户端开发环境搭建。

2、掌握 HelloWorld 工程项目的创建。

3、了解工程项目文件组织基本组织结构。

4、掌握移动应用开发过程中基本界面布局和基本控件使用。

5、利用基本布局和控件完成移动应用中常见功能。

二、知识要点

1、布局
Flutter 布局机制的核心就是 widget。在 Flutter 中,几乎所有东西都是一个widget - 甚至布局模型都是 widget。您在 Flutter 应用中看到的图像、图标和文本都是 widget。 甚至不可见的东西也是 widget,例如行(row)、列(column)以及用来排列、约束和对齐这些可见 widget 的网格(grid)。

2、基本控件
a) Scaffold:脚手架,布局的基本容器,内部可以使用 material 的控件。

b) Container、SizeBox:容器、盒子,一般用于对内部控件的约束。

c) Column、Row:列、行,用于实现竖直、水平布局。

d) Text:文本展示。

e) Image:图片展示。

f) TextField:文本输入。

g) FlatButton、RaisedButton:按钮。

h) Padding、Align、Center:单一功能简单控件,分别是填充、对齐方式、居中。

i) GridView:网格控件的一种,用于实现网格布局。

j) LinearProgressIndicator:条形进度条。

三、实验内容

1、课堂实验
参考效果图实现百度云盘的个人账户登录界面,具体要求和实现如下:

a) 百度 logo。

b) “欢迎登录百度账号”文本。

c) “登录”按钮,背景色为RGB(200,200,200),”登录”为 Colors.black38。

d) 账号密码未输入情况下,“登录”按钮不可点击。

e) 用户名和密码输入框,“密码是否可见按钮”(小眼睛)支持点击。

f) 输入账号密码后,登陆按钮背景变为 RGB(75,207,250),同时“登录”变为白色且可点击。

g) 点击登录按钮,校验与已设定密码是否相符,并弹出密码正确与否提示。

2、课后练习
参考效果图实现百度云盘个人中心页面的基本界面,具体要求和实现如下:

a) 在课堂实验的基础上,新建界面 personal_center,实现布局。

b) 要求登录成功后跳转至个人中心界面(要求使Navigator.push)。

c) 参考效果添加圆头头像。

d) 添加个人昵称。

e) 展示已用容量/可用容量文本。

f) 展示容量进度条(要求使用LinearProgressIndicator)。

g) 使用网格视图实现功能区,包括 8 个图标及文字(要求使用GridView)。

四、实验结果
1)、课堂实验

1、代码

import 'package:flutter/material.dart';
import 'package:flutter_app02/Tabs.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("LoginPage"),
      ),
      body: HomeContent(),
    );
  }
}

class HomeContent extends StatefulWidget {
  @override
  _HomeContentState createState() => _HomeContentState();
}

class _HomeContentState extends State<HomeContent> {

  String _username;
  String _password;
  //模拟数据库已经存在的账户和密码
  String db_username = "zhangsan";
  String db_password = "123456";

  bool _enable = false;
  bool _obscureText = true;

  void _click_event(){
      if(this._username == this.db_username && this._password == this.db_password)
      {
        print("登录成功");
        showDialog(
          context: this.context,
          builder: (context){
            return AlertDialog(
              title: Text('登录提醒'),
              content: Text('登录账户:$_username \n'+'登录密码:$_password'),
              actions: <Widget>[
                FlatButton(
                  color: Colors.blue,
                  child: Text('确 认'),
                  onPressed: (){
                    Navigator.pop(context);
                    Navigator.push(context, MaterialPageRoute(
                      builder: (context)=>Tabs(),
                    ));
                  },
                ),
                FlatButton(
                  color: Colors.blue,
                  child: Text('取 消'),
                  onPressed: (){
                    Navigator.pop(context);
                  },
                )
              ],
            );
          }
        );
      }
      else
        print("用户名或密码错误");
  }
  // 图片
  Widget _imageWidget(){
    return Container(
      height: 100.0,
      child: Image.network("https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png"),
    );
  }
  // 文字
  Widget _textWidget(){
    return Text(
      "欢迎登录百度账户",
      style: TextStyle(
        fontSize: 20,
      ),
    );
  }
  // username textField
  Widget _usernameTextField(){
    return TextField(
      decoration: InputDecoration(
          hintText: "请输入手机号/用户名/邮箱",
          border: OutlineInputBorder(),
          icon: Icon(Icons.supervised_user_circle)
      ),
      onChanged: (value){
        this._username = value;
        setState(() {
          if((this._username != "" && this._username != null) && (this._password != "" && this._password != null))
            this._enable = true;
          else
            this._enable = false;
        });
      },
    );
  }

  Widget _passwordTextField(){
    return TextField(
      decoration: InputDecoration(
          hintText: "请输入登录密码",
          fillColor: Color.fromARGB(255, 240, 240, 240),
          border: OutlineInputBorder(),
          icon: Icon(Icons.security),
          suffixIcon: IconButton(
            onPressed: (){
              setState(() {
                this._obscureText = !this._obscureText;
              });
            },
            icon: Image.asset(
              this._obscureText ? "assets/hide.png" : "assets/open.png",
              width: 20.0,
              height: 20.0,
            ),
            splashColor: Colors.transparent,
            highlightColor: Colors.transparent,
          )
      ),
      obscureText: this._obscureText,
      onChanged: (value){
        this._password = value;
        setState(() {
          if((this._username != "" && this._username != null) && (this._password != "" && this._password != null))
            this._enable = true;
          else
            this._enable = false;
        });
      },

    );
  }
  //登录按钮
  Widget _loginButton(){
    return Row(
      children: [
        Expanded(
          child: RaisedButton(
            child: Text("登录"),
            color: Colors.blue,
            textColor: Colors.white,
            onPressed: this._enable ? _click_event : null,
          ),
        )
      ],
    );
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(20),
      child: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            _imageWidget(),
            _textWidget(),
            SizedBox(height: 10.0,),
            _usernameTextField(),
            SizedBox(height: 10.0,),
            _passwordTextField(),
            SizedBox(),
            _loginButton()
          ],
        ),
      ),
    );
  }
}

2、结果截图

在这里插入图片描述

2)、课后练习

1、代码

import 'package:flutter/material.dart';

class PersonalCenterPage extends StatefulWidget {
  @override
  _PersonalCenterPageState createState() => _PersonalCenterPageState();
}

class _PersonalCenterPageState extends State<PersonalCenterPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: PersonalCenterContent(),
    );
  }
}

class PersonalCenterContent extends StatefulWidget {
  @override
  _PersonalCenterContentState createState() => _PersonalCenterContentState();
}

class _PersonalCenterContentState extends State<PersonalCenterContent> {

  List listData = [
    {"imgUrl":"assets/file_add_btn_scan.png","text":"扫一扫"},
    {"imgUrl":"assets/file_add_btn_photo.png","text":"上传图片"},
    {"imgUrl":"assets/file_add_btn_video.png","text":"上传视频"},
    {"imgUrl":"assets/file_add_btn_note.png","text":"新建笔记"},
    {"imgUrl":"assets/file_add_btn_file.png","text":"上传文档"},
    {"imgUrl":"assets/file_add_btn_music.png","text":"上传音乐"},
    {"imgUrl":"assets/file_add_btn_folder.png","text":"新建文件夹"},
    {"imgUrl":"assets/file_add_btn_other.png","text":"上传其他文件"},
  ];// 数据列表

  // 获取列表数据
  List<Widget> _getListData(){

    var list  = listData.map((value){
      return GridContent(value["imgUrl"],value["text"]);
    });

    return list.toList();
  }
  // 个人中心头部
  Widget _personalHeader(){
    return Row(
      children: [
        Container(
          child: ClipOval(
            child: Image.asset("assets/swan_app_user_portrait_pressed.png"),
          ),
          width: 80.0,
          height: 80.0,
        ),
        Expanded(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              Row(
                children: [
                  Text("移动开发",
                    style: TextStyle(
                        fontSize: 20.0,
                        color: Colors.grey
                    ),
                  ),
                  Container(
                    child: Image.asset("assets/home_identity_common.png"),
                    width: 25.0,
                    height: 25.0,
                  )
                ],
              ),
              Container(
                width: 300.0,
                child: LinearProgressIndicator(
                    backgroundColor: Colors.grey,
                    value: 0.2,
                    valueColor: new AlwaysStoppedAnimation<Color>(Colors.blue)
                ),
              ),
              Container(
                alignment: Alignment(-1,0),
                child: Text(
                  "668GB/3220GB",
                  style: TextStyle(
                      fontSize: 12.0,
                      color: Colors.grey
                  ),
                ),
              )
            ],
          ),
        )
      ],
    );
  }
  // 个人中心网格布局
  Widget _gridViewList(){
    return Container(
      child: GridView.count(
        crossAxisSpacing: 10,// 水平 子Widget 距离
        mainAxisSpacing: 10,// 垂直 子Widget 距离
        padding: EdgeInsets.all(10),
        crossAxisCount: 4,// 控制一行widget的数量

        childAspectRatio: 0.7,// 宽度和高度的比例

        children: this._getListData(),

      ),
      height: 400.0,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10),
      child: Column(
        children: [
          SizedBox(height: 15.0,),
          _personalHeader(),
          SizedBox(height: 30.0,),
          _gridViewList()
        ],
      ),
    );
  }
}

// 自定义网格组件
class GridContent extends StatelessWidget {

  String imgUrl;
  String text;

  GridContent(this.imgUrl,this.text);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 240,
      height: 240,
      padding: EdgeInsets.all(10),
      child: Column(
        children: [
          Container(
            child: Image.asset(this.imgUrl),
          ),
          // SizedBox(height: 20.0,),
          Expanded(
            flex: 1,
            child: Text(
              this.text,
              style: TextStyle(
                fontSize: 12.0
              ),
            ),
          )

        ],
      ),
    );
  }
}

2、结果截图

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值