第四篇-用Flutter手擼一個抖音國內版,看看有多炫_網頁設計公司

※想知道最厲害的網頁設計公司嚨底家"!

RWD(響應式網頁設計)是透過瀏覽器的解析度來判斷要給使用者看到的樣貌

前言

這次對布局進行優化,主要包含了首頁tabview pageview 以及添加幾個按鈕的操作過程.主要使用到stack層疊布局,tabpview和pageview,tabview兩個頁面,一個關注,一個推薦,左右切換,pageview被包含在tabview裏面.

布局優化

抖音的頂部appbar 是懸浮層疊展示,而flutter的層疊組件是stack, 因此最外面採用stack, 其次中間是tabview,分別是關注和推薦兩個選項卡,關注在沒有登錄的時候會彈出一個提示需要認證登錄的頁面,這裏加了兩個頁面,subscriptionScreen.dart,另外一個是loginScreen.dart

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      //backgroundColor: Colors.transparent,
      body: Stack(
        //fit: StackFit.expand,
        children: <Widget>[
          TabBarView(
            controller: _tabController,
            children: <Widget>[
              Subscription(),
              PageView(
                allowImplicitScrolling: true,
                controller: _pageController,
                children: <Widget>[
                  Trending(),
                ],
                onPageChanged: (int index) {
                  setState(() {
                    currentIndex = index;
                  });
                },
              ),
            ],
          ),
          Column(
            children: [
              AppBar(
                backgroundColor: Colors.transparent,
                elevation: 0,
                centerTitle: true,
                leading: IconButton(
                    icon: Icon(Icons.tv),
                    onPressed: () {
                      print('點擊了直播按鈕');
                    }),
                actions: <Widget>[
                  //導航欄右側菜單
                  IconButton(
                      icon: Icon(Icons.search),
                      onPressed: () {
                        print('點擊了搜索按鈕');
                      }),
                ],
                title: TabBar(
                  indicator: UnderlineTabIndicator(
                      borderSide: BorderSide(width: 2.0, color: Colors.white),
                      insets: EdgeInsets.symmetric(horizontal: 18.0)),
                  labelStyle: TextStyle(fontSize: 18),
                  isScrollable: true,
                  controller: _tabController,
                  tabs: toptabs,
                  onTap: (index) {
                    print(index);
                  },
                ),
              )
            ],
          ),
        ],
      ),
      bottomNavigationBar: bottomItems(),
    );
  }

  

底部彈出提示認證頁面

在 onTap 方法里

Scaffold.of(context).showBottomSheet<void>((BuildContext context) {
          return Login();
        });

BottomSheet 是一個底部滑出的組件

new BottomSheet(
    onClosing: () {},
    builder: (BuildContext context) {
        return new Text('aaa');
    },
),

通常很少直接使用 BottomSheet 而是使用 showModalBottomSheet。直接時候的時候看到的知識 builder 里的內容。

Future<T> showModalBottomSheet <T>({
    @required BuildContext context,
    @required WidgetBuilder builder
});

看一個示例

new MaterialButton(
    color: Colors.blue,
    child: new Text('點我'),
    onPressed: () {
        showModalBottomSheet(
            context: context,
            builder: (BuildContext context) {
                return new Container(
                    height: 300.0,
                    child: new Image.network(this.imgurl),
                );
            },
        ).then((val) {
            print(val);
        });
 

 

 具體詳細介紹參考官網.

 

 

關注頁面

 

 整個頁面布局,左右都有邊距,頂部也有邊距,所有採用Container包含,邊距使用padding: EdgeInsets.only(top: 150.0, left: 65.0, right: 65.0),  背景顏色 color: Color.fromRGBO(14, 15, 26, 1),依次image,另外使用sizebox佔用空間,

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

當全世界的人們隨著網路時代而改變向上時您還停留在『網站美醜不重要』的舊有思維嗎?機會是留給努力改變現況的人們,別再浪費一分一秒可以接觸商機的寶貴時間!

其他的中間層都是居中,所以採用center都是居中,另外登錄按鈕是佔滿屏幕的,所以也採用SizeBox,並且把width:設置為double.infinity,這樣就佔滿屏幕,button採用默認的RaisedButton,在button的onpressed事件調用showBottomSheet

import 'package:flutter/material.dart';
import 'package:flutter_app/Screens/loginScreen.dart';

class Subscription extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _SubscriptionState();
}

class _SubscriptionState extends State<Subscription>
    with TickerProviderStateMixin {
  final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.only(top: 150.0, left: 65.0, right: 65.0),
      color: Color.fromRGBO(14, 15, 26, 1),
      child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Image(image: AssetImage("assets/images/int_1581491273221.png")),
            SizedBox(height: 20),
            Center(
              child: Text(
                '你還沒有登錄',
                style: TextStyle(
                    color: Colors.white,
                    fontSize: 20.0,
                    fontWeight: FontWeight.w400),
              ),
            ),
            SizedBox(height: 10),
            Center(
              child: Text(
                '登錄賬號,查看你關注的精彩內容',
                style: TextStyle(
                    color: Color.fromRGBO(253, 253, 253, 0.6),
                    fontSize: 14.0,
                    fontWeight: FontWeight.w400),
              ),
            ),
            SizedBox(height: 20),
            SizedBox(
              width: double.infinity,
              child: RaisedButton(
                color: Color.fromRGBO(252, 1, 86, 1),
                child: Text(
                  '登錄',
                  style: TextStyle(color: Colors.white),
                ),
                onPressed: () {
                  Scaffold.of(context)
                      .showBottomSheet<void>((BuildContext context) {
                    return Login();
                  });
                },
              ),
            ),
          ]),
    );
  }
}

 

