Tips in the development of flutter (3)

Time:2020-3-15

It’s nearly 3 months since the open source of flitter ® deer. So far, we have gained 1600 + stars. Thank you for your recognition and support for this project. However, although the surface looks bright, I know there are still many nonstandard and unreasonable usage and writing methods. In order not to mislead beginners, so I almost perfect and optimize it every day during this period (it should be good now).

Today, I will continue to share some points that need attention in the development of flutter. I hope it can help you. All of the examples in this article are in my open source flitter. I hope star and fork support. If you have any questions, please issue. Attached: https://github.com/simplezhli

The first two articles in this series:

Some tips in the development of flutter

Tips in the development of flutter (2)

Tips in the development of flutter (3)

1. Multilingual configuration (internationalization)

By default, flutter is not multilingual. So no matter whether our mobile phone system environment is Chinese or not, the text of some widgets is displayed in English. For example, the common input box(TextField)Operation menu and date selection of(showDatePicker)Date of.

Tips in the development of flutter (3)

Since there is no configuration, we can add it.

  1. To add a dependency in pubspec.yaml:
  flutter_localizations:
    sdk: flutter
  1. MaterialAppMiddle configurationlocalizationsDelegatesandsupportedLocalesTwo properties.
import 'package:flutter_localizations/flutter_localizations.dart';

class MyApp extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Deer',
      home: SplashPage(),
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: [
        const Locale('zh', 'CH'),
        const Locale('en', 'US')
      ]
    );
  }
}

Here I only configure the support of Chinese and English. Other languages can be added by yourself.

  1. If it is an IOS platform, you need to configure it in the info.plist file as follows:

Tips in the development of flutter (3)

Among them:Localized resources can be mixedYes means that the application is allowed to get the language in the framework library.

If you have completed the above configuration, English will be automatically replaced with Chinese when the system is in Chinese environment.

Tips in the development of flutter (3)

In fact, if you look at the source code of fluent_localizations, you will find that it has built-in translation in multiple languages. If you think the text is inappropriate, you can also inherit the correspondingLocalizationsTo modify.Tips in the development of flutter (3)
For the detailed code of this question, see: Click to view

2. Text size

The default text configuration isThemeDataadoptTypography(platform: platform).blackMethod.

Tips in the development of flutter (3)

For example, we often useTextThe text configuration isTextThemeMediumbody1TypographyAccording to the specification of material, languages are divided into three categories:

  1. English like

Languages in most parts of western, central, Eastern Europe and Africa are usually written in Latin letters. Vietnamese is an obvious exception. Although it uses the localized form of Latin writing system, its accents may be much higher than those in Western European languages. Greek and Cyrillic writing systems are very similar to Latin.

  1. Tall

Language scripts that require extra line height to accommodate larger hieroglyphs, including South, Southeast and Middle East languages such as Arabic, Hindi, Thai and Vietnamese.

  1. Dense font

Additional line heights are required to accommodate larger pictographic language scripts, including Chinese, Japanese, and Korean.

Then for these three types of languages, the default text size will also be adjusted. For example, in the figure belowenglishLikeAnddenseComparison of (click to view the source code):

Tips in the development of flutter (3)
You can see that by default, Chinese, Japanese and Korean will be one font larger than English. For example, commonTextText configurationbody1After switching to the Chinese environment, the default size of the text changes to15.0However, in the English environment14.0

This problem is also a problem I found after I finished the multilingual configuration, because the text becomes larger, resulting in the text overflow component on individual pages.So try to specify the text size to avoid unnecessary problems.

3. Pre cache pictures

In flutter, there is a loading process for loading local pictures. For example, when you click the icon to switch the icon, it will flash for the first time. Especially for the needs like guide page, when you swipe and switch the picture from left to right, the white screen will flash.

Tips in the development of flutter (3)

The solution is simple. It uses precacheimage, which stores the image in the image cache. If the image is laterImageBoxDecationorFadeInImageUse, it will be loaded faster.

precacheImage(AssetImage("assets/logo"), context);

For the detailed code of this question, see: Click to view

4. Screen direction

The new flutter project does not limit the horizontal and vertical screens by default, so if your project does not fit the horizontal and vertical screens, you need to limit a certain direction. Let me take limiting the vertical screen as an example:

Flutter method:


void main(){
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.portraitUp,
    DeviceOrientation.portraitDown
  ]).then((_){
    runApp(MyApp());
  });
}

Native method:

Android inandroid -> app -> src-> main -> AndroidManifest.xmlActivity tags in addscreenOrientationAttribute.

    <activity
        ...
        android:screenOrientation="portrait">
    </activity>

IOS inRunner ->Info.plistDelete inUISupportedInterfaceOrientationsMediumUIInterfaceOrientationLandscapeLeftAnd.UIInterfaceOrientationLandscapeRight。 The final result is as follows:

    <key>UISupportedInterfaceOrientations</key>
    <array>
        <string>UIInterfaceOrientationPortrait</string>
    </array>

The above methods are all for the whole application. If you want some pages to be horizontal or vertical, you can only use the method of flutter to specify the direction on the corresponding page.

However, there is something wrong with the method of flutter on the IOS side. It does not force the screen to rotate (that is, the screen is currently vertical, and you specify the horizontal display of the page, which will not take effect). Therefore, students with such needs can use the plug-in “fluent orientation”.

