Flutter版仿火幣k線與深度線

flutter_k_chart基本實(shí)現(xiàn)了火幣里面各項(xiàng)指標(biāo)線以及深度線,F(xiàn)lutter目前沒有比較好的開源組件,就自己寫了一個(gè),聲明式ui自定義起來有點(diǎn)怪怪的,但大致與android差不多,先上效果圖


k_chart.2019-09-01 10_19_56.gif

depth.2019-09-01 10_21_31.gif

screenshots.png

使用方式

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<KLineEntity> datas;
  bool showLoading = true;
  MainState _mainState = MainState.MA;
  SecondaryState _secondaryState = SecondaryState.MACD;
  bool isLine = true;
  List<DepthEntity> _bids, _asks;

  @override
  void initState() {
    super.initState();
    getData('1day');
    rootBundle.loadString('assets/depth.json').then((result) {
      final parseJson = json.decode(result);
      Map tick = parseJson['tick'];
      var bids = tick['bids'].map((item) => DepthEntity(item[0], item[1])).toList().cast<DepthEntity>();
      var asks = tick['asks'].map((item) => DepthEntity(item[0], item[1])).toList().cast<DepthEntity>();
      initDepth(bids, asks);
    });
  }

  void initDepth(List<DepthEntity> bids, List<DepthEntity> asks) {
    if (bids == null || asks == null || bids.isEmpty || asks.isEmpty) return;
    _bids = List();
    _asks = List();
    double amount = 0.0;
    bids?.sort((left, right) => left.price.compareTo(right.price));
    //倒序循環(huán) //累加買入委托量
    bids.reversed.forEach((item) {
      amount += item.amount;
      item.amount = amount;
      _bids.insert(0, item);
    });

    amount = 0.0;
    asks?.sort((left, right) => left.price.compareTo(right.price));
    //倒序循環(huán) //累加買入委托量
    asks?.forEach((item) {
      amount += item.amount;
      item.amount = amount;
      _asks.add(item);
    });
    setState(() {});
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Color(0xff17212F),
//      appBar: AppBar(title: Text(widget.title)),
      body: ListView(
        children: <Widget>[
          Stack(children: <Widget>[
            Container(
              height: 450,
              width: double.infinity,
              child: KChartWidget(
                datas,
                isLine: isLine,
                mainState: _mainState,
                secondaryState: _secondaryState,
              ),
            ),
            if (showLoading)
              Container(
                  width: double.infinity,
                  height: 450,
                  alignment: Alignment.center,
                  child: CircularProgressIndicator()),
          ]),
          buildButtons(),
          Container(
            height: 230,
            width: double.infinity,
            child: DepthChart(_bids, _asks),
          )
        ],
      ),
    );
  }

  Widget buildButtons() {
    return Wrap(
      alignment: WrapAlignment.spaceEvenly,
      children: <Widget>[
        button("分時(shí)", onPressed: () => isLine = true),
        button("k線", onPressed: () => isLine = false),
        button("MA", onPressed: () => _mainState = MainState.MA),
        button("BOLL", onPressed: () => _mainState = MainState.BOLL),
        button("隱藏", onPressed: () => _mainState = MainState.NONE),
        button("MACD", onPressed: () => _secondaryState = SecondaryState.MACD),
        button("KDJ", onPressed: () => _secondaryState = SecondaryState.KDJ),
        button("RSI", onPressed: () => _secondaryState = SecondaryState.RSI),
        button("WR", onPressed: () => _secondaryState = SecondaryState.WR),
        button("隱藏副視圖", onPressed: () => _secondaryState = SecondaryState.NONE),
      ],
    );
  }

  Widget button(String text, {VoidCallback onPressed}) {
    return FlatButton(
        onPressed: () {
          if (onPressed != null) {
            onPressed();
            setState(() {});
          }
        },
        child: Text("$text"),
        color: Colors.blue);
  }

  void getData(String period) {
    Future<String> future = getIPAddress('$period');
    future.then((result) {
      Map parseJson = json.decode(result);
      List list = parseJson['data'];
      datas = list.map((item) => KLineEntity.fromJson(item)).toList().reversed.toList().cast<KLineEntity>();
      DataUtil.calculate(datas);
      showLoading = false;
      setState(() {});
    }).catchError((_) {
      showLoading = false;
      setState(() {});
      print('獲取數(shù)據(jù)失敗');
    });
  }

  Future<String> getIPAddress(String period) async {
    var url =
        'https://api.huobi.br.com/market/history/kline?period=${period ?? '1day'}&size=300&symbol=btcusdt';
    String result;
    var response = await http.get(url);
    if (response.statusCode == 200) {
      result = response.body;
    } else {
      print('Failed getting IP address');
    }
    return result;
  }
}

GitHub地址:https://github.com/gwhcn/flutter_k_chart
后期會(huì)持續(xù)完善,歡迎指出問題以及star

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 品質(zhì)控制服務(wù)深度用心程度傳播獲客營銷線下場景社群區(qū)域代理物流供應(yīng)鏈資源方與宏觀結(jié)構(gòu)力系統(tǒng)勝任能力公社理想 到位的工...
    咸叔說閱讀 241評論 0 1
  • 曾想在思想的深度走很遠(yuǎn),走很遠(yuǎn)。可生而為人,為動(dòng)物,活著也不過是為生存,為生殖。走的再遠(yuǎn)又何必,又何須。想走,還是要走。
    簡續(xù)之閱讀 219評論 0 0
  • 午飯是西葫蘆炒雞蛋就饅頭。翠綠的西葫蘆片搭配金黃的炒雞蛋,雪白的大饅頭,看著就有食欲。 于洋餓了,深吸一口香氣,埋...
    宇小天閱讀 529評論 0 0
  • 莫名地喜歡了雨天。 這兩天下著雨,早晨起來還灰蒙蒙的,不過馬上就變得生機(jī)勃勃的一家人,有的做早餐,...
    maggie_9aa2閱讀 407評論 0 2
  • 吟水萊 下午體育課的時(shí)候天氣特別熱。但是老師堅(jiān)決的要求我們一定要上課。30幾度的高溫再加上沒吃午飯的我還沒走到操場...
    吟水萊閱讀 336評論 0 1

友情鏈接更多精彩內(nèi)容