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: ..., //內容部分),),);} }從上面可以看到先繼承dialog,在它的build函數然后widget,剩下的與正常的widget差不多。
但是注意幾點:
- 最外層需要用Scaffold包裹,否則所有默認樣式都會失效。
- 使用Scaffold后,背景是不透明的,需要再設置backgroundColor為透明的。
- dialog默認是全屏的,所以需要用Container來限制內容的大小,并用Center包裹使內容居中。同時也可以對Container添加decoration實現彈窗背景
大小動態調整的Dialog
開發中經常遇到這樣的dialog,內容變化很大,所以dialog的大小也要跟著變化,但是為了美觀又不能太大,當內容過多的時候dialog大小就不再改變,而是內容可滾動查看。
下面我們一步步實現這個dialog
Text內容可滾動
這里同時也解決Text顯示不全的問題。
我們用最簡單的dialog,內容只有文字,那么第一步要解決的就是如果文字特別多的情況下,怎么讓Text的內容可以滾動。
答案是用SingleChildScrollView,它只有一個child,作用就是如果child太大的情況下可以滾動查看。
代碼:
SingleChildScrollView(child: Text(widget.msg,style:TextStyle(color: Color(0xff919294), fontSize: 18), ),但是這里有一個問題,就是雖然能滾動了,但是Text顯示不全,現象是當Text文字內容很多的時候,最后一行看不到,而倒數第二行只能顯示一半。
這個不是SingleChildScrollView的問題,經測試,在空白頁面上單獨使用Text,高度不限,依然會出現這樣的情況,甚至Text下半部分還空白著,后面的文字依然不顯示。
注意:這個情況是發生在flutter web,在chrome上出現,在Android或ios未測試,可能是web特有的問題
經過反復嘗試,最終發現為Text設置overflow: TextOverflow.ellipsis可以解決,文字可以完整顯示出來了。
overflow的作用就是文字顯示不下時采用什么樣的處理,ellipsis就是省略,還有shape(漸變)、visible等等。這里不知道為什么設置ellipsis可以起作用,反而設置visible不行。
但是設置overflow: TextOverflow.ellipsis可以解決單獨使用Text時的問題,如果使用SingleChildScrollView嵌套到達滾動效果的話,Text只顯示一行。。。
這里我的解決方法時設置Text的maxLines: 100 這里的100只是一個較大的數,可以是1000,只有保證內容完全顯示即可。
這個解決方案并不理想,但是暫時只想到這個解決方案。最終代碼:
SingleChildScrollView(child: Text(widget.msg,overflow: TextOverflow.ellipsis,maxLines: 100,style:TextStyle(color: Color(0xff919294), fontSize: 18), ),窗口大小動態調整并限制最大高度
這里使用LimitedBox來實現高度的限制,直接上代碼:
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,目的是設置窗口的寬度,這個是固定的,而窗口的高度是動態的。
然后就遇到了第一個問題,一開始我在第二層就使用LimitedBox,如下:
但是這樣無論Container內容有多大,Container高度(甚至里面沒有任何內容)都一直是400,而我們期望的是Container高度可以隨著內容變化,而最大高度限制在400
經過嘗試,將LimitedBox放在Container里層即可,具體原因還不得而知,Flutter UI嵌套感覺問題一直很多。
最終結果就像上面一樣,只在內容部分的外層套一層LimitedBox來限制最大高度,這樣就實現了動態變化且有最大限制。
這里還要注意,在Column中我設置了mainAxisSize: MainAxisSize.min 因為默認Column是在垂直方向上是完全展開的,這樣高度就不能動態變化了,所以這里的設置讓Column垂直方向上根據內容展示即可。
在flutter中由于各種ui的嵌套和各種默認值,做一些大小動態調整的組件還是需要一些工作量,要注意一些坑。
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的Flutter入门:自定义dialog的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Flutter入门:applicatio
- 下一篇: Android录制和播放PCM数据