preface

Why this article?

This article can be described as a personal essay on Flutter issues. Although Flutter can be easily cross-platform, it is a new project and not so comprehensive as expected. Therefore, in this article, I will track the problems encountered in the process of using Flutter, the current solutions, and keep track of them.

List of questions (continuously updated) :

  1. Flutter does not support asynchronous mapping of large volumes of text.
  2. Flutter IOS background audio playback(There is already a third party).
  3. The NestedScrollView of Flutter has sliding anomalies such as folding head and sublist.
  4. The Hero exit animation will not play properly and the original image will not be displayed if the image after the Hero jump is hidden by folding in the collapsed layout(The Master branch of Flutter has been fixed,stable version hotfix has been released)
  5. ListView does not support index redirection
  6. The value of Simulation will return Infinite
  7. HintText can’t be centered vertically?

The body of the

1. Asynchronous mapping of large amounts of text is not supported in Flutter

This is from the personal training APP. In the process of developing the reading module, I encountered such a problem:

If you want to customize text spacing, paragraph spacing, etc., then you naturally use textPainter to draw your own text. But this raises a problem: with tens of thousands of characters, mapping can take a long time. Naturally, the main process is blocked.

The first idea to solve this problem is of course to use asynchronous processing. What are the asynchronous solutions for FLUTTER?

  1. Future(including await async stuff)
  2. isoloate

According to the official document, a large number of calculation things should be put into THE Isolate, so naturally, we put textPinter mapping method into the Isolate to execute, but the execution failed: native function not found

The reason is that the UI package classes are only allowed to execute in the UI Isolate of Flutter.

This problem have no solution, end scatter flower, each return home, each look for each mother (just strange)

Solution 1: Plugin

The idea for this approach comes from the official developer’s answer:

right now you would have to write your own line-breaking logic – perhaps as a plugin. We don’t currently have any API for doing text layout in a separate isolate. @GaryQian might have some other idea about this too.

So let’s take a look at how the official Plugin is implemented.

Android_alarm_manager. In the alarmservice. Java file of the Plugin, there is a method: startBackgroundIsolate (factor detection +1)

Through reading the source code, we learned that, in fact, is to create a New FlutterNativeView, this FlutterNativeView is not responsible for rendering interface, only responsible for when the background thread to use. In the same way, we can handle asynchronous tasks that need to run on UI Isolate. (As for why creating a New FlutterNativeView can fulfill this requirement, roughly speaking, every time you create a New FlutterNativeView, you actually create some TaskRunners, including UI Taskrunners, Anyway, if you’re interested, check out the TaskRunner mechanism of Flutter.)

However, there is a third party that does this: Flutter_ISOLATE. It works just like normal ISOLATE, so the solution is very simple: Locate the code that uses Isolate and replace Isolate. Spawn with Flutterisolate. spawn. However, after testing, errors were reported in 1.10, so if you want to use this method, you should switch back to the stable branch.

Solution 2: Divide it into several small tasks (personally, I do not recommend this method, it feels uncontrollable, after all, what if the execution time of small tasks is also very long)

In this way, the result is submitted once every row is mapped, rather than after the whole mapping is completed.

Here’s a quick example:

Future(() async {
  var result;
  for (var i = 0; i < 1000000; ++i) {
    result = 'result is $i';
    await Future.delayed(Duration.zero);
  }
  print(result);
});
Copy the code

This way you don’t get stuck in the UI

Solution 3: This problem is currently being added to the milestone, and a solution should be available someday

Github.com/flutter/flu…

2. Flutter IOS background audio playback

You know, like a music player, there’s a notification showing progress, and you can play music even on your desktop

Currently only Android implementation, IOS part of the current no plan…… %

3. There are sliding anomalies such as folding head and sublist in NestedScrollView of Flutter

It took me a while to find a big guy who had solved the problem:

Juejin. Cn/post / 684490…

Extended_nested_scroll_view solves this problem, as noted here

4. If the image after the Hero jump is hidden by folding in the collapsed layout, the Hero exit animation will not play properly and the original image will not be displayed

This description may be a bit abstract, but the specific situation is described as an example:

First, put a picture on the home page, give him the Settings click jump details page, and set hero animation.

2. Set the picture to the content in the Widget of FlexibleSpaceBar of SliverAppBar, then pull up the page and fold and hide the SliverAppBar.

3. Press the back button to exit the detail page and trigger the hero closing animation.

Following these three steps, the original picture on the home page becomes blank and unclickable.

Issue:

Github.com/flutter/flu…

Github.com/flutter/flu…

So switch to the Master or dev branch (fix v.1.10.14), or lower the stable version.

5. The listView cannot be redirected by index

Here’s what I found:

Stackoverflow.com/questions/5…

Pub. Dev/packages/in…

Pub. Dev/packages/sc…

Pub. Dev/packages/fl…

