Flutter入门:自定义dialog
自定義dialog
先來看看一個示例
class ExamResultDialog extends Dialog{...@overrideWidget build(BuildContext context) {return new ExamResultDialogContent(entity, listener);} }class ExamResultDialogContent extends StatefulWidget{...@overrideState<StatefulWidget> createState() {...return _ExamResultDialogContent();}... }class _ExamResultDialogContent extends State<ExamResultDialogContent>{@overrideWidget build(BuildContext context) {return Scaffold(backgroundColor: Colors.transparent,body: Center(child: Container(decoration: BoxDecoration(color: Colors.white,borderRadius: BorderRadius.all(Radius.circular(20)),),width: 752,height: 426,child: ..., //內(nèi)容部分),),);} }從上面可以看到先繼承dialog,在它的build函數(shù)然后widget,剩下的與正常的widget差不多。
但是注意幾點:
- 最外層需要用Scaffold包裹,否則所有默認(rèn)樣式都會失效。
- 使用Scaffold后,背景是不透明的,需要再設(shè)置backgroundColor為透明的。
- dialog默認(rèn)是全屏的,所以需要用Container來限制內(nèi)容的大小,并用Center包裹使內(nèi)容居中。同時也可以對Container添加decoration實現(xiàn)彈窗背景
大小動態(tài)調(diào)整的Dialog
開發(fā)中經(jīng)常遇到這樣的dialog,內(nèi)容變化很大,所以dialog的大小也要跟著變化,但是為了美觀又不能太大,當(dāng)內(nèi)容過多的時候dialog大小就不再改變,而是內(nèi)容可滾動查看。
下面我們一步步實現(xiàn)這個dialog
Text內(nèi)容可滾動
這里同時也解決Text顯示不全的問題。
我們用最簡單的dialog,內(nèi)容只有文字,那么第一步要解決的就是如果文字特別多的情況下,怎么讓Text的內(nèi)容可以滾動。
答案是用SingleChildScrollView,它只有一個child,作用就是如果child太大的情況下可以滾動查看。
代碼:
SingleChildScrollView(child: Text(widget.msg,style:TextStyle(color: Color(0xff919294), fontSize: 18), ),但是這里有一個問題,就是雖然能滾動了,但是Text顯示不全,現(xiàn)象是當(dāng)Text文字內(nèi)容很多的時候,最后一行看不到,而倒數(shù)第二行只能顯示一半。
這個不是SingleChildScrollView的問題,經(jīng)測試,在空白頁面上單獨使用Text,高度不限,依然會出現(xiàn)這樣的情況,甚至Text下半部分還空白著,后面的文字依然不顯示。
注意:這個情況是發(fā)生在flutter web,在chrome上出現(xiàn),在Android或ios未測試,可能是web特有的問題
經(jīng)過反復(fù)嘗試,最終發(fā)現(xiàn)為Text設(shè)置overflow: TextOverflow.ellipsis可以解決,文字可以完整顯示出來了。
overflow的作用就是文字顯示不下時采用什么樣的處理,ellipsis就是省略,還有shape(漸變)、visible等等。這里不知道為什么設(shè)置ellipsis可以起作用,反而設(shè)置visible不行。
但是設(shè)置overflow: TextOverflow.ellipsis可以解決單獨使用Text時的問題,如果使用SingleChildScrollView嵌套到達(dá)滾動效果的話,Text只顯示一行。。。
這里我的解決方法時設(shè)置Text的maxLines: 100 這里的100只是一個較大的數(shù),可以是1000,只有保證內(nèi)容完全顯示即可。
這個解決方案并不理想,但是暫時只想到這個解決方案。最終代碼:
SingleChildScrollView(child: Text(widget.msg,overflow: TextOverflow.ellipsis,maxLines: 100,style:TextStyle(color: Color(0xff919294), fontSize: 18), ),窗口大小動態(tài)調(diào)整并限制最大高度
這里使用LimitedBox來實現(xiàn)高度的限制,直接上代碼:
SizedBox(width: 400,child: Container(child: Stack(children: [Column(mainAxisSize: MainAxisSize.min,children: [Container(child: Text("公告",style: TextStyle(color: Color(0xff212223), fontSize: 24),),width: double.infinity,alignment: Alignment.center,margin: EdgeInsets.only(top: 10, bottom: 20),),LimitedBox(maxHeight: 400,child: SingleChildScrollView(child: Text(widget.msg,overflow: TextOverflow.ellipsis,maxLines: 100,style:TextStyle(color: Color(0xff919294), fontSize: 18),),padding: EdgeInsets.only(left: 20, right: 20),),),Padding(padding: EdgeInsets.all(10))],),GestureDetector(child: Container(child: Image.asset(R.assetsAlertClose,width: 20,height: 20,),padding: EdgeInsets.all(10),alignment: Alignment.topRight,),onTap: () {Navigator.of(context).pop();},)],),decoration: ShapeDecoration(color: Colors.white,shape: RoundedRectangleBorder(side: BorderSide(color: Colors.transparent),borderRadius: BorderRadius.all(Radius.circular(13),),),),));最外層是一個SizedBox,目的是設(shè)置窗口的寬度,這個是固定的,而窗口的高度是動態(tài)的。
然后就遇到了第一個問題,一開始我在第二層就使用LimitedBox,如下:
但是這樣無論Container內(nèi)容有多大,Container高度(甚至里面沒有任何內(nèi)容)都一直是400,而我們期望的是Container高度可以隨著內(nèi)容變化,而最大高度限制在400
經(jīng)過嘗試,將LimitedBox放在Container里層即可,具體原因還不得而知,Flutter UI嵌套感覺問題一直很多。
最終結(jié)果就像上面一樣,只在內(nèi)容部分的外層套一層LimitedBox來限制最大高度,這樣就實現(xiàn)了動態(tài)變化且有最大限制。
這里還要注意,在Column中我設(shè)置了mainAxisSize: MainAxisSize.min 因為默認(rèn)Column是在垂直方向上是完全展開的,這樣高度就不能動態(tài)變化了,所以這里的設(shè)置讓Column垂直方向上根據(jù)內(nèi)容展示即可。
在flutter中由于各種ui的嵌套和各種默認(rèn)值,做一些大小動態(tài)調(diào)整的組件還是需要一些工作量,要注意一些坑。
超強干貨來襲 云風(fēng)專訪:近40年碼齡,通宵達(dá)旦的技術(shù)人生總結(jié)
以上是生活随笔為你收集整理的Flutter入门:自定义dialog的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flutter入门:applicatio
- 下一篇: Android录制和播放PCM数据