什麼黑科技?實現Flutter跨平臺屏幕適配

什麼黑科技?實現Flutter跨平臺屏幕適配

碼個蛋(codeegg)第 713 次推文

博客:https://www.jianshu.com/p/143fb2111f96

前言

採用flutter開發APP已經1年多了,平時開發的過程中踩過很多坑,今天想分享一個flutter應用跨平臺適配的解決方案,目的是讓你的flutter應用可以靈活高效的自動適配各種平臺,實現UI最大化複用,業務邏輯代碼在不同平臺間能夠共享。

下圖描述了flutter-adapter的整體實現方案,我們在APP的入口處設置當前APP所運行的平臺,這個平臺可以在實際使用的時候動態設置,然後對於每個widget,我們只需要實現特定平臺的樣式適配即可。個別widget在不同平臺的表現可能僅僅是部分屬性的數值不同而已,對於屬性值的垮平臺適配我們提供了一個通用的函數superObjectAdapter去解決這個問題。

什么黑科技?实现Flutter跨平台屏幕适配

不同平臺適配效果

什么黑科技?实现Flutter跨平台屏幕适配

手機豎屏

什么黑科技?实现Flutter跨平台屏幕适配

平板豎屏

什么黑科技?实现Flutter跨平台屏幕适配

平板橫屏

使用方式

flutter_adapter插件內置了3類平臺,分別是:手機(TEAdaptPlatform.phone)、pad橫屏(TEAdaptPlatform.padLandscape)、pad豎屏(TEAdaptPlatform.padPortrait)。如果你只適配部分平臺,那麼只需要對待適配的widget實現特定平臺的build函數即可,其他未適配的平臺默認會返回Phone的樣式。

使用的時候只需要在APP

的入口處採用ScreenAdaptWidget,然後設置當前APP需要適配的平臺名稱即可。

如果你需要擴展適配的平臺,對於StatelessWidget只需要實現一個繼承自FlexibleStatelessWidget的抽象類,然後實現新平臺的build函數並註冊該平臺即可;對於StatefulWidget只需要實現一個繼承自FlexibleState的抽象類,然後實現新平臺的build函數並註冊該平臺即可。

插件使用示例:

<code>ScreenAdaptWidget(
platform: TEAdaptPlatform.phone.toString,
child: 任意widget
)),/<code>

如果你的某個StatelessWidget需要適配特定平臺,只需要將該widget繼承自FlexibleStatelessWidget,然後實現特定平臺的build函數即可。

StatelessWidget適配示例:

<code>class MyStatelessPage extends FlexibleStatelessWidget {

@override
Widget buildPhone(BuildContext context) {
return Text('Phone',style: TextStyle(fontSize: 18.0),);
}

@override

Widget buildPadPortrait(BuildContext context) {
return Text('PadPortrait',style: TextStyle(fontSize: 22.0),);
}

@override
Widget buildPadLandscape(BuildContext context) {
return Text('PadLandscape',style: TextStyle(fontSize: 30.0),);
}
/<code>

StatefulWidget適配示例:

如果你的某個StatefulWidget需要適配特定平臺,只需要將該StatefulWidget對應的的State繼承自FlexibleState,然後實現特定平臺的build函數即可,例如:

<code>class MyStatefulPageState extends FlexibleState<mystatefulpage> {

@override
Widget buildPhone(BuildContext context) {
return Text('Phone',style: TextStyle(fontSize: 18.0),);
}

@override
Widget buildPadPortrait(BuildContext context) {
return Text('PadPortrait',style: TextStyle(fontSize: 22.0),);
}

@override
Widget buildPadLandscape(BuildContext context) {
return Text('PadLandscape',style: TextStyle(fontSize: 30.0),);
}
}/<mystatefulpage>/<code>

普通Widget適配示例:

如果你的某個widget僅僅需要在不同平臺中改變個別屬性的值,那麼只需要對特定的屬性值進行跨平臺適配即可,flutter_adapter提供了superObjectAdapter函數來解決屬性值的跨平臺適配難題。

<code>class MyNormalPage extends StatelessWidget {
final String textStr;

MyNormalPage(this.textStr);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('page normal'),
),
body: Column(
children: <widget>[
Container(
padding: EdgeInsets.all(10.0),
margin: EdgeInsets.only(bottom: 30.0),
width: double.infinity,
height: 100.0,
color: superObjectAdapter(context, {TEAdaptPlatform.phone.toString(): Colors.yellow, TEAdaptPlatform.padPortrait.toString(): Colors.greenAccent}),
child: Center(
child: Text(
'$textStr ${superObjectAdapter(context, {
TEAdaptPlatform.phone.toString(): "[Phone]",
TEAdaptPlatform.padPortrait.toString: "[PadPortrait]"
})}',
style: TextStyle(
fontSize: superObjectAdapter(context, {TEAdaptPlatform.phone.toString: 18.0, TEAdaptPlatform.padPortrait.toString: 38.0}),
color: Colors.black),
),
),
),
],
),

);
}
}/<widget>/<code>
什么黑科技?实现Flutter跨平台屏幕适配