5. Split widget

When writing the page of flutter, it is inevitable that there will be a deep level of nesting or many reusable widgets. So we usually pull out some widgets. There are two ways to extract, one is to directly extract the method (function) return. One is to extract a custom widget to use. Let me give you an example:

class _TestPageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Test"),
      ),
      body: Column(
        children: <Widget>[
          const Text("Android", style: const TextStyle(fontSize: 12.0, fontStyle: FontStyle.italic, color: Colors.blue),),
          const Text("iOS", style: const TextStyle(fontSize: 12.0, fontStyle: FontStyle.italic, color: Colors.blue),),
          const Text("Flutter", style: const TextStyle(fontSize: 12.0, fontStyle: FontStyle.italic, color: Colors.blue),),
        ],
      ),
    );
  }
}

In the above code, there are three styles that are the same, but the text is different. Let’s pull it out (or you can just pull it out of the column).

Use the first method:

  Widget _buildText(String text){
    return Text(text, style: const TextStyle(fontSize: 12.0, fontStyle: FontStyle.italic, color: Colors.blue),);
  }

Usage:

  Column(
    children: <Widget>[
      _buildText("Android"),
      _buildText("iOS"),
      _buildText("Flutter"),
    ],
  )

The second way:

class _MyText extends StatelessWidget {
  
  const _MyText(this.text, {Key key}) : super(key: key);
  
  final String text;
  
  @override
  Widget build(BuildContext context) {
    return Text(text, style: const TextStyle(fontSize: 12.0, fontStyle: FontStyle.italic, color: Colors.blue),);
  }
}

Usage:

  Column(
    children: <Widget>[
      const _MyText("Android"),
      const _MyText("iOS"),
      const _MyText("Flutter"),
    ],
  )

It looks like the first one is very convenient, but I don’t know if you have found the first oneUnable to addconstKeyword。 In fact, the problem is here. As mentioned in my previous blog, try to useconstKey to define a constant. So why is that?

Let’s take another small example:
Tips in the development of flutter (3)

I directly call the widget drawn out above and click the button every timesetStateRefresh the page and output the hashcode of the widget.
Tips in the development of flutter (3)
Can seeWidgets decorated with const keyword will not be created repeatedly。 It seems to be easy to addconstOur good habits will improve the performance of the application invisibly, such as the common color, TextStyle, and separator blocks. We can integrate them and call directly is a good way.
Tips in the development of flutter (3)

This problem is caused byProviderWhat is the difference between functions and classes to create widgets?.

The author concludes that:Never create reusable widgets in the form of method returns, always encapsulate them in statelesswidgets.Pay attention to the conclusionreusable

In the example above, our text is fixed (reusable), which allows us to add directly to the widgetconst。 In fact, the data we display is requested and not fixed, even if we pull it outStatelessWidget, and cannot be added directlyconstTo use. So if your widget can’t be reused, either of these two methods works the same.

In the above example, even if text cannot be usedconstTag, but in textTextStyleIt can be reused. It all depends on whether the granularity of your widget split is reasonable enough to avoid this performance waste as much as possible.

Of course, I would recommendStatelessWidgetThe way. As the author said, it has the following advantages:

  • Allow performance optimization(constConstructor, more granular reconstruction)
  • Hot heavy haul
  • Integrate into widget inspector(debugFillProperties
  • Key can be defined (see the solution here for the function of key)
  • Easy to use context
  • Specification that all widgets are used in the same way (always using constructors)
  • Ensures correct configuration information when switching between two different layouts (functions may reuse some previous states)

If you have written a lot of methods to create the return widget code, you can use R é mi roussselet’s functional ABCD widget to improve this problem.

6. other

  • It says pull it outStatelessWidget。 In fact, to avoid local widget calls due to refreshsetStateAs for the performance loss caused by the whole page refresh, we can extract the local refresh place asStatefulWidget。 I once wrote a page that was optimized in this way, and the time-consuming was reduced from 25ms to 6ms, so it is necessary to control the refresh range.
  • Generally not recommendedOffstageTo do the hide function, although it can hide the specified widget. But it will still create the corresponding widget, just put it in the invisible “background”. I’ve had one beforeCupertinoActivityIndicator()So it’s hidden. It turns out thatPerformanceOverlayYou can see that the page is constantly drawing… So if you need to hide widgets, you can use theisGone ? const SizedBox() : CupertinoActivityIndicator()This kind of ternary operator is handled in a way.
  • Data analysis can be placed inisolateIn order to avoid the jam caused by some devices with poor performance when parsing data. Detailed examples can be viewed in the documentation.

This piece continued to write for half a month, and finally finished! I can go to GDD at ease. It’s not easy to code. I hope you like it! Finally, I present deer’s GitHub address again. You can also support a wave!

Recommended Today

Comparison and analysis of Py = > redis and python operation redis syntax

preface R: For redis cli P: Redis for Python get ready pip install redis pool = redis.ConnectionPool(host=’39.107.86.223′, port=6379, db=1) redis = redis.Redis(connection_pool=pool) Redis. All commands I have omitted all the following commands. If there are conflicts with Python built-in functions, I will add redis Global command Dbsize (number of returned keys) R: dbsize P: print(redis.dbsize()) […]