Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能

AWeiLoveAndroid發表於2019-11-18

版權宣告:本文為博主原創文章,未經博主允許不得轉載。 juejin.im/post/5dd279…

轉載請標明出處: juejin.im/post/5dd279… 本文出自 AWeiLoveAndroid的部落格

本文首發在公眾號Flutter那些事,未經允許,嚴禁轉載。

本文配套程式碼已經傳到了github,歡迎朋友們給個star,感謝大家,希望能在幫助大家的同時,麻煩大家給個打賞買口水喝,謝謝大家。

開源倉庫地址: github.com/AweiLoveAnd…


本文首發在公眾號Flutter那些事,未經允許,嚴禁轉載。

本文配套程式碼已經傳到了github,歡迎朋友們給個star,感謝大家,希望能在幫助大家的同時,麻煩大家給個打賞買口水喝,謝謝大家。

開源倉庫地: github.com/AweiLoveAnd…


上次跟大家分享了Flutter實現Adobe全家桶Logo列表功能 ,主要通過一個簡單的案例,帶領大家瞭解如何在需求開發不斷變更的時候,學會封裝和具有架構核心思想。今天給大家帶來的是Flutter僅用100行程式碼輕鬆實現自定義P站和油管的Logo以及自由切換Logo的功能。通過這篇文章,你可以學到兩個知識點:自定義你喜歡的Logo風格;學會通過一個元件控制另一個元件的功能。下面詳細介紹我的實現思路和步驟。

本文內容圖文並茂,希望大家可以認真看完。為了避免大家犯困,我這裡特意準備了本文配套的兩個視訊,下面這個是騰訊視訊的播放連結:

騰訊視訊連結:Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能

如果你喜歡去B站觀看本文配套的視訊講解,請點選Bilibili連結:

B站連結: Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能

按照國際慣例,先來一張效果圖鎮樓。

Flutter建立自定義Logo並只有切換Logo效果圖

預設文字是“切換至PornHub Logo”,預設Logo是“YouTube”。當我點選按鈕的時候,文字變成“切換至YouTube Logo”,Logo變成“PornHub ”,當我再次點選,就會還原層預設的樣式。


第一部分:自定義Logo

你可以根據自己的心情定義你自己的Logo樣式,我這裡以“YouTube”和“PornHub”的Logo為模板,你可以隨意更改你的設定,然後達到自定義Logo的目的。下面詳細講解一下如何實現這兩個Logo模板的。

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風格,我們看一下執行效果如下圖所示:

效果圖

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',
    ),
  ],
),
複製程式碼

我們看看效果圖如下圖所示:

Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能

上例中有一個String.fromCharCodes(Runes('\u{1f525}'))這個用法是一個比較特殊的用法,詳細介紹可以檢視Flutter基礎篇(2)-- 老司機用一篇部落格帶你快速熟悉Dart語法,這裡面的第四條:資料型別,裡面有詳細的介紹,這裡就不再講解了。

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),
),
複製程式碼

效果如下圖所示:

Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能

同理把上述ListView的內容,對應的改成YouTube風格的相關配置,即可輕鬆實現YouTube風格的Logo樣式了

效果如下圖所示:

Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能

7.除此之外你還可以自定義各種型別的Logo風格

這類橫向的都是文字型別Logo很難收集,我花了很長時間才找到的,所以就照葫蘆畫瓢做了這些Logo,截圖如下所示:

【注】:這裡的Logo都是百度到的,然後自己試著用上述程式碼模板仿製出來了,僅作為學習使用,嚴禁商用,這部分的程式碼就不提供了,希望大家理解。

Flutter創造更多自定義Logo


第二部分:自由切換Logo功能(這個很牛逼了)

1.封裝InheritedWidget類

封裝一個類繼承自InheritedWidget類,把我們要操作的內容傳入即可。

【Tips:】為什麼要用InheritedWidget類,因為直接操作是沒反應的,而使用它可以讓不同層級(樹形結構)的元件之間相互交操作,所以很牛逼啊,不用不行。

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;
}
複製程式碼

這就是我今天套給大家分享的一個乾貨知識點。作者辛苦了,麻煩點個贊吧,謝謝大家。

關於作者:公眾號“Flutter那些事”,獨家放送最新Flutter、Dart和Fuchsia等技術動態,以及眾多原創,有技術深度的技術乾貨文章,還有Flutter實戰乾貨文章,等你來看,喜歡Flutter和跨平臺開發以及原生移動端開發的朋友們,趕緊來看看,歡迎大家關注。

相關文章