屬性跨平臺適配-手機

什么黑科技?实现Flutter跨平台屏幕适配

屬性跨平臺適配-平板

擴展需要適配的平臺

插件內置的3個平臺在實際使用的過程中可能不夠用,因此我們提供了用戶自定義平臺的適配解決方案。

StatelessWidget適配新平臺:

對於StatelessWidget只需要實現一個繼承自FlexibleStatelessWidget的抽象類,然後實現新平臺的build函數,之後註冊該平臺即可。

<code>abstract class CustomFlexibleStatelessWidget extends FlexibleStatelessWidget {
@protected
Widget buildNewPlatform(BuildContext context) {
return buildPhone(context); // by default, you can return the phone's style
}

@protected
void initAdapter {
super.initAdapter;
addAdapter(Constant.newPlatform, buildNewPlatform);// register new Platform
}
}/<code>

StatelessWidget適配新平臺示例:

<code>class MyStatelessPage extends CustomFlexibleStatelessWidget {

@override
Widget buildPhone(BuildContext context) {
return Text('Phone',style: TextStyle(fontSize: 18.0),);
}

@override
Widget buildPadPortrait(BuildContext context) {
return Text('PadPortrait',style: TextStyle(fontSize: 22.0),);
}

@override
Widget buildNewPlatform(BuildContext context) {
return Text('buildNewPlatform',style: TextStyle(fontSize: 30.0),);
}
}/<code>

StatefulWidget適配新平臺:

對於StatefulWidget只需要實現一個繼承自FlexibleState的抽象類,然後實現新平臺的build函數,之後註冊該平臺即可。

<code>abstract class CustomFlexibleState extends FlexibleState {
@protected
Widget buildNewPlatform(BuildContext context) {
return buildPhone(context); // by default, you can return the phone's style
}

@protected
void initAdapter {
super.initAdapter;
addAdapter(Constant.newPlatform, buildNewPlatform);// register new Platform
}
}
/<code>

StatefulWidget適配新平臺示例:

<code>class MyStatefulPageState extends CustomFlexibleState<mystatefulpage> { 


@override
Widget buildPhone(BuildContext context) {
return Text('Phone',style: TextStyle(fontSize: 18.0),);
}

@override
Widget buildPadPortrait(BuildContext context) {
return Text('PadPortrait',style: TextStyle(fontSize: 22.0),);
}

@override
Widget buildNewPlatform(BuildContext context) {
return Text('NewPlatform',style: TextStyle(fontSize: 30.0),);
}
}/<mystatefulpage>/<code>
什么黑科技?实现Flutter跨平台屏幕适配

用戶自定義平臺

本項目已經開源,開源地址:

Flutter-adapterhttps://github.com/buaashuai/flutter_adapter

日問題:

多平臺都跨了,怎麼能缺屏幕適配?

什么黑科技?实现Flutter跨平台屏幕适配

專屬升級社區:《這件事情,我終於想明白了》


分享到:


相關文章: