flutter 封装组件(1)

前言:先封装几个组件,provider相关的知识后续更新

1.Flutter AppBar 封装

(1)首先我们要找到源码里面AppBar实现的类

(2)开始封装(属性以备注好了)

import 'package:flutter/material.dart';
import 'package:bourse/constant/i_colors.dart';
import 'package:bourse/utils/general_util.dart';
import 'package:bourse/utils/screen_util.dart';

///标题
class AppbarWidget {
  
  final String title;
  final onTap;
  ///是否展示back键
  final bool canBack;
  ///右侧菜单
  final List<Widget> actions;
  ///给以在app下方添加的组件,例如TabBar
  final Widget bottom;
  ///是否居中
  final bool centerTitle;
  final Color backgroundColor;
  final Color fontColor;
  ///back键颜色
  final Color arrowColor;
  ///设置状态栏字体颜色
  final Brightness brightness;

  AppbarWidget({
    this.title = '',
    this.canBack = true,
    this.actions,
    this.centerTitle = true,
    this.onTap,
    this.bottom,
    this.backgroundColor = Colors.white,
    this.fontColor = textColor333,
    this.arrowColor = textColor333,
    this.brightness = Brightness.light
  });

  PreferredSizeWidget build(BuildContext context) {
    ///屏幕适配
    //GeneralUtil.screenAdaptation(context);
    return AppBar(
      backgroundColor: backgroundColor,
      elevation: 0,
      title: Text(
        "$title",
        style: TextStyle(
          fontSize: 17,
          color: fontColor,
        ),
      ),
      brightness: brightness,
      leading: canBack
          ? InkWell(
              child: Icon(
                Icons.arrow_back_ios,
                color: arrowColor,
                size: sHeight(40),
              ),
              onTap: onTap ?? () => Navigator.pop(context),
            )
          : null,
      centerTitle: centerTitle,
      actions: actions,
      bottom: bottom,
    );
  }
}

(3)使用