登錄頁面

布局如下圖:

 

 

這個頁面整體布局頂部,左右都有邊距,因此使用Container比較合適,設置背景顏色為color: Colors.white, 邊距設置為padding:EdgeInsets.only(top: 25.0, left: 25.0, right: 25.0, bottom: 50.0),整體布局採用Column,因為是上下布局,因此Column 設置

crossAxisAlignment: CrossAxisAlignment.start,頂部的布局是左邊一個clear圖標按鈕,右邊一個幫助按鈕,所以使用
Row布局,並且設置Row的mainAxisAlignment: MainAxisAlignment.spaceBetween,這樣就左右布局了,其他依次採用SizeBox佔位, 中間則採用Center來展示文字控件,底部的登錄部分因為包含標籤 超鏈接,所有採用RichText比較合適,包含TextSpan即可.

全部代碼如下:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

class Login extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => _LoginState();
}

class _LoginState extends State<Login> {
  TapGestureRecognizer _myTapGestureRecognizer;
  @override
  void initState() {
    super.initState();
    _myTapGestureRecognizer = TapGestureRecognizer()
      ..onTap = () {
        launch('https://open.douyin.com/platform');
      };
  }

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

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      padding:
          EdgeInsets.only(top: 25.0, left: 25.0, right: 25.0, bottom: 50.0),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              IconButton(
                icon: Icon(Icons.clear),
                onPressed: () {
                  Navigator.pop(context);
                },
                color: Colors.black,
              ),
              Text('幫助', style: TextStyle(color: Colors.black)),
            ],
          ),
          SizedBox(
            height: 150.0,
          ),
          Center(
            child: Text('180****2520',
                style: TextStyle(color: Colors.black, fontSize: 38)),
          ),
          Center(
            child: Text('認證服務由中國電信提供',
                style: TextStyle(
                    color: Color.fromRGBO(53, 53, 53, 1), fontSize: 12)),
          ),
          SizedBox(
            height: 50.0,
          ),
          SizedBox(
            width: double.infinity,
            child: RaisedButton(
              color: Color.fromRGBO(252, 1, 86, 1),
              child: Text(
                '本機號碼一鍵登錄',
                style: TextStyle(color: Colors.white),
              ),
              onPressed: () {
                showBottomSheet(
                    context: context, builder: (context) => Login());
              },
            ),
          ),
          SizedBox(
            height: 2.0,
          ),
          SizedBox(
            width: double.infinity,
            child: OutlineButton(
              color: Color.fromRGBO(252, 1, 86, 1),
              child: Text(
                '其他手機號碼登錄',
                style: TextStyle(color: Colors.black),
              ),
              onPressed: () {
                showBottomSheet(
                    context: context, builder: (context) => Login());
              },
            ),
          ),
          SizedBox(
            height: 5.0,
          ),
          Center(
              child: RichText(
            text: TextSpan(
              children: [
                TextSpan(
                  text: '登錄即表明同意',
                  style: TextStyle(color: Color.fromRGBO(53, 53, 53, 0.8)),
                ),
                TextSpan(text: '  '),
                TextSpan(
                  text: '用戶協議',
                  style: TextStyle(color: Color.fromRGBO(0, 164, 219, 0.8)),
                ),
                TextSpan(text: '  '),
                TextSpan(
                  text: '和',
                  style: TextStyle(color: Color.fromRGBO(53, 53, 53, 0.8)),
                ),
                TextSpan(text: '  '),
                TextSpan(
                  text: '隱私政策',
                  style: TextStyle(color: Color.fromRGBO(0, 164, 219, 0.8)),
                ),
              ],
            ),
          )),
          Center(
              child: RichText(
            text: TextSpan(
              children: [
                TextSpan(
                  text: '以及',
                  style: TextStyle(color: Color.fromRGBO(53, 53, 53, 0.8)),
                ),
                TextSpan(text: '  '),
                TextSpan(
                    text: '《中國電信認證服務條款》',
                    style: TextStyle(color: Color.fromRGBO(0, 164, 219, 0.8)),
                    recognizer: _myTapGestureRecognizer),
              ],
            ),
          )),
          Expanded(
              flex: 1,
              child: Center(
                  heightFactor: 25.0,
                  child: Text('其他方式登錄',
                      style:
                          TextStyle(color: Color.fromRGBO(0, 164, 219, 0.8))))),
        ],
      ),
    );
  }
}

變更記錄

本次變更主要體現在首頁的選項卡設計,需要層疊展示,並且透明的採用appbar显示出頂部的關注、推薦按鈕,另外新增了關注頁,登錄頁,並且把底部按鈕以及右邊的按鈕都加上了觸發時間

 

接下來要完成的雙擊心形按鈕點贊,評論頁面,分享頁面,這些都可以採用showmodalbottomsheet方法打開一個底部抽屜頁面

 

還有底部的首頁刷新,消息頁面,拍短視頻頁面,消息頁面,我的個人信息頁面

 

結語

請繼續關注本博客,其他頁面持續更新完成,源碼地址:https://github.com/WangCharlie/douyin,歡迎fork和star,謝謝!!!

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

透過資料庫的網站架設建置,建立公司的形象或購物系統,並提供最人性化的使用介面,讓使用者能即時接收到相關的資訊