Flutter 不到50行代码就可以自定义可伸缩的Text控件

前提:

自学Flutter的第二周,已经可以自定义一些自己想要的控件了(仅限于简单点的),比如网络加载时的状态显示(loading,error,empty等),还有就是封装了loading 和第三方刷新加载库 SmartRefresher,在做网络加载时仅用一个自定义widget就可以做以上所有操作,不需要自己处理刷新和加载更多还有展示loading,error等操作,改天有时间发布一下。

回归正题,因为自己做项目的过程中,需要用到可伸缩的Text,在网上找寻第三方库的时候没有找到适合自己的,有些是因为显示问题,有些是因为滑动冲突,所以决定自己写一个。

收缩效果:

 

展开效果:

思路如下:

第一,因为要显示伸缩的文字,说到底还是文字,所以自定义的widget里面需要有Text。

第二,需求是text缩起来时显示几行,然后扩展开时,显示全部文字,

第三,需要一个icon之类的按钮在文字下面,缩起来显示向下图标,展开全部时显示向上图标

第四,就是StatelessWidget(无状态)和StatefulWidget(有状态)的选择, 因为我们这里需要变换图标还有行数,所以就选后面的StatefulWidget。

 

具体思路就写在源码里面的注释了,如下:

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

class ExpandText extends StatefulWidget {
  final String text; // 要显示的文字
  final int shrinkLines;// 收缩时要显示多少行 默认值为2
  final IconData shrinkIcon; // 收缩时候显示的icon 默认为Icons.keyboard_arrow_down
  final IconData expandIcon; // 展开时候显示的icon 默认为Icons.keyboard_arrow_down

  ExpandText(
      {@required this.text,// 必传参数
      this.shrinkLines = 2,
      this.shrinkIcon = Icons.keyboard_arrow_down,
      this.expandIcon = Icons.keyboard_arrow_up});

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

class _ExpandTextState extends State<ExpandText> {
  bool _isShrinkState = true; // 是否是缩小状态

  @override
  Widget build(BuildContext context) {
    // DefaultTextStyle 具体下面详细说明
    final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);
    //这里使用脚手架的原因是material下的Text不会有默认的下边黄色下划线,可以根据需求直接return 下面的Column
    return Scaffold(
      // 列布局 上面显示文字 下面显示icon按钮
      body: Column(
        children: [
          Text(
            widget.text,// 要显示的文字
            // 三目运算 是否是收缩状态  是的话就显示传入或者默认为2的行数 不是的话就显示能显示的最大行数
            maxLines: _isShrinkState ? widget.shrinkLines : defaultTextStyle.maxLines,
          ),
          // 这里因为icon需要点击 但icon本身没有点击事件 就在外面包裹 GestureDetector手势 ,然后在onTap里实现点击事件
          GestureDetector(
            // 三目运算 是否是收缩状态 是的话就显示收缩时需要显示的icon(有默认图标) 不是的话就显示展开时需要显示的icon(也有默认值)
            child: Icon(_isShrinkState ? widget.shrinkIcon : widget.expandIcon),
            // 点击事件
            onTap: () {
              // 点击时设置状态当前 重新绘制,
              setState(() {
                if (_isShrinkState) {
                  _isShrinkState = false;
                } else {
                  _isShrinkState = true;
                }
              });
            },
          ),
        ],
      ),
    );
  }
}

直接复制就可以用,如果想要其他的比如颜色或者字体大小什么的,可以自己在参数里面加TextStyle,需要什么自己添加就行。

写这个控件的时候碰到了一个小难点(其实也不算难点),就是收缩的时候可以设置行数,展开的时候设置几行呢?总不能去根据字数和字体大小来计算出行数吧。然后我就想到了Text本身就是可以计算出要显示的行数的,我就点Text源码去看,找到maxLines这个参数,然后全局搜索,果然一段源码引起了我的注意

maxLines: maxLines ?? defaultTextStyle.maxLines,

这个??符号有点类似于三目运算,意思是第二个maxLines为空吗 不为空第一个maxLines就为第二个maxLines,否则的话就为defaultTextStyle.maxLines,就是能显示多少行就显示多少行。我点击一下defaultTextStyle,然后源码转到build方法第一行,

final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context);

这时候我就把这一行代码复制到我自定义Text的build方法里面,使用了defaultTextStyle.maxLines这个最大值。

总结:Flutter和原生一样,并不是所有控件和效果都能在自带的widget里面找到,有时候可以去试着找第三方库或者自己定义一下,碰到难点就试着去读一下源码。到目前为止Flutter的学习资料还有第三方支持远远不如原生开发多,所以之后我如果碰到了一些问题或者思路都会在这里记录一下,帮助需要帮助的人,因为我也经常碰见难点需要帮助。当办法多了以后,问题就不是问题了。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值