DefaultTabController(
      length: 2,
      child: new Scaffold(
        backgroundColor: Colors.white,
        appBar: AppbarWidget(
          backgroundColor: whiteColor,
          title: "${S.of(context).coin_logs}",
          bottom: TabBar(
            controller: _tabController,
            indicatorSize: TabBarIndicatorSize.label,
            indicatorColor: Color(0xff3A3B47),
            indicatorWeight: sHeight(2 * 3),
            unselectedLabelColor: textColor999,
            labelColor: textColor333,
            tabs: [
              Text(
                '${S.of(context).wallet_assets_recharge}',
                style: TextStyle(fontSize: sSp(15 * 3)),
              ),
              Text(
                '${S.of(context).wallet_assets_pick}',
                style: TextStyle(fontSize: sSp(15 * 3)),
              ),
            ],
          ),
        ).build(context),//别忘了.build(context)
        body://
}

2.Flutter 全局按钮封装

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:bourse/constant/i_colors.dart';
import 'package:bourse/utils/general_util.dart';
import 'package:bourse/utils/screen_util.dart';

class CommitButtonWidget extends StatefulWidget {
  ///按钮显示的子widget
  final Widget child;
  ///必传参数,按钮展示时的颜色
  final Color color;
  ///按钮按压下的颜色
  final Color disabledColor;
  final EdgeInsetsGeometry padding;
  ///圆角
  final BorderRadius borderRadius ;
  final onPressed;
  ///线框
  final double borderWidth;
  ///可以重制CupertinoButton的默认大小(padding)
  final double minSize;
  ///按钮宽度
  final double width;
  final bool isRadius;

  const CommitButtonWidget({
    Key key,
    @required this.color,
    @required this.disabledColor,
    this.padding,
    this.borderRadius ,
    this.onPressed,
    this.minSize = 44,
    this.child,
    this.borderWidth = 0.01,
    this.isRadius = true,
    this.width = 300,
  }) : super(key: key);

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

class _CommitButtonWidgetState extends State<CommitButtonWidget> {
  @override
  Widget build(BuildContext context) {
    GeneralUtil.screenAdaptation(context);
    return Container(
      width: widget.width,
      decoration: BoxDecoration(
        border: Border.all(width: widget.borderWidth , color: primaryColor),
        borderRadius: BorderRadius.all(Radius.circular(widget.isRadius ? 4 :0))
      ),
      child: CupertinoButton(
        minSize: widget.minSize,
        child: widget.child,
        color: widget.color,
        disabledColor: widget.disabledColor,
        padding: widget.padding,
        borderRadius: widget.borderRadius,
        onPressed: this.widget.onPressed,
      ),
    );
  }
}

使用:

(非线框)

 CommitButtonWidget(
                  width: sWidth(264 * 3),
                  borderRadius: BorderRadius.all(Radius.circular(4)),
                  padding: EdgeInsets.symmetric(
                    vertical: sHeight(27),
                  ),
                  disabledColor: Colors.grey,
                  color: Color(0xff3B3F52),
                  isRadius: false,
                  child: Text(
                    "${widget.cancelText}",
                    style: TextStyle(
                        fontSize: sSp(16 * 3), color: Color(0xffEEC67F)),
                  ),
                  onPressed: () {
                    Navigator.pop(context);
                    widget.cancelCallback("cancel");
                  },
                ),

(2)线框

CommitButtonWidget(
                              color: whiteColor,
                              child: Text(
                                '${S.of(context).invite_copy}',
                                style: TextStyle(
                                  fontSize: sSp(13 * 3),
                                  color: textColor333,
                                ),
                              ),
                              disabledColor: Colors.grey,
                              minSize: 20,
                              padding: EdgeInsets.symmetric(

                                  vertical: sHeight(6 * 3)),
                              borderRadius:
                                  BorderRadius.all(Radius.circular(4)),
                              borderWidth: sWidth(1 * 3),
                              onPressed: () {
                                ///复制内容
                                ClipboardData data =
                                    new ClipboardData(text: "${SpUtil.getString(Constant.USER_INVITE_CODE)}");
                                Clipboard.setData(data);
                                showToast('${S().invite_copy_success}');
                              },
                            ),

3.Flutter  轮播图组件

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:scm/utils/general_util.dart';
import 'package:scm/utils/screen_util.dart';

class IBannerView extends StatelessWidget implements PreferredSizeWidget {
  final List banners;
  final double bannerHeight;
  final double bannerWidth;
  final SwiperOnTap onTap;
  ///指示器样式
  final SwiperPlugin pagination;
  final bool autoPlay;
  final Alignment alignment;
  final ValueChanged<int> onIndexChanged;

  IBannerView(
      {@required this.banners,
      @required this.bannerHeight,
      @required this.bannerWidth,
      this.onTap,
      this.pagination,
      this.alignment = Alignment.bottomCenter,
      this.autoPlay = true,
      this.onIndexChanged});

  @override
  Size get preferredSize =>
      new Size(bannerWidth, bannerHeight);

  @override
  Widget build(BuildContext context) {
    GeneralUtil.screenAdaptation(context,  width: 1125);
    return new Container(
      width: this.preferredSize.width,
      height: this.preferredSize.height,

      ///Swiper组件支持无限轮播
      child: banners.length > 0
          ? new Swiper(
              autoplay: autoPlay,

              ///构建轮播item的样式
              itemBuilder: (BuildContext context, int index) {
                return new Container(
                  margin: EdgeInsets.symmetric(horizontal: sWidth(0)),
                  padding: EdgeInsets.only(bottom: 3),
                  child: new ClipRRect(
                    borderRadius: BorderRadius.circular(4.0),
                    child: Image.network(
                      banners[index],
                      fit: BoxFit.cover,
                    ),
                  ),

                );
              },

              ///轮播指示器(支持数字和点,其他类型可自定义)
              pagination: new SwiperPagination(
                builder: pagination,
                alignment: alignment
              ),
              itemCount: this.banners.length,
              scale: 0.95,
              ///回掉当前index
              onIndexChanged: (index) {
                if (onIndexChanged != null) {
                  onIndexChanged(index);
                }
              },
              onTap: (int index) {
                if (onTap != null) {
                  onTap(index);
                }
              },
            )
          : new Center(),
    );
  }

}

使用

 IBannerView(
              banners: banners,
              bannerHeight: sHeight(168 * 3),
              bannerWidth: sWidth(373 * 3),
              ///指示器为小点
              pagination: DotSwiperPaginationBuilder(
                color: Colors.white.withOpacity(0.5),
                activeColor: Colors.white,
                size: 6.0,
                activeSize: 7.0,
              ),
            ),

备注:如果指示器有特殊样式,可以自定义 

<1>首先继承SwiperPlugin

<2>代码

import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_swiper/flutter_swiper.dart';
import 'package:scm/constant/i_colors.dart';
import 'package:scm/utils/general_util.dart';

class CustomizePaginationBuilder extends SwiperPlugin {
  ///color ,if set null , will be Theme.of(context).scaffoldBackgroundColor
  final Color color;

  ///color when active,if set null , will be Theme.of(context).primaryColor
  final Color activeColor;

  font size
  final double fontSize;

  ///font size when active
  final double activeFontSize;

  final Key key;

  final Color bgColor;

  final double horizontal;
  final double vertical;

  const CustomizePaginationBuilder(
      {this.color,
      this.fontSize: 20.0,
      this.key,
      this.activeColor,
      this.bgColor = whiteTransferColor,
      this.horizontal = 10,
      this.vertical= 4,
      this.activeFontSize: 35.0});

  @override
  Widget build(BuildContext context, SwiperPluginConfig config) {
    ThemeData themeData = Theme.of(context);
    Color activeColor = this.activeColor ?? themeData.primaryColor;
    Color color = this.color ?? themeData.scaffoldBackgroundColor;

    if (Axis.vertical == config.scrollDirection) {
      return Container(
        padding: EdgeInsets.symmetric(vertical: vertical , horizontal: horizontal,),
        decoration: GeneralUtil.decoration(
          radius: 10,
          color: bgColor,
        ),
        child: new Column(
          key: key,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            new Text(
              "${config.activeIndex + 1}",
              style: TextStyle(color: activeColor, fontSize: activeFontSize),
            ),
            new Text(
              "/",
              style: TextStyle(color: color, fontSize: fontSize),
            ),
            new Text(
              "${config.itemCount}",
              style: TextStyle(color: color, fontSize: fontSize),
            )
          ],
        ),
      );
    } else {
      return Container(
        padding: EdgeInsets.symmetric(vertical: vertical , horizontal: horizontal,),
        decoration: GeneralUtil.decoration(
          radius: 10,
          color: bgColor,
        ),
        child: new Row(
          key: key,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            new Text(
              "${config.activeIndex + 1}",
              style: TextStyle(color: activeColor, fontSize: activeFontSize),
            ),
            new Text(
              " / ${config.itemCount}",
              style: TextStyle(color: color, fontSize: fontSize),
            )
          ],
        ),
      );
    }
  }
}

