­

Flutter100行轻松实现自定义P站和油管的Logo及自由切换Logo功能

  • 2019 年 11 月 21 日
  • 筆記

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://www.jianshu.com/p/004b7a56bb51

转载请标明出处: https://www.jianshu.com/p/004b7a56bb51 本文出自 AWeiLoveAndroid的博客

本文首发在公众号Flutter那些事,未经允许,严禁转载。

本文配套代码已经传到了github,欢迎朋友们给个star,感谢大家,希望能在帮助大家的同时,麻烦大家给个打赏买口水喝,谢谢大家。

开源仓库地址: https://github.com/AweiLoveAndroid/Flutter-learning/

Flutter系列博文链接 ↓:

工具安装:

Flutter基础篇:

Flutter进阶篇:

Dart语法系列博文链接 ↓:

Dart语法基础篇:

Dart语法进阶篇:


本文首发在公众号Flutter那些事,未经允许,严禁转载。

本文配套代码已经传到了github,欢迎朋友们给个star,感谢大家,希望能在帮助大家的同时,麻烦大家给个打赏买口水喝,谢谢大家。

开源仓库地: https://github.com/AweiLoveAndroid/Flutter-learning/


上次跟大家分享了Flutter实现Adobe全家桶Logo列表功能 ,主要通过一个简单的案例,带领大家了解如何在需求开发不断变更的时候,学会封装和具有架构核心思想。今天给大家带来的是Flutter仅用100行代码轻松实现自定义P站和油管的Logo以及自由切换Logo的功能。通过这篇文章,你可以学到两个知识点:自定义你喜欢的Logo风格;学会通过一个组件控制另一个组件的功能。下面详细介绍我的实现思路和步骤。

本文内容图文并茂,希望大家可以认真看完。为了避免大家犯困,我这里特意准备了本文配套的两个视频,下面这个是腾讯视频的播放链接:

腾讯视频链接:Flutter100行轻松实现自定义P站和油管的Logo及自由切换Logo功能

如果你喜欢去B站观看本文配套的视频讲解,请点击Bilibili链接:

B站链接: Flutter100行轻松实现自定义P站和油管的Logo及自由切换Logo功能


你可以根据自己的心情定义你自己的Logo样式,我这里以“YouTube”和“PornHub”的Logo为模板,你可以随意更改你的设置,然后达到自定义Logo的目的。下面详细讲解一下如何实现这两个Logo模板的。

image

1.首先这里是一个Contanner组件,给它设置背景,边框,文字内容,以及对应的前景和背景颜色。

示例代码如下所示:

