美文网首页Android 技术文章
Flutter100行轻松实现自定义P站和油管的Logo及自由切

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

作者: AWeiLoveAndroid | 来源:发表于2019-11-18 17:44 被阅读0次

    版权声明:本文为博主原创文章,未经博主允许不得转载。
    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

    你可以根据自己的心情定义你自己的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
    6.同理可以自定义YouTube风格的Logo

    只需要更改传入的参数类型,即可实现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

    这就是我今天套给大家分享的一个干货知识点。作者辛苦了,麻烦点个赞吧,谢谢大家。

    关于作者:公众号“Flutter那些事”,独家放送最新Flutter、Dart和Fuchsia等技术动态,以及众多原创,有技术深度的技术干货文章,还有Flutter实战干货文章,等你来看,喜欢Flutter和跨平台开发以及原生移动端开发的朋友们,赶紧来看看,欢迎大家关注。

    相关文章

      网友评论

        本文标题:Flutter100行轻松实现自定义P站和油管的Logo及自由切

        本文链接:https://www.haomeiwen.com/subject/dyfbictx.html