版權聲明:本文爲博主原創文章,未經博主容許不得轉載。 juejin.im/post/5dd279…html
轉載請標明出處: juejin.im/post/5dd279… 本文出自 AWeiLoveAndroid的博客git
本文首發在公衆號Flutter那些事,未經容許,嚴禁轉載。github
本文配套代碼已經傳到了github,歡迎朋友們給個star
,感謝你們,但願能在幫助你們的同時,麻煩你們給個打賞買口水喝,謝謝你們。bash
開源倉庫地: github.com/AweiLoveAnd…架構
上次跟你們分享了Flutter實現Adobe全家桶Logo列表功能 ,主要經過一個簡單的案例,帶領你們瞭解如何在需求開發不斷變動的時候,學會封裝和具備架構核心思想。今天給你們帶來的是Flutter僅用100行代碼輕鬆實現自定義P站和油管的Logo以及自由切換Logo的功能。經過這篇文章,你能夠學到兩個知識點:自定義你喜歡的Logo風格;學會經過一個組件控制另外一個組件的功能。下面詳細介紹個人實現思路和步驟。app
本文內容圖文並茂,但願你們能夠認真看完。爲了不你們犯困,我這裏特地準備了本文配套的兩個視頻,下面這個是騰訊視頻的播放連接:ide
騰訊視頻連接:Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能函數
若是你喜歡去B站觀看本文配套的視頻講解,請點擊Bilibili連接:post
B站連接: Flutter100行輕鬆實現自定義P站和油管的Logo及自由切換Logo功能學習
你能夠根據本身的心情定義你本身的Logo樣式,我這裏以「YouTube」和「PornHub」的Logo爲模板,你能夠隨意更改你的設置,而後達到自定義Logo的目的。下面詳細講解一下如何實現這兩個Logo模板的。
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
}
複製代碼
這裏面須要傳入的變量有不少,包括如下這些:
// 全局背景顏色
Color bgColor;
// 全局內容寬度
double bgWidth;
// 全局內容高度
double bgHeight;
// 左側文字內容
String leftText;
// 左側文字大小
double leftTextSize;
// 左側文字顏色
Color leftTextColor;
// 右側背景顏色
Color rightBgColor;
// 右側邊框圓角大小
double rightBgBorderRadius;
// 右側文字內容
String rightText;
// 右側文字顏色
Color rightTextColor;
複製代碼
代碼以下所示:
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);
複製代碼
下面這個就是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
風格,咱們看一下運行效果以下圖所示:
母胎單身的我不知道大家在笑什麼。
好比如下幾個示例:
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語法,這裏面的第四條:數據類型
,裏面有詳細的介紹,這裏就再也不講解了。咱們看看效果圖以下圖所示:
個人天啊,這個「PornHub
」風格的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),
),
複製代碼
效果以下圖所示:
同理把上述ListView的內容,對應的改爲YouTube
風格的相關配置,便可輕鬆實現YouTube
風格的Logo樣式了
效果以下圖所示:
這類橫向的都是文字類型Logo很難收集,我花了很長時間才找到的,因此就照葫蘆畫瓢作了這些Logo,截圖以下所示:
【注意】: 這裏的Logo都是百度到的,而後本身試着用上述代碼模板仿製出來了,僅做爲學習使用,嚴禁商用,這部分的代碼就不提供了,但願你們理解。
封裝一個類繼承自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);
}
}
複製代碼
ListView的內容修改以下,替換成使用 MyInheritedWidget
操做咱們的組件:
body: ListView(
children: <Widget>[
MyInheritedWidget.of(context).showWidgetContents,
RaisedButton(
onPressed: () {
MyInheritedWidget.of(context).onTap();
},
child:Text(
'${MyInheritedWidget.of(context).texts.toString()}'
),
),
],
),
複製代碼
把咱們的操做對象逐個存入給MyInheritedWidget
,而後包裹住咱們的具體頁面內容MyHomePage
。
@override
Widget build(BuildContext context) {
return new MyInheritedWidget(
texts: texts,
onTap: changeWidget,
showWidgetContents: showWidgetContents,
isChange: isChange,
child: new MyHomePage(),
);
}
複製代碼
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;
}
複製代碼
(你們心想:博主真是太厲害了,很少說了,趕忙拿個筆記下來!哈哈哈。。。)
默認文字是「切換至PornHub Logo」,默認Logo是「YouTube」。當我點擊按鈕的時候,文字變成「切換至YouTube Logo」,Logo變成「PornHub 」,當我再次點擊,就會還原層默認的樣式。
最後讓咱們看看效果圖,以下所示:
這就是我今天套給你們分享的一個乾貨知識點。做者辛苦了,麻煩點個贊吧,謝謝你們。
關於做者:公衆號「Flutter那些事」,獨家放送最新Flutter、Dart和Fuchsia等技術動態,以及衆多原創,有技術深度的技術乾貨文章,還有Flutter實戰乾貨文章,等你來看,喜歡Flutter和跨平臺開發以及原生移動端開發的朋友們,趕忙來看看,歡迎你們關注。