How to set request orientation in runtime?

后端 未结 1 644
傲寒
傲寒 2021-01-25 13:42

I want my gluon application to be able to change orientation from Landscape to portrait in run time. I have check the Gluon Charmdown SDK, It seem that it have only getOrientati

相关标签:
1条回答
  • 2021-01-25 14:08

    Charm Down has an OrientationService, but as you have mentioned, it is "read only", it just listens to orientation changes and gives you the current orientation at any time. But so far you can set the orientation programatically.

    To include this feature there are two options: clone Charm Down, modify the Orientation Service, build and use your custom build, or directly create a new service, like ExtendedOrientationService, that you can include in your project directly.

    Assuming the latter, this is a very basic implementation of a service that allows setting the orientation programmatically:

    ExtendedOrientationService.java

    package com.gluonhq.charm.down.plugins;
    
    import javafx.geometry.Orientation;
    
    public interface ExtendedOrientationService {
    
        void coerceOrientation(Orientation orientation);
    
        void releaseOrientation();
    
    }
    

    ExtendedOrientationServiceFactory.java

    package com.gluonhq.charm.down.plugins;
    
    import com.gluonhq.charm.down.DefaultServiceFactory;
    
    public class ExtendedOrientationServiceFactory extends DefaultServiceFactory<ExtendedOrientationService> {
    
        public ExtendedOrientationServiceFactory() {
            super(ExtendedOrientationService.class);
        }
    
    }
    

    For Android:

    AndroidExtendedOrientationService.java

    package com.gluonhq.charm.down.plugins.android;
    
    import android.content.pm.ActivityInfo;
    import com.gluonhq.charm.down.plugins.ExtendedOrientationService;
    import javafx.geometry.Orientation;
    import javafxports.android.FXActivity;
    
    public class AndroidExtendedOrientationService implements ExtendedOrientationService {
    
        private final FXActivity instance = FXActivity.getInstance();
    
        @Override
        public void coerceOrientation(Orientation orientation) {
            if (orientation.equals(Orientation.HORIZONTAL)) {
                instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else if (orientation.equals(Orientation.VERTICAL)) {
                instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
            instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
        }
    
        @Override
        public void releaseOrientation() {
            instance.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
        }
    
    }
    

    On iOS:

    ExtendedOrientation.h

    #import <UIKit/UIKit.h>
    #include "jni.h"
    
    @interface ExtendedOrientation : UIViewController {}
        @property (nonatomic, assign) BOOL shouldAutoRotate;
    
        - (void) setOrientation:(NSString *)orientation;
        - (void) release;
    @end
    

    ExtendedOrientation.m

    #include "ExtendedOrientation.h"
    
    extern JNIEnv *jEnv;
    #define GET_MAIN_JENV \
    if (jEnv == NULL) NSLog(@"ERROR: Java has been detached already, but someone is still trying to use it at %s:%s:%d\n", __FUNCTION__, __FILE__, __LINE__);\
    JNIEnv *env = jEnv;
    
    JNIEXPORT jint JNICALL
    JNI_OnLoad_ExtendedOrientation(JavaVM *vm, void *reserved)
    {
    #ifdef JNI_VERSION_1_8
        //min. returned JNI_VERSION required by JDK8 for builtin libraries
        JNIEnv *env;
        if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_8) != JNI_OK) {
            return JNI_VERSION_1_4;
        }
        return JNI_VERSION_1_8;
    #else
        return JNI_VERSION_1_4;
    #endif
    }
    
    static int ExtendedOrientationInited = 0;
    
    // ExtendedOrientation
    ExtendedOrientation *_extendedOrientation;
    
    JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_plugins_ios_IOSExtendedOrientationService_initOrientation
    (JNIEnv *env, jclass jClass)
    {
        if (ExtendedOrientationInited)
        {
            return;
        }
        ExtendedOrientationInited = 1;
    
        _extendedOrientation = [[ExtendedOrientation alloc] init];
    }
    
    JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_plugins_ios_IOSExtendedOrientationService_setOrientation
    (JNIEnv *env, jclass jClass, jstring jOrientation)
    {
        const jchar *charsOrientation = (*env)->GetStringChars(env, jOrientation, NULL);
        NSString *orientation = [NSString stringWithCharacters:(UniChar *)charsOrientation length:(*env)->GetStringLength(env, jOrientation)];
        (*env)->ReleaseStringChars(env, jOrientation, charsOrientation);
        [_extendedOrientation setOrientation:orientation];
    }
    
    JNIEXPORT void JNICALL Java_com_gluonhq_charm_down_plugins_ios_IOSExtendedOrientationService_release
    (JNIEnv *env, jclass jClass)
    {
        [_extendedOrientation release];
    }
    
    @implementation ExtendedOrientation
    
    -(void) setOrientation:(NSString*)orientation
    {
        _shouldAutoRotate = YES;
    
        NSLog(@"Set orientation: %@", orientation);
        if ([orientation isEqualToString:@"HORIZONTAL"])
        {
            [[UIDevice currentDevice] setValue:[NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft] forKey:@"orientation"];
        } else
        {
            [[UIDevice currentDevice] setValue:[NSNumber numberWithInt:UIInterfaceOrientationPortrait] forKey:@"orientation"];
        }
    }
    
    - (void) release
    {
        _shouldAutoRotate = NO;
    }
    
    - (BOOL)shouldAutorotate
    {
        return _shouldAutoRotate;
    }
    
    @end
    

    IOSExtendedOrientationService.java

    package com.gluonhq.charm.down.plugins.ios;
    
    import com.gluonhq.charm.down.plugins.ExtendedOrientationService;
    import javafx.geometry.Orientation;
    
    public class IOSExtendedOrientationService implements ExtendedOrientationService {
    
        static {
            System.loadLibrary("ExtendedOrientation");
            initOrientation();
        }
    
        @Override
        public void coerceOrientation(Orientation orientation) {
            setOrientation(orientation.toString());
        }
    
        @Override
        public void releaseOrientation() {
            release();
        }
    
        // native
        private static native void initOrientation();
        private static native void setOrientation(String orientation);
        private static native void release();
    
    }
    

    Now add the ios-gradle.build file from this sample.

    Finally we need to build and include the native library:

    build.gradle

    apply from: 'ios-build.gradle'
    
    
    task xcodebuild {
        doLast {
            xcodebuildIOS("$project.buildDir","$project.projectDir", "ExtendedOrientation")
        }
    }
    
    task installNativeLib (type:Copy, dependsOn: xcodebuild) {
        from("$project.buildDir/native")
        into("src/ios/jniLibs")
        include("*.a")
    }
    

    You can build and add the library to the project with:

    ./gradlew installNativeLib 
    

    SAMPLE

    This snippet shows how to use this service: If the orientation is vertical it will force horizontal orientation, else it will release the orientation:

    Services.get(ExtendedOrientationService.class).ifPresent(o -> {
                Orientation orientation = Services.get(OrientationService.class)
                        .flatMap(OrientationService::getOrientation)
                        .orElse(Orientation.HORIZONTAL);
    
                if (orientation == Orientation.VERTICAL) {
                    o.coerceOrientation(Orientation.HORIZONTAL);
                } else {
                    o.releaseOrientation();
                }
            });
    
    0 讨论(0)
提交回复
热议问题