版權宣告:本文為博主原創文章,未經博主允許不得轉載。 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功能
按照國際慣例,先來一張效果圖鎮樓。
預設文字是“切換至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',
),
],
),
複製程式碼
我們看看效果圖如下圖所示:
上例中有一個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),
),
複製程式碼
效果如下圖所示:
同理把上述ListView的內容,對應的改成YouTube
風格的相關配置,即可輕鬆實現YouTube
風格的Logo樣式了
效果如下圖所示:
7.除此之外你還可以自定義各種型別的Logo風格
這類橫向的都是文字型別Logo很難收集,我花了很長時間才找到的,所以就照葫蘆畫瓢做了這些Logo,截圖如下所示:
【注】:這裡的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和跨平臺開發以及原生移動端開發的朋友們,趕緊來看看,歡迎大家關注。