Flutter數(shù)字鍵盤自實(shí)現(xiàn)

用getx實(shí)現(xiàn)的數(shù)字鍵盤

使用示例

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:demo_news/num_keyboard.dart';

class NewsPage3 extends GetView {

  final PayNumKeyboardController _textEditingController = PayNumKeyboardController('');
  final _resultData = ''.obs;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(""),
      ),
      body: _buildBody(context),
    );
  }

  Widget _buildBody(BuildContext context) {
    return Column(
      children: [
        SizedBox(height: 60, width: MediaQuery.sizeOf(context).width),
        Text(
          '修改支付密碼',
          style: TextStyle(
            fontSize: 20,
            fontWeight: FontWeight.w500,
          ),
        ),
        SizedBox(height: 10),
        Text(
          '請(qǐng)輸入原始支付密碼恤磷,以驗(yàn)證身份',
          style: TextStyle(
            fontSize: 15,
          ),
        ),
        SizedBox(height: 20),
        Obx(() {
          return _buildNumberWidget(_resultData.value.length);
        }),
        Spacer(),
        PayNumKeyboard(
          controller: _textEditingController,
          onChanged: (value) {
            _resultData.value = value;
            if (value.length == 6) {
              _textEditingController.clearText();
              _resultData.value = '';
              // 接口校驗(yàn)
            }
          },
        ),
      ],
    );
  }

  Widget _buildNumberWidget(int length) {
    return Container(
      height: 47,
      width: 282,
      child: ListView.builder(
        padding: EdgeInsets.zero,
        scrollDirection: Axis.horizontal,
        physics: NeverScrollableScrollPhysics(),
        itemCount: 6,
        itemExtent: 47,
        itemBuilder: (BuildContext context, int index) {
          bool showPoint = index < length;
          return _buildNumberItemWidget(index, showPoint);
        },
      ),
    );
  }

  Widget _buildNumberItemWidget(int index, bool showPoint) {
    // 設(shè)置四周圓角 角度
    BorderRadiusGeometry borderRadius = BorderRadius.only();
    // 設(shè)置四周邊框
    Color color = Colors.black12;
    BorderSide borderSide0 = BorderSide(width: 0, color: color);
    BorderSide borderSide05 = BorderSide(width: 0.5, color: color);
    BoxBorder border = Border(top: borderSide05, left: borderSide05, bottom: borderSide05, right: borderSide0);
    if (index == 0) {
      borderRadius = BorderRadius.only(
        topLeft: Radius.circular(4),
        bottomLeft: Radius.circular(4),
      );
      border = Border(top: borderSide05, left: borderSide05, bottom: borderSide05, right: borderSide0);
    } else if (index == 5) {
      borderRadius = BorderRadius.only(
        topRight: Radius.circular(4),
        bottomRight: Radius.circular(4),
      );
      border = Border.all(width: 0.5, color: color);
    }
    return Container(
      height: 47,
      width: 47,
      alignment: Alignment.center,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: borderRadius,
        border: border,
      ),
      child: showPoint
          ? Container(
        height: 10,
        width: 10,
        decoration: BoxDecoration(
          color: Colors.black,
          borderRadius: BorderRadius.circular(5),
        ),
      )
          : Container(),
    );
  }
}

鍵盤組件

import 'package:flutter/material.dart';
import 'package:get/get.dart';

class PayNumKeyboard extends StatelessWidget {
  final PayNumKeyboardController controller;
  final ValueChanged<String> onChanged;

  PayNumKeyboard({required this.controller, required this.onChanged, Key? key}) : super(key: key);

