简体   繁体   English

Animation xxhdpi 上的“重影” Android javafxports 应用程序

[英]Animation “ghosting” on xxhdpi Android javafxports application

I've written a small javafx app that animates a square moving from the top-left corner to bottom-right.我编写了一个小型 javafx 应用程序,该应用程序动画一个正方形从左上角移动到右下角。 It then reverses the animation and runs it continuously.然后它反转 animation 并连续运行它。 On my pixel 4 (xxhdpi) the square leaves behind a trail of edges on the return trip.在我的像素 4 (xxhdpi) 上,正方形在回程中留下了一条边线。 This does not happen on on my Nexus 7 2013 (xhdpi) or on my desktop.这不会发生在我的 Nexus 7 2013 (xhdpi) 或我的桌面上。

Tried both the gluon plugin and also the gluon-vm plugin.尝试了 gluon 插件和 gluon-vm 插件。

Seems related to screen pixel density.似乎与屏幕像素密度有关。 . . . . how do you prevent the ghosting artifacts on dense screens?您如何防止密集屏幕上的重影伪影? Image and code below.图片和代码如下。

Pixel 4 screenshot:像素 4 截图:

Nexus 2013 Screenshot: Nexus 2013 截图:

And the app:和应用程序:

public class StockJavaFx extends Application {
    @Override
    public void start(Stage primaryStage) {
        Dimension2D dimension = Services.get(DisplayService.class)
                .map(DisplayService::getDefaultDimensions)
                .orElseThrow(() -> new NullPointerException("DisplayService"));

        Rectangle rectangle = new Rectangle(75, 75);

        Pane container = new Pane();
        container.getChildren().add(new Rectangle(dimension.getWidth(), dimension.getHeight(), Color.DARKSLATEGRAY));
        container.getChildren().add(rectangle);

        Scene scene = new Scene(container);

        primaryStage.setScene(scene);

        TranslateTransition tt = new TranslateTransition(Duration.millis(750), rectangle);
        tt.setFromX(0);
        tt.setToX(dimension.getWidth() - 75);
        tt.setFromY(0);
        tt.setToY(dimension.getHeight() - 75);
        tt.setCycleCount(Animation.INDEFINITE);
        tt.setAutoReverse(true);

        FillTransition ft = new FillTransition(Duration.millis(750), rectangle);
        ft.setFromValue(Color.ORANGERED);
        ft.setToValue(Color.CADETBLUE);
        ft.setCycleCount(Animation.INDEFINITE);
        ft.setAutoReverse(true);

        tt.play();
        ft.play();

        primaryStage.show();
    }
}

The old Gluon jfxmobile plugin is more or less EOL, and it's being replaced by the new Gluon Client plugin.jfxmobile插件或多或少是 EOL,它正在被新的 Gluon Client 插件所取代。 More details can be found here and here .更多细节可以在这里这里找到。 Detailed documentation can be found here .详细的文档可以在这里找到。

This is how you can try creating an Android app that will solve the "ghosting" issue, with some extra "small" benefits, like using Java and JavaFX 11+, GraalVM, and getting a much more performant app.这就是您可以尝试创建一个 Android 应用程序的方法,该应用程序将解决“重影”问题,并具有一些额外的“小”好处,例如使用 Java 和 Z47A34A9D6CE8F6VMECB9778811+Graal 以及获得更多性能。 Note that the client plugin for Android is still under heavy development and it's not ready for production yet.请注意,Android 的客户端插件仍在大力开发中,尚未准备好投入生产。

Before you get started, please check that you follow the prerequisites here :在开始之前,请检查您是否遵循此处的先决条件:

  • Use a Linux machine使用 Linux 机器
  • Download and extract this version of GraalVM.下载并解压此版本的 GraalVM。
  • Set GRAALVM_HOME environment variable to the GraalVM installation directory, like:GRAALVM_HOME环境变量设置为 GraalVM 安装目录,如:

     export GRAALVM_HOME=/opt/graalvm-svm-linux-20.1.0-ea+28
  • Use Java 11, or set export JAVA_HOME=$GRAALVM_HOME使用 Java 11,或设置export JAVA_HOME=$GRAALVM_HOME

You can modify one of the existing samples, like HelloGluon .您可以修改现有示例之一,例如HelloGluon

