【问题标题】:gluon android splash screen胶子安卓启动画面
【发布时间】:2016-03-22 08:13:08
【问题描述】:

我使用 Gluon Mobile 创建了小型移动应用,现在正在通过 Google Play 进行 Beta 测试。 但我意识到我的移动应用在 android 设备上的启动时间很慢(大约需要 10 多秒)。

如果我可以在加载应用程序之前添加一个 SplashScreen 那就太好了,这样用户总共不会等待 10 次,但他们觉得只有一半,因为他们在看到 SplashScreen 时得到了应用程序的响应。

在原生 android 开发中,我们只构建了 2 个 Activity(一个用于 SplashScreen,一个用于主应用程序),例如:

<activity
android:name=”.SplashScreen”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>
<activity
android:name=”.MainActivity”
android:label=”@string/app_name”
>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
</intent-filter>
</activity>

我的问题,是否有任何方法可以显示基于 JavaFX/GluOn 构建的 SplashScreen,它将同时在 andorid/ios 上运行,而不是在本机上运行。 如果我们基于 javaFX 而不是这种本机方法构建有什么缺点吗?

由于 gluon/javaFX 在移动设备上的年轻时代,获得最佳实践的理想方法并不容易。请点亮我

rgrds

【问题讨论】:

    标签: android gluon


    【解决方案1】:

    虽然启动画面可能是个好主意,但实际上使用 Gluon 插件创建的 Gluon Mobile 多视图项目允许您通过将主视图用作图像或任何其他轻量级内容的占位符来创建类似的效果显示,同时将所有重物加载到辅助视图中。

    默认情况下,主视图是在Application.start() 方法期间加载的初始视图。在用户切换到它们之前,不会加载其他视图。

    使用下面的视图,只有当用户点击浮动动作按钮时,才开始实际加载重物,但很快就会显示移动设备上的启动视图:

    public class SplashView extends View {
    
        public SplashView(String name) {
            super(name);
    
            setCenter(new ImageView(new Image(getClass().getResourceAsStream("splash.png"))));
    
            FloatingActionButton action = new FloatingActionButton(MaterialDesignIcon.ARROW_FORWARD.text, e -> 
                    MobileApplication.getInstance().switchView(GluonSplash.SECONDARY_VIEW));
            getLayers().add(action);
        }
    
        @Override
        protected void updateAppBar(AppBar appBar) {
            appBar.setVisible(false);
        }
    
    }
    

    为避免用户干预,您可以去掉操作按钮并在显示启动画面一定时间后开始加载第二个视图。

    在另一个示例中,在显示初始视图后,将开始暂停过渡。一秒钟后,它会显示标签以指示将加载新视图。同时,启动加载该视图的任务。当所有重量级视图加载完毕后,就会显示出来。

    public class SplashView extends View {
    
        public SplashView(String name) {
            super(name);
    
            Label access = new Label("Accessing...");
            access.setTranslateY(200);
            access.setVisible(false);
            setCenter(new StackPane(new ImageView(new Image(getClass().getResourceAsStream("splash.png"))), 
                                access));
    
            Task<Void> task = new Task<Void>() {
    
                @Override
                protected Void call() throws Exception {
                    Platform.runLater(() -> MobileApplication.getInstance().switchView(GluonSplash.SECONDARY_VIEW));
                    return null;
                }
            };
    
            addEventHandler(LifecycleEvent.SHOWN, e -> {
                PauseTransition pause = new PauseTransition(Duration.seconds(1));
                pause.setOnFinished(f -> {
                    access.setVisible(true);
                    new Thread(task).start();
                });
                pause.play();
            });
    
        }
    
        @Override
        protected void updateAppBar(AppBar appBar) {
            appBar.setVisible(false);
        }
    
    }
    

    【讨论】:

    • 其实我想用其他内容/浅色图片从头开始删除空白黑屏。但我会测试这种方法是否不仅会在应用程序显示前几秒钟显示,而且在加载时间的大部分时间里仍然会出现空白黑屏。希望你明白我的意思。
    • 确切地说,这个想法是使用一个非常轻量级的 Home_View,它会立即显示出来。为此,仅在需要此视图时才尝试加载与第二个视图相关的所有内容。否则,加载时间也会影响 Home/Splash 视图
    • 是的,这种方法非常有效。我遇到的唯一问题是当用户在 android 上按下后退按钮时,屏幕可以去加载启动图像。我可以避免从应用程序栏返回,但仍然无法使用 android 硬件的后退按钮(在右下角)。有什么建议/技巧来克服这个吗?提前致谢。
    • 遵循Android标准,按下返回按钮将返回上一个视图或退出应用程序。在您的情况下,我建议添加一个 first 布尔值,以在第一次运行时显示启动画面,然后修改主视图以显示正确的内容。
    【解决方案2】:

    我有点晚了,但对于未来的项目,这可能会有用:

    Github 上有一个项目正在扩展 Gluon 的功能。
    https://github.com/Ciruman/QuarkFX
    它包括:

    • 不同的视图处理方法可让您针对不同的设备尺寸和方向进行开发
    • 还包括一个启动画面(它还不能配置,但由于它是开源的,您可以根据需要快速更改它)
    • 有关更多功能,请查看其自述文件

    【讨论】:

    • 它是开源的吗? @LucaZ
    【解决方案3】:

    好的,这是旧的,但它仍然会在谷歌搜索中弹出,所以就在这里。 在插件的 4.x 版本中,可以使用 SplashView,它默认隐藏 appBar,并且可以像普通视图一样注册,仅使用名称 SPLASH_VIEW。 FXML 应如下所示:

    <?xml version="1.0" encoding="UTF-8"?>
    <?import com.gluonhq.charm.glisten.mvc.SplashView?>
    <?import javafx.scene.control.Label?>
    <?import javafx.scene.image.Image?>
    <?import javafx.scene.image.ImageView?>
    <?import javafx.scene.layout.BorderPane?>
    
    <SplashView fx:id="splash" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.shara.views.SplashPresenter">
       <center>
          <ImageView fitHeight="150.0" fitWidth="200.0" pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER">
             <image>
                <Image url="@../../../icon.png" />
             </image>
          </ImageView>
       </center>
       <bottom>
          <Label BorderPane.alignment="CENTER" />
       </bottom>
    </SplashView>
    

    那么它的控制器应该是这样的:

    import com.gluonhq.charm.down.Services;
    import com.gluonhq.charm.down.plugins.LifecycleService;
    import com.gluonhq.charm.glisten.afterburner.GluonPresenter;
    import com.gluonhq.charm.glisten.animation.FadeInTransition;
    import com.gluonhq.charm.glisten.application.MobileApplication;
    import com.gluonhq.charm.glisten.control.Alert;
    import com.gluonhq.charm.glisten.control.LifecycleEvent;
    import com.gluonhq.charm.glisten.mvc.SplashView;
    import com.shara.Shara;
    import com.shara.Network;
    import javafx.animation.PauseTransition;
    import javafx.application.Platform;
    import javafx.event.ActionEvent;
    import javafx.fxml.FXML;
    import javafx.util.Duration;
    
    /**
     *
     * @author mighty
     */
    public class SplashPresenter extends GluonPresenter<Shara> {
    
        @FXML private SplashView splash;
    
        public void initialize(){
            splash.setShowTransitionFactory(FadeInTransition::new);
            splash.setOnShown((LifecycleEvent e) -> {
                PauseTransition pause = new PauseTransition(Duration.seconds(3));
                pause.setOnFinished((ActionEvent f) -> {
                    splash.hideSplashView();
                });
                pause.play();
            });
    
        }
    }
    

    视图正常初始化,可以通过调用 hideSplashView() 进行切换。 启动视图可以正常设置样式,并且可以使用样式表。 视图可以像这样在 AppViewManager 中注册:

    public static final AppView SPLASH_VIEW = view("Splash", SplashPresenter.class, MaterialDesignIcon.PAGES);
    

    并在您的 registerViewsAndDrawer 方法中替换

    REGISTRY.getViews().forEach((view) -> {
                view.registerView(app);
        });
    

    REGISTRY.getViews().forEach((view) -> {
                if(view.getId() != "SPLASH_VIEW"){
                    view.registerView(app);
                }
            });
    

    为了确保您的启动画面不会出现在您的抽屉中。

    【讨论】:

      猜你喜欢
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      相关资源
      最近更新 更多