How can i make the first screen of my flutter show up before executing native based java code that will fetch data using a java library

huangapple go评论76阅读模式
英文:

How can i make the first screen of my flutter show up before executing native based java code that will fetch data using a java library

问题

public class MainActivity extends FlutterActivity {
    private static final String CHANNEL = "samples.flutter.dev/battery";
    
    @Override
    public void configureFlutterEngine(FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
                .setMethodCallHandler(
                        (call, result) -> {
                            if (call.method.equals("getDate")) {
                                try {
                                    result.success(getReal2());
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                } catch (ExecutionException e) {
                                    e.printStackTrace();
                                }
                            } else {
                                result.notImplemented();
                            }
                        }
                );
    }

    public static List getCoffee() throws IOException {
        ArrayList coffee = new ArrayList();
        Document doc;
        doc = Jsoup.connect("https://www.bankofabyssinia.com").timeout(6000).get();
        for (int i = 0; i <= 8; i++) {
            for (int j = 2; j <= 3; j++) {
                coffee.add(doc.select("#myTable > tbody > tr:nth-child(" + i + ") > td:nth-child(" + j + ")").text());
            }
        }
        return coffee;
    }

    @TargetApi(Build.VERSION_CODES.N)
    public List getReal2() throws ExecutionException, InterruptedException {
        CompletableFuture<List> completableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                return getCoffee();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        });
        while (!completableFuture.isDone()) {
            // Waiting for the CompletableFuture to complete
        }
        List result = completableFuture.get();
        return result;
    }
}
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'Home.dart';

class Load extends StatefulWidget {
  @override
  _LoadState createState() => _LoadState();
}

class _LoadState extends State<Load> {
  static const platform = const MethodChannel('samples.flutter.dev/battery');

  void getWholeJava() async {
    try {
      final List result = await platform.invokeMethod('getDate');
      Navigator.of(context).pushReplacement(MaterialPageRoute(
        builder: (BuildContext context) => Home(
          whole: result,
        ),
      ));
    } on PlatformException catch (e) {
      print(e);
    }
  }

  @override
  void initState() {
    super.initState();
    getWholeJava();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Builder(builder: (BuildContext context) {
        return Container(
          child: Center(
            child: Column(
              children: <Widget>[
                Text(
                  'The app is loading',
                  style: TextStyle(
                    fontSize: 40.0,
                    fontWeight: FontWeight.w900,
                    color: Colors.green[900],
                  ),
                ),
              ],
            ),
          ),
        );
      }),
    );
  }
}
英文:

i was working on some project with flutter that has to fetch data from the internet i tried to get it done using dart but it was not possible so i decided to do it in java and it works the problem the native java code started executing before the loading screen shows up on the screen and it shows some white screen and after that it just goes to the homepage is there anyway that i can make my loading screen appear first and then load the data from the internet as the loading screen is showing while the user waits and push the screen to the home screen after the loading is over.
i have tried putting sleep Duration for one second so that it can render the loading screen first but it didn't work.

Here is my java code