You can modify the pom to use the latest versions like:您可以修改 pom 以使用最新版本,例如:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.gluonhq.hello</groupId>
    <artifactId>hellogluon</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>hellogluon</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.release>11</maven.compiler.release>
        <javafx.version>14.0.1</javafx.version>
        <attach.version>4.0.7</attach.version>
        <client.plugin.version>0.1.22</client.plugin.version>
        <mainClassName>com.gluonhq.hello.HelloGluon</mainClassName>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-controls</artifactId>
            <version>${javafx.version}</version>
        </dependency>
        <dependency>
            <groupId>com.gluonhq</groupId>
            <artifactId>charm-glisten</artifactId>
            <version>6.0.4</version>
        </dependency>
        <dependency>
            <groupId>com.gluonhq.attach</groupId>
            <artifactId>display</artifactId>
            <version>${attach.version}</version>
        </dependency>
        <dependency>
            <groupId>com.gluonhq.attach</groupId>
            <artifactId>lifecycle</artifactId>
            <version>${attach.version}</version>
        </dependency>
        <dependency>
            <groupId>com.gluonhq.attach</groupId>
            <artifactId>statusbar</artifactId>
            <version>${attach.version}</version>
        </dependency>
        <dependency>
            <groupId>com.gluonhq.attach</groupId>
            <artifactId>storage</artifactId>
            <version>${attach.version}</version>
        </dependency>
        <dependency>
            <groupId>com.gluonhq.attach</groupId>
            <artifactId>util</artifactId>
            <version>${attach.version}</version>
        </dependency>
    </dependencies>

    <repositories>
        <repository>
            <id>Gluon</id>
            <url>https://nexus.gluonhq.com/nexus/content/repositories/releases</url>
        </repository>
    </repositories>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <release>${maven.compiler.release}</release>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.4</version>
                <configuration>
                    <mainClass>${mainClassName}</mainClass>
                </configuration>
            </plugin>

            <plugin>
                <groupId>com.gluonhq</groupId>
                <artifactId>client-maven-plugin</artifactId>
                <version>${client.plugin.version}</version>
                <configuration>
                    <target>${client.target}</target>
                    <attachList>
                        <list>display</list>
                        <list>lifecycle</list>
                        <list>statusbar</list>
                        <list>storage</list>
                    </attachList>
                    <mainClass>${mainClassName}</mainClass>
                </configuration>
            </plugin>
        </plugins>

    <profiles>
        <profile>
            <id>desktop</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <client.target>host</client.target>
            </properties>
            <dependencies>
                <dependency>
                    <groupId>com.gluonhq.attach</groupId>
                    <artifactId>display</artifactId>
                    <version>${attach.version}</version>
                    <classifier>desktop</classifier>
                    <scope>runtime</scope>
                </dependency>
                <dependency>
                    <groupId>com.gluonhq.attach</groupId>
                    <artifactId>lifecycle</artifactId>
                    <version>${attach.version}</version>
                    <classifier>desktop</classifier>
                    <scope>runtime</scope>
                </dependency>
                <dependency>
                    <groupId>com.gluonhq.attach</groupId>
                    <artifactId>storage</artifactId>
                    <version>${attach.version}</version>
                    <classifier>desktop</classifier>
                    <scope>runtime</scope>
                </dependency>
            </dependencies>
        </profile>
        <profile>
            <id>ios</id>
            <properties>
                <client.target>ios</client.target>
            </properties>
        </profile>
        <profile>
            <id>android</id>
            <properties>
                <client.target>android</client.target>
            </properties>
        </profile>
    </profiles>
    </build>
</project>

Now you can modify the main view to add your transition:现在您可以修改主视图以添加您的过渡:

public class HelloGluon extends MobileApplication {

    @Override
    public void init() {
        addViewFactory(HOME_VIEW, () -> {
            Rectangle rectangle = new Rectangle(75, 75, Color.DARKSLATEGRAY);
            Pane container = new Pane(rectangle);
            container.setStyle("-fx-background-color: darkslategray");

            return new View(container) {
                @Override
                protected void updateAppBar(AppBar appBar) {
                    appBar.setNavIcon(MaterialDesignIcon.MENU.button(e -> System.out.println("Menu")));
                    appBar.setTitleText("Gluon Mobile");
                    appBar.getActionItems().add(MaterialDesignIcon.PLAY_ARROW.button(e -> {
                        TranslateTransition tt = new TranslateTransition(Duration.millis(750), rectangle);
                        tt.setFromX(0);
                        tt.setToX(getWidth() - 75);
                        tt.setFromY(0);
                        tt.setToY(getHeight() - 75);
                        tt.setCycleCount(Animation.INDEFINITE);
                        tt.setAutoReverse(true);

                        FillTransition ft = new FillTransition(Duration.millis(750), rectangle);
                        ft.setFromValue(Color.ORANGERED);
                        ft.setToValue(Color.CADETBLUE);
                        ft.setCycleCount(Animation.INDEFINITE);
                        ft.setAutoReverse(true);
                        tt.play();
                        ft.play();
                    }));
                }
            };
        });
    }

    @Override
    public void postInit(Scene scene) {
        Swatch.TEAL.assignTo(scene);
        scene.getStylesheets().add(HelloGluon.class.getResource("styles.css").toExternalForm());

        if (Platform.isDesktop()) {
            Dimension2D dimension2D = DisplayService.create()
                    .map(DisplayService::getDefaultDimensions)
                    .orElse(new Dimension2D(640, 480));
            scene.getWindow().setWidth(dimension2D.getWidth());
            scene.getWindow().setHeight(dimension2D.getHeight());
        }
    }

    public static void main(String[] args) {
        launch();
    }

}

You can now run with your regular JDK on your machine:您现在可以在您的机器上使用常规 JDK 运行:

mvn clean javafx:run

and verify that works fine.并验证它工作正常。

If that is the case, you can now create a native image with GraalVM, also on your machine:如果是这种情况,您现在可以在您的机器上使用 GraalVM 创建本机映像:

mvn clean client:build

This is a lengthy process, that requires usually 16 GB RAM, and a few minutes.这是一个漫长的过程,通常需要 16 GB RAM 和几分钟。

Once finished successfully, you can run it:成功完成后,您可以运行它:

mvn client:run

It should work as expected:它应该按预期工作:

Finally, you can try to build an Android native image:最后,您可以尝试构建一个 Android 原生镜像:

mvn -Pandroid client:build

When finished, create the apk:完成后,创建 apk:

mvn -Pandroid client:package

It will create an apk under target/client/aarch64-android/gvm/apk/bin/hellogluon.apk .它将在target/client/aarch64-android/gvm/apk/bin/hellogluon.apk下创建一个 apk。

Plug a device, to install and run:插入设备,安装并运行:

mvn -Pandroid client:install client:run

Note: by default, icon assets and AndroidManifest are generated at target/client/aarch64-android/gensrc/android .注意:默认情况下,图标资源和 AndroidManifest 生成在target/client/aarch64-android/gensrc/android If you want to modify either of them, you have to copy the content of this folder to src/android .如果要修改其中任何一个,则必须将此文件夹的内容复制到src/android

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM