用flutter很簡單的實現一個時光軸樣式【flutter20個例項之五】

蔥頭來過發表於2021-08-11

一、老套路,先看樣式

圖1是我業務中的樣式,圖2是下方原始碼展示樣式(複製可直接執行,無額外元件引入)

二、講解

1.結構拆分

首先我們來拆分下結構,無非就兩個主要部分,一個是左邊豎線和圓形圖,一個是右邊的內容

分析下大概用到以下元件:

Stack :重疊元件

VerticalDivider:豎線

BoxDecoration:圓圈

Column,Row,Text,Padding等
複製程式碼

2.先實現下整體的樣式佈局

  Widget getItem() {
    return Container(
      height: 70,
      child: Row(
        children: <Widget>[
          Container(
            height: 70,
            width: 20,
            child: leftItem(),
          ),
          Padding(
            padding: const EdgeInsets.only(left: 20),
            child: rightItem(),
          ),
        ],
      ),
    );
  }
複製程式碼

說明:根部的container設定高度,是因為豎線的包裹元件需要一個指定高度,所以我們列表的每個list需要設定高度

設定一個Row,左邊是圖形,右邊是內容

3.左邊的stack圖形樣式

    return Stack(
      children: <Widget>[
        Padding(
          padding: EdgeInsets.only(left: 1),
          child: VerticalDivider(
            thickness: 2,
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: 0, top: 20),
          child: Container(
            width: 20,
            height: 20,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Colors.orange,
            ),
          ),
        ),
      ],
    );
複製程式碼

通過VerticalDivider的屬性設定一個屬性,寬度設定為2,當前還有其他的一些屬性,可以翻看文件

需要注意的是:

【1】stack的父元件寬度設定為20,高度為70,那麼豎線出來的效果高度也為70,橫向位置在中間

【2】為了豎線在圓圈的中心穿過,圓圈寬高需要都設定為20,距離頂部在25,圓圈會位於豎線中心位置

這些數字可以改,但是要保持之前關係,可以進行除錯檢視效果

4.右邊的內容相對比較簡單

主要是一些column和row元件來設定佈局了

裡面涉及的一些元件的含義和屬性,可以翻看文件熟悉

三、原始碼(可直接執行除錯)

import 'package:flutter/material.dart';

class MyTest extends StatefulWidget {
  @override
  _MyTestState createState() => _MyTestState();
}

class _MyTestState extends State<MyTest> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          leading: new IconButton(
            icon: new Icon(Icons.arrow_back),
          ),
          centerTitle: true,
          title: Text(
            '我的時光軸',
          ),
          actions: <Widget>[
            IconButton(
              icon: Icon(Icons.edit),
            ),
          ],
        ),
        body: Padding(
          padding: const EdgeInsets.all(10.0),
          child: ListView(
            children: <Widget>[
              getItem(),
              getItem(),
              getItem(),
            ],
          ),
        ));
  }

  Widget getItem() {
    return Container(
      height: 70,
      child: Row(
        children: <Widget>[
          Container(
            height: 70,
            width: 20,
            child: leftItem(),
          ),
          Padding(
            padding: const EdgeInsets.only(left: 20),
            child: rightItem(),
          ),
        ],
      ),
    );
  }

  Widget leftItem() {
    return Stack(
      children: <Widget>[
        Padding(
          padding: EdgeInsets.only(left: 1),
          child: VerticalDivider(
            thickness: 2,
          ),
        ),
        Padding(
          padding: EdgeInsets.only(left: 0, top: 25),
          child: Container(
            width: 20,
            height: 20,
            decoration: BoxDecoration(
              shape: BoxShape.circle,
              color: Colors.orange,
            ),
          ),
        ),
      ],
    );
  }

  Widget rightItem() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Container(
          child: Row(
            children: <Widget>[
              Text('我是一個標題'),
              Padding(
                padding: const EdgeInsets.only(left: 20),
                child: Text(
                  '2020-08-07 18:00:00',
                  style: TextStyle(color: Colors.black38),
                ),
              ),
            ],
          ),
        ),
        Text(
          '這裡放一些描述資訊',
          style: TextStyle(color: Colors.black54, fontSize: 12),
        ),
        Container(
            width: 300,
            child: Divider(
              height: 24,
            )),
      ],
    );
  }
}
複製程式碼

持續更新中......

相關文章