public class MainActivity extends FlutterActivity {
private static final String CHANNEL = &quot;samples.flutter.dev/battery&quot;;
@Override
public  void configureFlutterEngine( FlutterEngine flutterEngine) {
super.configureFlutterEngine(flutterEngine);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL)
.setMethodCallHandler(
(call, result) -&gt; {
if (call.method.equals(&quot;getDate&quot;)) {
try {
result.success(getReal2());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
else {
result.notImplemented();
}
}
);
}
public static List getCoffee() throws IOException {
ArrayList coffee = new ArrayList();
Document doc;
doc= Jsoup.connect(&quot;https://www.bankofabyssinia.com&quot;).timeout(6000).get();
for(int i=0;i&lt;=8;i++) {
for (int j=2;j&lt;=3;j++){
coffee.add(doc.select(&quot; #myTable &gt; tbody &gt; tr:nth-child(&quot;+i+&quot;) &gt; td:nth-child(&quot;+j+&quot;)&quot;).text());
}
}
return coffee;
}
@TargetApi(Build.VERSION_CODES.N)
public List getReal2() throws ExecutionException, InterruptedException {
CompletableFuture&lt;List &gt; completableFuture = CompletableFuture.supplyAsync(() -&gt; {
try {
return getCoffee();
} catch (IOException e) {
e.printStackTrace();
}
return null;
});
while (!completableFuture.isDone()) {
}
List result = completableFuture.get();
return  result;
}
}

and here is my flutter code


import &#39;dart:io&#39;;
import &#39;package:flutter/material.dart&#39;;
import &#39;package:flutter/services.dart&#39;;
import &#39;Home.dart&#39;;
class Load extends StatefulWidget {
@override
_LoadState createState() =&gt; _LoadState();
}
class _LoadState extends State&lt;Load&gt; {
static const platform = const MethodChannel(&#39;samples.flutter.dev/battery&#39;);
void getWholeJava() async {
try {
final List result = await platform.invokeMethod(&#39;getDate&#39;);
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (BuildContext context) =&gt; Home(
whole: result,
)));
} on PlatformException catch (e) {
print(e);
}
}
@override
void initState() {
// TODO: implement initState
super.initState();
getWholeJava();
}
@override
Widget build(BuildContext context) {
return Scaffold(body: Builder(builder: (BuildContext context) {
return Container(
child: Center(
child: Column(
children: &lt;Widget&gt;[
Text(
&#39;The app is loading&#39;,
style: TextStyle(
fontSize: 40.0,
fontWeight: FontWeight.w900,
color: Colors.green[900]),
),
],
)),
);
}));
}
}

答案1

得分: 0

首先,Android 将默认显示其启动屏幕,由模板 Flutter Android 项目中的 launch_background.xml 管理。这意味着你需要为启动屏幕使用一个背景颜色,以便与 Android 原生启动屏幕的可绘制资源相匹配。

接下来,要实现一个启动屏幕,然后导航到一个页面,在该页面上可以运行和加载数据,你可以参考以下代码:

import 'package:async/async.dart';

class SampleSplashScreenPage extends StatefulWidget {
  @override
  _SampleSplashScreenPageState createState() => new _SampleSplashScreenPageState();
}

class _SampleSplashScreenPageState extends State<SampleSplashScreenPage> {
  @override
  void initState() {
    super.initState();

    new RestartableTimer(new Duration(seconds: 3), () async {
      await Navigator.push(context, MaterialPageRoute(builder: (_) {
        return FlutterDataLoadingPage();
      }));
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Text("Your splash screen");
  }
}

RestartableTimer 是一个类,它会启动一个计时器,并计时达到指定的持续时间。一旦达到这个持续时间,它将调用你传递给它的处理程序,这在本例中是导航逻辑,用于前往负责读取远程数据的页面。值得注意的是,该计时器不会重新启动,并且会在垃圾回收器中自动释放。

详细了解请参阅文档:
https://api.flutter.dev/flutter/package-async_async/RestartableTimer-class.html

英文:

First, android will default to its launch screen, which is managed by launch_background.xml inside the template flutter android project. This means that you will need to use a background color for the splash screen, that will work with the android native launch screen drawable.

Next, to implement a splash screen, that will then navigate to a page, where you can run and load your data, you can look at this:

import &#39;package:async/async.dart&#39;;
class SampleSplashScreenPage extends StatefulWidget {
@override
_SampleSplashScreenPageState createState() =&gt; new _SampleSplashScreenPageState();
}
class _SampleSplashScreenPageState extends State&lt;SampleSplashScreenPage&gt; {
@override
void initState() {
super.initState();
new RestartableTimer(new Duration(seconds: 3), () async {
await Navigator.push(context, MaterialPageRoute(builder: (_) {
return FlutterDataLoadingPage();
}));
});
}
@override
Widget build(BuildContext context) {
return new Text(&quot;Your splash screen&quot;);
}

RestartableTimer is a class that will begin a stopwatch, and will count up to the designated duration. Once this duration is reached, it will then invoke the handler you pass to it, which in this case is the navigation logic to the page responsible for reading the remote data. This counter by the way does not restart, and will automatically be disposed by the garbage collector.

Take a look at the documentation to learn more:
https://api.flutter.dev/flutter/package-async_async/RestartableTimer-class.html

huangapple
  • 本文由 发表于 2020年8月19日 21:50:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/63488483.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定