  static const List<PayKeyboardDataBean> _keyboardDataList = [
    PayKeyboardDataBean(PayKeyboardType.num, "1"),
    PayKeyboardDataBean(PayKeyboardType.num, "2"),
    PayKeyboardDataBean(PayKeyboardType.num, "3"),
    PayKeyboardDataBean(PayKeyboardType.num, "4"),
    PayKeyboardDataBean(PayKeyboardType.num, "5"),
    PayKeyboardDataBean(PayKeyboardType.num, "6"),
    PayKeyboardDataBean(PayKeyboardType.num, "7"),
    PayKeyboardDataBean(PayKeyboardType.num, "8"),
    PayKeyboardDataBean(PayKeyboardType.num, "9"),
    PayKeyboardDataBean(PayKeyboardType.none, ""),
    PayKeyboardDataBean(PayKeyboardType.num, "0"),
    PayKeyboardDataBean(PayKeyboardType.delete, ""),
  ];

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
      gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
        crossAxisCount: 3,
        childAspectRatio: (125 / 54),
      ),
      itemBuilder: (context, index) {
        return buildNumKeyboardItem(_keyboardDataList[index]);
      },
      itemCount: _keyboardDataList.length,
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
    );
  }

  Widget buildNumKeyboardItem(PayKeyboardDataBean keyboardDataBean) {
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: () {
        if (keyboardDataBean.type == PayKeyboardType.delete) {
          if (controller.value.length > 0) {
            controller.value = controller.value.substring(0, controller.value.length - 1);
            onChanged(controller.value);
          }
        } else if (keyboardDataBean.type == PayKeyboardType.num) {
          controller.value += keyboardDataBean.value;
          onChanged(controller.value);
        }
      },
      child: Container(
        alignment: Alignment.center,
        decoration: BoxDecoration(
          color: keyboardDataBean.type == PayKeyboardType.num ? Colors.transparent : Colors.black12,
          border: Border(
            top: BorderSide(width: 0.5, color: Colors.black12),
            right: BorderSide(width: 0.5, color: Colors.black12),
          ),
        ),
        child: keyboardDataBean.type == PayKeyboardType.delete
            ? Image.asset('packages/demo_news/assets/images/keyboard_delete.png', width: 24, height: 24,)
            : Text(
                keyboardDataBean.value,
                style: TextStyle(
                  fontSize: 20,
                  color: Colors.black,
                ),
              ),
      ),
    );
  }
}

enum PayKeyboardType {
  none,
  num,
  delete,
}

class PayKeyboardDataBean {
  final PayKeyboardType type;
  final String value;

  const PayKeyboardDataBean(this.type, this.value);
}

class PayNumKeyboardController extends RxString {
  PayNumKeyboardController(super.initial);

  void setText(String text) {
    value = text;
  }

  void clearText() {
    value = '';
  }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壳坪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子童本,更是在濱河造成了極大的恐慌岸霹,老刑警劉巖萄唇,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峡谊,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡雏蛮,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門阱州,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)挑秉,“玉大人,你說(shuō)我怎么就攤上這事苔货∠牛” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵夜惭,是天一觀的道長(zhǎng)姻灶。 經(jīng)常有香客問我,道長(zhǎng)诈茧,這世上最難降的妖魔是什么产喉? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮敢会,結(jié)果婚禮上曾沈,老公的妹妹穿的比我還像新娘。我一直安慰自己鸥昏,他們只是感情好塞俱,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吏垮,像睡著了一般障涯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上膳汪,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天唯蝶,我揣著相機(jī)與錄音,去河邊找鬼遗嗽。 笑死生棍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的媳谁。 我是一名探鬼主播涂滴,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼晴音!你這毒婦竟也來(lái)了柔纵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锤躁,失蹤者是張志新(化名)和其女友劉穎搁料,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡郭计,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年霸琴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昭伸。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梧乘,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出庐杨,到底是詐尸還是另有隱情选调,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布灵份,位于F島的核電站仁堪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏填渠。R本人自食惡果不足惜弦聂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望氛什。 院中可真熱鬧莺葫,春花似錦、人聲如沸屉更。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)瑰谜。三九已至,卻和暖如春树绩,著一層夾襖步出監(jiān)牢的瞬間萨脑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工饺饭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留渤早,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓瘫俊,卻偏偏與公主長(zhǎng)得像鹊杖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扛芽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344