Author: buaashui

Blog: https://www.jianshu.com/p/143fb2111f96

preface

I have been developing my APP with Flutter for more than one year. I have experienced many difficulties in the process of development. Today, I want to share a solution for the cross-platform adaptation of Flutter application.

The following figure describes the overall implementation of the Flutter adapter. We set the platform that the APP is running on at the entrance of the APP. This platform can be dynamically set when the APP is actually used. Individual widgets may behave differently on different platforms only because of the value of some attributes. We provide a generic function superObjectAdapter to solve this problem.

Adaptation effect of different platforms

Mobile phone vertical screen

Flat vertical screen

Flat landscape

use

The Flutter_Adapter plug-in has three built-in platforms: Mobile phone (TEAdaptPlatform. Phone), landscape (TEAdaptPlatform. PadLandscape) pad, pad vertical screen (TEAdaptPlatform. PadPortrait). If you only adapt to some platforms, implement the platform-specific build function for the adapted widget, and return the Phone style for other platforms by default. To use it, just use ScreenAdaptWidget at the entrance of the APP, and then set the platform name for the current APP.

If you need to extend the platform, implement an abstract class inherited from FlexibleStatelessWidget for StatelessWidget, implement the build function for the new platform, and register the platform. All you need to do for StatefulWidget is implement an abstract class that inherits from FlexibleState, implement the build function for the new platform, and register for that platform.

Examples of plug-in usage:

ScreenAdaptWidget (platform: TEAdaptPlatform. Phone. ToString (), the child: any widget)),Copy the code

If one of your StatelessWidgets needs to be platform-specific, simply inherit the FlexibleStatelessWidget and implement the platform-specific build function.

Example StatelessWidget adaptation:

class MyStatelessPage extends FlexibleStatelessWidget { @override Widget buildPhone(BuildContext context) { return The 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)); }Copy the code

Copy the code

Examples of StatefulWidget adaptation:

If you have a StatefulWidget that needs to be platform-specific, simply inherit the State of the StatefulWidget from FlexibleState and implement the platform-specific build function, for example:

class MyStatefulPageState extends FlexibleState<MyStatefulPage> { @override Widget buildPhone(BuildContext context) { Return the 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)); }}Copy the code

Copy the code

Examples of common Widget adaptation:

If one of your widgets only needs to change the value of individual attributes on different platforms, then you only need to cross-adapt specific attribute values. Flutter_adapter provides the superObjectAdapter function to solve the cross-platform adaptation problem.

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. The toString () : }), (), (), (), (), (), (), (); }}Copy the code

Properties cross-platform adaptation – mobile

Properties cross-platform adaptation – tablet

The extension needs to adapt to the platform

The three built-in platforms of the plug-in may not be enough in actual use, so we provide a customized platform adaptation solution.

StatelessWidget for new platforms:

All you need to do for StatelessWidget is implement an abstract class that inherits from the FlexibleStatelessWidget, implement the build function for the new platform, and then register the platform.

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 }}Copy the code

Example StatelessWidget for a new platform:

class MyStatelessPage extends CustomFlexibleStatelessWidget { @override Widget buildPhone(BuildContext context) { return The 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)); }}Copy the code

StatefulWidget for new platforms:

All you need to do for StatefulWidget is implement an abstract class that inherits From FlexibleState, implement the build function for the new platform, and then register that platform.

abstract class CustomFlexibleState<T extends StatefulWidget> extends FlexibleState<T> { @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 }}Copy the code
Copy the code

Examples of StatefulWidget for a new platform:

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)); }}Copy the code

User-defined platform

This project has been open source, open source address:

Flutter-adapter(https://github.com/buaashuai/flutter_adapter

Recent Articles:

  • “What kind of garbage are you?” (below)

  • Android layout optimization, look at these 3 points is enough!

  • Guo God’s heart practice: deep section RecyclerView

Question of the day:

Multiple platforms are crossed, how can you lack screen adaptation?

Exclusive upgrade community: I Finally Figured it out