@override  Widget build(BuildContext context) {    return Container(      margin: EdgeInsets.all(30),      width: widget.bgWidth,      height: widget.bgHeight,      color: widget.bgColor,      child: Row(        mainAxisSize: MainAxisSize.max,        mainAxisAlignment: MainAxisAlignment.center,        children: <Widget>[          Padding(            padding: EdgeInsets.only(left: 0, top: 0, right: 5, bottom: 0),            child: Text(              widget.leftText,              style: TextStyle(                fontSize: widget.leftTextSize,                color: widget.leftTextColor,                fontWeight: FontWeight.bold,              ),            ),          ),          Container(            decoration: BoxDecoration(              color: widget.rightBgColor,              border: Border.all(                color: widget.rightBgColor,                width: 8.0,              ),              borderRadius: BorderRadius.circular(                widget.rightBgBorderRadius,              ),            ),            padding: EdgeInsets.all(5),            child: Text(              widget.rightText,              style: TextStyle(                fontSize: widget.leftTextSize,                color: widget.rightTextColor,                fontWeight: FontWeight.bold,              ),// TextStyle            ),// Text          ),// Container        ],// Row children      ),// Row    );// Container  }
2.传入所需的变量类型

这里面需要传入的变量有很多,包括以下这些:

// 全局背景颜色    Color bgColor;      // 全局内容宽度    double bgWidth;      // 全局内容高度    double bgHeight;      // 左侧文字内容    String leftText;      // 左侧文字大小    double leftTextSize;      // 左侧文字颜色    Color leftTextColor;      // 右侧背景颜色    Color rightBgColor;      // 右侧边框圆角大小    double rightBgBorderRadius;      // 右侧文字内容    String rightText;      //  右侧文字颜色    Color rightTextColor;
3.构造函数里面传入这些变量,并对每一个变量做一个初始化

代码如下所示:

  Contents(        {Key key,        this.bgColor = Colors.black,        this.bgWidth = 300,        this.bgHeight = 300,        this.leftText = 'Porn',        this.leftTextSize = 30,        this.leftTextColor = Colors.white,        this.rightBgColor = const Color.fromARGB(255, 254, 155, 0),        this.rightBgBorderRadius = 5,        this.rightText = 'Hub',        this.rightTextColor = Colors.black})        : super(key: key);
4.接下来我们可以使用这个类

下面这个就是PornHub风格的样式:

Scaffold(    appBar: AppBar(      title: Text('Flutter创建自定义Logo'),    ),    body: Contents(        bgColor: Colors.black,        bgWidth: 300,        bgHeight: 300,        leftText: 'Porn',        leftTextSize: 60,        leftTextColor: Colors.white,        rightBgColor: Color.fromARGB(255, 254, 155, 0),        rightBgBorderRadius: 5,        rightText: 'Hub',        rightTextColor: Colors.black,    ),  );

如果我们只使用:body: Contents(),,啥属性都不填写,默认就是PornHub风格,我们看一下运行效果如下图所示:

效果图

母胎单身的我不知道你们在笑什么。

image

5.你也可以自定义其它的样式

比如以下几个示例:

body:ListView(    children: <Widget>[      Contents(        bgWidth: 150,        bgHeight: 150,        leftText: '${String.fromCharCodes(Runes('u{1f525}'))}Tokyo',        rightText: 'Hot',      ),      Contents(        bgWidth: 150,        bgHeight: 150,        leftText: 'Git',        rightText: 'Hub',      ),      Contents(        bgWidth: 150,        bgHeight: 150,        leftText: 'Flutter',        rightText: 'dev',      ),        Contents(        bgWidth: 150,        bgHeight: 150,        leftText: '韦哥的',        rightText: '博客',      ),      Contents(        bgWidth: 150,        bgHeight: 150,        leftText: 'Developer',        rightText: 'Group',      ),    ],  ),

上例中有一个String.fromCharCodes(Runes('u{1f525}'))这个用法是一个比较特殊的用法,详细介绍可以查看Flutter基础篇(2)– 老司机用一篇博客带你快速熟悉Dart语法,这里面的第四条:数据类型,里面有详细的介绍,这里就不再讲解了。我们看看效果图如下图所示:

image

我的天啊,这个“PornHub”风格的Logo太有魔性了,我笑出了猪叫。

image

只需要更改传入的参数类型,即可实现YouTube的Logo风格了,示例如下:

Contents(    bgColor: Color.fromARGB(255, 238, 28, 27),    bgWidth: 150,    bgHeight: 150,    leftText: 'You',    leftTextSize: 40,    leftTextColor: Colors.white,    rightBgColor: Colors.white,    rightBgBorderRadius: 10,    rightText: 'Tube',    rightTextColor: Color.fromARGB(255, 238, 28, 27),  ),

效果如下图所示:

image

同理把上述ListView的内容,对应的改成YouTube风格的相关配置,即可轻松实现YouTube风格的Logo样式了

效果如下图所示:

image

7.除此之外你还可以自定义各种类型的Logo风格

这类横向的都是文字类型Logo很难收集,我花了很长时间才找到的,所以就照葫芦画瓢做了这些Logo,截图如下所示:

Flutter创造更多自定义Logo

【注意】: 这里的Logo都是百度到的,然后自己试着用上述代码模板仿制出来了,仅作为学习使用,严禁商用,这部分的代码就不提供了,希望大家理解。

image


第二部分:自由切换Logo功能(这个很牛逼了)

1.封装InheritedWidget类

封装一个类继承自InheritedWidget类,把我们要操作的内容传入即可。

【Tips:】为什么要用InheritedWidget类,因为直接操作是没反应的,而使用它可以让不同层级(树形结构)的组件之间相互交操作,所以很牛逼啊,不用不行。

image

下面看看代码是怎么写的:

class MyInheritedWidget extends InheritedWidget {    final String texts;    final Function onTap;    final Widget showWidgetContents;    final bool isChange;      const MyInheritedWidget(        {Key key,        this.texts,        this.onTap,        this.showWidgetContents,        this.isChange,        child})        : super(key: key, child: child);      @override    bool updateShouldNotify(MyInheritedWidget oldWidget) {      return oldWidget.showWidgetContents != showWidgetContents ||          oldWidget.isChange != isChange ||          oldWidget.texts != texts;    }      static MyInheritedWidget of(BuildContext context) {      return context.inheritFromWidgetOfExactType(MyInheritedWidget);    }  }
2.修改body的具体内容页面

ListView的内容修改如下,替换成使用 MyInheritedWidget操作我们的组件:

body: ListView(    children: <Widget>[      MyInheritedWidget.of(context).showWidgetContents,        RaisedButton(          onPressed: () {            MyInheritedWidget.of(context).onTap();          },        child:Text(            '${MyInheritedWidget.of(context).texts.toString()}'        ),      ),    ],  ),
3.在主页面里面修改逻辑交互的操作内容

把我们的操作对象逐个存入给MyInheritedWidget,然后包裹住我们的具体页面内容MyHomePage

@override  Widget build(BuildContext context) {      return new MyInheritedWidget(        texts: texts,        onTap: changeWidget,        showWidgetContents: showWidgetContents,        isChange: isChange,        child: new MyHomePage(),      );  }
4.当我们点击按钮时,changeWidget()函数会被调用,按钮文字和Logo都会跟随更改。
changeWidget() {      setState(() {        if (isChange == true) {          showWidgetContents = new Contents().pornhub;          texts = '切换至 YouTube Logo';          isChange = !isChange;        } else {          showWidgetContents = Contents().youtube;          // showWidgetContents = Contents().suning;          texts = '切换至 PornHub Logo';          isChange = !isChange;        }      });      return showWidgetContents;  }

(大家心想:博主真是太厉害了,不多说了,赶紧拿个笔记下来!哈哈哈。。。)

image

默认文字是“切换至PornHub Logo”,默认Logo是“YouTube”。当我点击按钮的时候,文字变成“切换至YouTube Logo”,Logo变成“PornHub ”,当我再次点击,就会还原层默认的样式。

最后让我们看看效果图,如下所示:

image