CodenameOne:从启动画面导航到UIBuilder应用程序中的“首次使用”表单

3

我有一个棘手的问题,只在移动设备上出现,而不是模拟器,所以我需要一些专家帮助来进行故障排除。就像stateMachine在显示我的“FirstTimeSetup”表单后短暂地将我带回SplashScreen(或执行某些奇怪的回退转换)。

这是我的设置:我使用GUIBuilder构建了一个应用程序,其中包含一个SplashScreen表单,它将首先显示,然后在processBackground中发生某些网络连接后自动转换为Main表单。

这很好,但是第一次启动时(当偏好未设置时),我希望显示一个不同的表单:FirstTimeSetup。我能想到的最好的方法是:

1)在processBackground中,如果是第一次运行,则立即返回false,以便它不会转换到Main。

protected boolean processBackground(Form f) {
    if ("SplashScreen".equals(f.getName())) {
        if (Preferences.get(PREFS_FIRST_TIME_SETUP,true)){
            //return false to indicate that we should not proceed to next_form specified in property
            //we do this because postSplashScreen will trigger the load of the "FirstTimeSetup" form
            return false;
        }
        //...continue with normal app initialization if this is not the first time

2) 在postSplashScreen中,我再次检查是否第一次加载,并禁用返回命令,然后调用showForm到首次设置表单。

@Override
protected void postSplashScreen(Form f) {
    if (Preferences.get(PREFS_FIRST_TIME_SETUP, true)) {
        //disable back command for this form
        setBackCommandEnabled(false);
        showForm("FirstTimeSetup", null);
    }
}

3) 在postFirstTimeSetup方法中,我会展示一些对话框向用户解释下一步操作,进行一些网络检查以确保我们可以完成注册,然后结束该方法,以便用户可以与对话框交互并注册。在iOS或Android设备上,在此时看到幻灯片转换到“启动画面” ,然后它立即重新显示“第一次设置”表单,在用户能够与该表单交互之前,它会这样做两次。

4) 有时(不稳定),postFirstTimeSetup方法会再次执行(相同的提示用户的对话框被再次显示!)。

感觉就像在我从processBackground返回false并且postSplashScreen方法已经完成后仍然尝试执行某个“启动画面”自动转换...任何建议都将有助于消除这种奇怪的双重转换!

更新: 通过进一步调整和调查,我意识到这似乎是由Android权限对话框引起的,这就是为什么它只会在首次安装应用时发生。

在processBackground中,我进行了第一次网络调用(提示网络使用权限对话框),并访问设备参数IMEI和UUID以获取设备标识符(提示“允许访问电话”的权限)。在关闭每个对话框后,SplashScreen表单会重新进入,导致表单重新显示并进行过渡动画(我认为还重新运行了processBackground!重新执行所有我的启动画面初始化工作!)。

因此,这里是更新的问题:如何让Android权限对话框停止重新加载SpashScreen?

我尝试将触发器命令移动到initVars中,但然后我在一个空屏幕上获得了权限对话框,然后启动画面只是像我在这个视频中分享的那样快速转换了两次:youtu.be/2QpdaeigNZ8

我尝试使用callSerially()包装这两个“触发器”(引起权限的命令),以便它延迟对话框,直到至少显示SplashScreen表单,但然后表单显示,权限对话框出现,我点击“允许”,然后SplashScreen表单再次显示,然后第二个权限对话框弹出。我点击“允许”,然后又一次重新显示SplashScreen表单。

1个回答

2
解决方案是在 processBackground() 中执行您的逻辑,并且摆脱 postSplashScreen,然后在该方法末尾返回 false。
@Override
protected boolean processBackground(final Form f) {
    if ("SplashScreen".equalsIgnoreCase(f.getName())) {
        new UITimer(() -> {
            if (Preferences.get(PREFS_FIRST_TIME_SETUP, true)) {
                showForm("FirstTimeSetup", null);
            } else {
                showForm("Main", null);// or any other form you want to show
            }
        }).schedule(3000, false, f); //wait 3 seconds before proceeding
    }
    return false; //always return false at the end
}

在您的FirstTimeSetup表单的postShow()(即postFirstTimeSetup()方法),请记得将PREFS_FIRST_TIME_SETUP设置为false
Preferences.set(PREFS_FIRST_TIME_SETUP, false);

谢谢 @Diamond。我尝试了一下不使用“UITimer”,它没有转换到FirstTimeSetup表单,但弹出了postForm方法调用的对话框...我不明白为什么会这样,但是通过完全采纳你的回答,它基本上是成功的。还有一个问题:SplashScreen在转移到FirstTimeSetup表单之前仍然进行了双重“转换”。有什么想法是为什么吗? - Java-K
你能制作一个关于“双重转换”的短视频吗?不太清楚你在说什么。 - Diamond
你是否在任何地方调用了 showSplashScreen() 方法,并删除了 postSplash()beforeSplash() 方法?你是否将 SplashScreen 设置为你的 initial form 并且它有默认的下一个要显示的表单? - Diamond
我没有调用showSplashScreen(),我已经删除了postSplashScreen()并且以前也没有beforeSplashScreen()。启动画面是我的初始窗体,我仍然将默认的下一个窗体设置为Main(即使现在返回false也不会使用该下一个窗体)。 - Java-K

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接