The above implementation method is different, sort out the main defects, later can be used according to the actual situation:

  1. There are two methods mentioned in stackOverflow: one is to use index_list_View, which will be analyzed later. The second is gist.github.com/debuggerx01… , but some elder brother put it on the list with comments, the result is poor performance, the introduction article also explained that if not handled properly, there may indeed be performance problems.
  2. Indexed_list_view stackOverflow applies to infinite lists.
  3. scroll_to_indexThe code is a little more intrusive (That’s not really the point), secondly, there is no jump method, the scroll length seems to have no effect, so if the list is relatively large and the jump distance is also very large (such as the chapter of the biography of Mortals Xiuxian……). So the animation effect is more touching. (PS: It seems that this problem of long sliding time (Github.com/flutter/flu…) has been fixed. Although it was not mentioned in this issue, I found on V1.10.14 that the scroll animation can now slide to the target position in a very short time)
  4. Flutter_widgets is a large Google widget (but not an official widget) that meets basic requirements and has a very simple method, including jump. However, if it is placed in the NestScrollView to slide the parallax page, it will not slide the entire page, only the contents of the ScrollablePositionedList…… And if expansiontiles, on the other hand, scale the heights of items, ScrollablePositionedList will not update the heights. Instead, the index jumps based on the previous height.

We are now trying to solve the parallax sliding problem in ScrollablePositionedList, In NestScrollView, you set the PrimaryScrollController, Let the innerController manage the body slide, so using this innerController instead of the Controller of the ScrollablePositionedList solves the problem of not sliding, but then there’s a new problem. Jumping to index now causes the body to trigger a slide that collapses the SliverAppBar…………… directly How to change the position of the body in the NestScrollView when the index is moved, and only the position of the body in the NestScrollView can be changed when the index is moved manually. The current idea is to see if there is a breakthrough in the floating and pinned sliding methods of SliverAppBar. No, it’s fine now. Direct full screen display, if not, add a jump to the top button, I feel quite reasonable. (fog)

Level change this, continue to monitor set addPersistentFrameCallback way at present. I thought the performance would be poor, but after testing it, the frame didn’t change much, so it should not be a problem.

6. The ClampingScrollSimulation value will return Infinite

Take the following code for example

ClampingScrollSimulation simulation; AnimationController AnimationController; simulation = ClampingScrollSimulation( position: mTouch.dy, velocity: details.velocity.pixelsPerSecond.dy, tolerance: Tolerance.defaultTolerance, ); animationController .. addListener(() { currentState = STATE.STATE_ANIMATING; canvasKey.currentContext.findRenderObject().markNeedsPaint(); /// We need to check whether the data is valid...if(! animationController.value.isInfinite && ! animationController.value.isNaN) { currentAnimationPage.onTouchEvent(TouchEvent( TouchEvent.ACTION_MOVE, Offset(0, animationController.value))); }}).. addStatusListener((status) { switch (status) {case AnimationStatus.dismissed:
              break;
            case AnimationStatus.completed:
              currentState = STATE.STATE_IDE;
              currentAnimationPage
                  .onTouchEvent(TouchEvent(TouchEvent.ACTION_UP, Offset(0, 0)));
              currentTouchData = TouchEvent(TouchEvent.ACTION_UP, Offset(0, 0));
              break;
            case AnimationStatus.forward:
            case AnimationStatus.reverse:
              currentState = STATE.STATE_ANIMATING;
              break; }}); animationController.animateWith(simulation);Copy the code

Be reasonable, there should not be illegal data returned… Anyway, let me write it down here

7. If textField is set to hintText, it cannot be vertically centered

I really have no clue about this. Although there are many issues in flutter that have the same situation as me, it seems that setting the baseline is ok, but this does not take effect for me… And found that suffixIcon seemed to restore normal… It’s not impossible to force the solution by adding the padding, but it feels so low

So let me write that down

digression

Some of you may be confused as to why I need to measure tens of thousands of words, so here’s a simple note:

The situation of mapping thousands of words came from my intention to convert my original Android native novel reader into the implementation of Flutter (mainly to implement the simulation, scrolling and other page-turning animations and practice the canvas operation of Flutter). The basic idea of the novel reader is from this project: Ren Read.

The idea is this:

The basic function is: previous page, next page, previous chapter, next chapter, chapter within the page jump.

Since the function of switching from one chapter to the next and how many pages to jump to within the chapter should be taken into consideration, the chapter is naturally based on the unit. The page contains pages inside the chapter, and the data of the page to be displayed should be taken out from the page data of the chapter, and then drawn on the canvas.

Therefore, the cache calculation is also the content of the computed chapter, so when a new chapter is downloaded from the server, it is possible to encounter a chapter with tens of thousands of words.

May also have students said: directly according to the page cache is not on the line, only a few pages of cache each time, then certainly do not need to measure the situation of tens of thousands of words. If a user opens a new novel, jumps straight to Chapter 10, and then clicks the previous page. 2. Go to page N (n> number of cached pages).

Because of the existence of punctuation marks, full corners, special characters and other non-ordinary Chinese characters, it is impossible for us to know the contents of each page directly. Naturally, we cannot know the contents of a page before measuring the whole chapter. Therefore, to support the two situations mentioned above, it is necessary to measure the contents of the whole chapter.

Of course, maybe my idea is not the optimal solution, if there is a better solution, I hope you don’t hesitate to advise