使用

IBannerView(
            banners: banners,
            autoPlay: false,
            bannerHeight: sHeight(375 * 3),
            bannerWidth: ScreenUtil.screenWidth,

            ///指示器位置
            alignment: Alignment.bottomRight,

            ///自定义指示器样式
            pagination: CustomizePaginationBuilder(
              color: textColor333,
              fontSize: sSp(45),
              activeFontSize: sSp(45),
              activeColor: textColor333,
              bgColor: Color(0x70cccccc),
              vertical: sHeight(6),
              horizontal: sWidth(33),
            ),
          ),

效果 

4. flutter 评分星级组件

(1).插件依赖

smooth_star_rating: ^1.1.1

(2).封装

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

class SmoothStarWidget extends StatefulWidget {
  final double rating;
  final bool isReadOnly;
  final double size;
  final int starCount;
  final bool allowHalfRating;
  final double spacing;
  final Color color;
  final Color borderColor;
  final ValueChanged<double> valueCallback;

  const SmoothStarWidget({
    Key key,
    this.rating,
    this.isReadOnly,
    this.size,
    this.starCount,
    this.allowHalfRating,
    this.spacing,
    this.color = Colors.blue,
    this.borderColor= Colors.grey,
    this.valueCallback,
  }) : super(key: key);

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

class _SmoothStarWidgetState extends State<SmoothStarWidget> {
  @override
  Widget build(BuildContext context) {
    return SmoothStarRating(
      ///默认展示个数
      rating: widget.rating,
      ///是否可读
      isReadOnly: widget.isReadOnly,
      ///大小
      size: widget.size,
      filledIconData: Icons.star,
      halfFilledIconData: Icons.star_half,
      defaultIconData: Icons.star_border,
      ///星级总个数
      starCount: widget.starCount,
      ///是否展示半星
      allowHalfRating: widget.allowHalfRating,
      spacing: widget.spacing,
      color: widget.color,
      borderColor: widget.borderColor,
      ///点击事件
      onRated: (value) =>widget.valueCallback(value),
    );
  }
}

使用:

SmoothStarWidget(
                        rating: 3,
                        isReadOnly: false,
                        size: 18,
                        starCount: 5,
                        allowHalfRating: true,
                        spacing: 2.0,
                        color: Colors.red,
                        valueCallback: (value) => print("$value"),
                      ),

效果:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值