在Flutter中我們在 Widget 實現(xiàn)一些手勢交互通常會使用 GestureDetector 裝飾器來實現(xiàn),但是默認(rèn)情況下, widget 是支持多點觸控,但是在一些特定需求下,我們不需要多點觸控的操作,或者多點觸控反而給一些功能帶來麻煩,而且比較不方便的是,多點觸控?zé)o法通過操作 widget 或者 GestureDetector 來屏蔽掉。查閱了官方文檔發(fā)現(xiàn)的這個玩意: RawGestureDetector
創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站建設(shè)、成都網(wǎng)站制作與策劃設(shè)計,集安網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:集安等地區(qū)。集安做網(wǎng)站價格咨詢:13518219792
大概意思是:一個小部件,用于檢測由給定手勢工廠描述的手勢。對于常用手勢,請使用GestureRecognizer。 RawGestureDetector主要在開發(fā)自己的手勢識別器時很有用。
例如:
我們可以通過RawGestureDetector來自定義手勢。
有時,你可能需要禁用多點觸摸或在Flutter應(yīng)用程序中點擊小部件。 例如,有一個列表,并且一次只能單擊其中一項。 您不希望用戶同時用三個手指點擊或觸摸并立即選擇三個項?;旧?,您要防止用戶多次點擊或多點觸摸。
我們先創(chuàng)建一個簡單的頁面,頁面加載一個 ListView.builder() ,
這個列表上的cell都支持多點觸控,效果圖:
【圖】
Flutter允許在 GestureRecognizer 基類的幫助下創(chuàng)建自定義手勢識別器小部件。 該類已經(jīng)有兩個抽象的實現(xiàn),可以實現(xiàn)多次輕擊和單次輕擊手勢。
首先創(chuàng)建一個自定義窗口小部件,以使其子窗口小部件只能具有單一觸摸手勢。
在 build() 方法中,我們將返回僅支持單點觸摸手勢的手勢檢測器小部件。 因此,我們?yōu)榇藙?chuàng)建另一個名為 _SingleTouchRecognizer 的類
現(xiàn)在我們回到我們的 SingleTouchRecognizerWidget 中,通過 RawGestureDetector 裝飾器來定義我們剛才創(chuàng)建的單擊手勢檢測器:
現(xiàn)在, build() 方法返回了一個 RawGestureDetector ,該 RawGestureDetector 處理 _SingleTouchRecognizer 類中的手勢。接下來,我們需要在識別器類中實現(xiàn)這些方法。我們首先覆蓋 GestureRecognizer 的 addAllowedPointer 方法。
在這里, startTrackingPointer 方法注冊了將由識別器處理的相關(guān)事件。 然后, resolve() 負(fù)責(zé)確保是否允許繼續(xù)進行觸摸事件。
如果我們傳入 GestureDisposition.rejected ,則當(dāng)前的觸摸事件無法處理。 因此,此觸摸事件將被傳遞并允許其繼續(xù)。 但是,如果傳遞了 GestureDisposition.accepted ,則將解析觸摸事件,并且不會再調(diào)用其他事件。
通過handleEvent函數(shù)重置控制變量_p的值。
這樣就完成了_SingleTouchRecognizer類的實現(xiàn)。
現(xiàn)在,只需要將該 Widget 包裹在想要支持單點觸控的 widget 外層即可。
參考文獻(xiàn):
disable-multi-touch-on-a-widget-in-flutter
api.flutter.dev
在編寫幾個 Flutter 項目后,發(fā)現(xiàn) Flutter 的強大之處在于業(yè)務(wù)中所有用到的控件以及場景都有對應(yīng)的處理方案;而 Dart 語言也與 Java 、 Kotlin 類似,所以對 Android 開發(fā)者來說門檻非常低;特意記錄一下常用的控件及其使用:
StatelessWidget 不需要額外的創(chuàng)建 State
StatefulWidget 創(chuàng)建 State 類,并可以在其中保存一些狀態(tài)
only 可以單獨設(shè)置每個方向的內(nèi)邊距
類似于 LinearLayout 中的 orientation 設(shè)置為 vertical , mainAxisAlignment 表示豎向的一個對齊方式, crossAxisAlignment 表示橫向的對齊方式
與 Column 相反,主軸是橫向,對齊方式類似, crossAxisAlignment 表示豎向的對齊方式
類似 SizedBox ,一個容器,但是主要功能是有一個 decoration —— 裝飾器,作用是繪制背景,或者使用 item 中的陰影
棧,先入后出,類似于 Android 上的 FrameLayout
通常配合 Stack 使用,固定顯示在某一個位置
配合多 child 使用,會填充剩余的空間
Image 功能強大,使用不同的方法可以加載不同來源的圖片
看到這些方法,突然覺得 Flutter 太香了,而且 Image 可以配置 clip 等裁剪出不同形狀的圖片,無論是圓形還是五角星都不在話下,然而 Android 要實現(xiàn)不規(guī)則的形狀,可是要下不少功夫的。
名字和 Android 的一模一樣,但是用法卻比 Android 的簡單很多:
主要就是 itemCount 與 itemBuilder ,其余就是配置樣式, itemBuilder 需要返回一個 widget ,當(dāng)然了,每個 ListView 都有其對應(yīng)的 item ,在里面的方法中編寫 widget 即可
與 ListView 類似,但是需要有一個 delegate 類,作用是設(shè)置有多少列,每一列之間的間距是多少
GridView 沒有 build , children 表示所有的子 view
最常用的控件之一,有非常多的樣式, Flutter 中通常是使用裝飾器來處理控件的,如背景使用 BoxDecoration , TextFiled 使用 InputDecoration ; 使用如下
源碼分析:
分析源碼可得,TextField 是有狀態(tài) StatefulWidget,有豐富的屬性,自定義化較高,實踐中需要合理利用各種回調(diào);
1、光標(biāo)的相關(guān)屬性;cursorColor 為光標(biāo)顏色,cursorWidth 為光標(biāo)寬度,cursorRadius 為光標(biāo)圓角;其中 Radius 提供了 circle 圓角和 elliptical 非圓角兩種;
2、textAlign 為文字起始位置,可根據(jù)業(yè)務(wù)光標(biāo)居左/居右/居中等;注意只是文字開始方向;textDirection 問文字內(nèi)容方向,從左向右或從右向左;
3、maxLength 為字符長度,設(shè)置時默認(rèn)是展示一行,且右下角有編輯長度與整體長度對比;與 maxLengthEnforced 配合,maxLengthEnforced 為 true 時達(dá)到最大字符長度后不可編輯;為 false 時可繼續(xù)編輯展示有差別;
4、設(shè)置 maxLength 之后右下角默認(rèn)有字符計數(shù)器,設(shè)置 TextField.noMaxLength 即可只展示輸入字符數(shù);
5、maxLines 為允許展現(xiàn)的最大行數(shù),在使用 maxLength 時內(nèi)容超過一行不會自動換行,因為默認(rèn) maxLines=1,此時設(shè)置為 null 或固定展示行數(shù)即可自動換行;區(qū)別在于 null 會展示多行,而 maxLines 最多只展示到設(shè)置行數(shù);
6、obscureText 是否隱藏編輯內(nèi)容,常見的密碼格式;
7、enableInteractiveSelection 長按是否出現(xiàn)【剪切/復(fù)制/粘貼】菜單;不可為空;
8、keyboardAppearance 為鍵盤亮度,包括 Brightness.dark/light 兩種,但僅限于 iOS 設(shè)備;
9、textCapitalization 文字大小寫;理論上 sentences 為每句話第一個字母大寫;characters為每個字母大寫;words 為每個單詞首字母大寫;但該屬性僅限于 text keybord,和尚在本地更換多種方式并未實現(xiàn),有待研究;
10、keyboardType 為鍵盤類型,和尚理解整體分為數(shù)字鍵盤和字母鍵盤等;根據(jù)設(shè)置的鍵盤類型,鍵盤會有差別;
a. 數(shù)字鍵盤
--1-- datetime 鍵盤上可隨時訪問 : 和 /;
--2-- phone 鍵盤上可隨時訪問 # 和 *;
--3-- number 鍵盤上可隨時訪問 + - * /
b. 字母鍵盤
--1-- emailAddress 鍵盤上可隨時訪問 @ 和 .;
--2-- url 鍵盤上可隨時訪問 / 和 .;
--3-- multiline 適用于多行文本換行;
--4-- text 默認(rèn)字母鍵盤;
11、textInputAction 通常為鍵盤右下角操作類型,類型眾多,建議多多嘗試;
12、autofocus 是否自動獲取焦點,進入頁面優(yōu)先獲取焦點,并彈出鍵盤,若頁面中有多個 TextField 設(shè)置 autofocus 為 true 則優(yōu)先獲取第一個焦點;
13、focusNode 手動獲取焦點,可配合鍵盤輸入等減少用戶操作次數(shù),直接獲取下一個 TextField 焦點;
14、enabled 設(shè)為 false 之后 TextField 為不可編輯狀態(tài);
15、decoration 為邊框修飾,可以借此來調(diào)整 TextField 展示效果;可以設(shè)置前置圖標(biāo),后置圖片,邊框?qū)傩?,?nèi)容屬性等,會在后續(xù)集中嘗試;若要完全刪除裝飾,將 decoration 設(shè)置為空即可;
16、inputFormatters 為格式驗證,例如原生 Android 中通常會限制輸入手機號或其他特殊字符,在 Flutter 中也可以借此來進行格式限制,包括正則表達(dá)式;使用時需要引入 package:flutter/services.dart;
a. LengthLimitingTextInputFormatter 限制最長字符;
b. WhitelistingTextInputFormatter 僅允許輸入白名單中字符;如 digitsOnly 僅支持?jǐn)?shù)字 [0-9];
c. BlacklistingTextInputFormatter 防止輸入黑名單中字符;如 singleLineFormatter 強制輸入單行;
分析源碼 RegExp("[/]") 可以設(shè)置正則表達(dá)式;
17、onChanged 文本內(nèi)容變更時回調(diào),可實時監(jiān)聽 TextField 輸入內(nèi)容;
18、controller 文本控制器,監(jiān)聽輸入內(nèi)容回調(diào);
19、onTap 點擊 TextField時回調(diào);
20、onEditingComplete 在提交內(nèi)容時回調(diào),通常是點擊回車按鍵時回調(diào);
21、onSubmit 在提交時回調(diào),不可與 onEditingComplete 同時使用,區(qū)別在于 onSubmit 是帶返回值的回調(diào);
問題小結(jié):
當(dāng) TextField 設(shè)置 enableInteractiveSelection 屬性后長按會出現(xiàn)菜單,默認(rèn)為英文,可通過設(shè)置 Flutter 國際化來處理;
(1)在 pubspec.yaml 中集成 flutter_localizations;
2)在 MaterialApp 中設(shè)置本地化代理和支持的語言類型;
(1)將 maxLength 設(shè)置為 null 僅使用 LengthLimitingTextInputFormatter 限制最長字符;
(2)設(shè)置 InputDecoration 中 decoration 屬性為空;但是底部有空余,只是隱藏而并非消失;
DecoratedBox可以在其子組件繪制前(或后)繪制一些裝飾(Decoration),如背景、邊框、漸變等。
DecoratedBox定義如下:
我們通常會直接使用BoxDecoration類,它是一個Decoration的子類,實現(xiàn)了常用的裝飾元素的繪制。
圓形頭像
圓角頭像
對于初學(xué)flutter的朋友來說,要知道,flutter的UI萬物皆Widget。
flutter所寫的頁面的結(jié)構(gòu)可以被看成套娃,一層套一層,一層套一層,一層套一層。。。。。。
Flutter Widget采用現(xiàn)代響應(yīng)式框架構(gòu)建,這是從 React 中獲得的靈感,中心思想是用widget構(gòu)建你的UI。 Widget描述了他們的視圖在給定其當(dāng)前配置和狀態(tài)時應(yīng)該看起來像什么。當(dāng)widget的狀態(tài)發(fā)生變化時,widget會重新構(gòu)建UI,F(xiàn)lutter會對比前后變化的不同, 以確定底層渲染樹從一個狀態(tài)轉(zhuǎn)換到下一個狀態(tài)所需的最小更改。
Text : 該 widget 可讓創(chuàng)建一個帶格式的文本。
Row 、 Column : 這些具有彈性空間的布局類Widget可讓您在水平( Row )和垂直( Column )方向上創(chuàng)建靈活的布局。
Stack :取代線性布局 (和Android中的LinearLayout相似),Stack允許子 widget 堆疊, 你可以使用 Positioned 來定位他們相對于 Stack 的上下左右四條邊的位置。
Container : Container 可讓您創(chuàng)建矩形視覺元素。 您可以為 Container 裝飾一個 BoxDecoration , 如 background、一個邊框、或者一個陰影。 Container 也可以具有邊距(margins)、填充(padding)和應(yīng)用于其大小的約束(constraints)。另外, Container 可以使用矩陣在三維空間中對其進行變換。
具體的演示見我另外的博客
有一部分Widget都有一個 child 屬性,用于容納唯一的子Widget。
例如:Container、Center、Padding、Align等Widget。
還有一部分Widget允許存在多個子Widget,用 children 作為屬性。
例如:Row、Column、Stack等Widget。
在StatefulWidget調(diào)用createState之后,框架將新的狀態(tài)插入樹種,然后調(diào)用狀態(tài)對象的initState。子類化State可以重寫initState,以完成僅需要一次執(zhí)行的工作。當(dāng)然在initState的實現(xiàn)中需要調(diào)用super.initState
當(dāng)一個狀態(tài)對象不再需要時,框架調(diào)用狀態(tài)對象的dispose。也可以通過覆蓋dispose方法來執(zhí)行清理工作。
OVER~