【问题标题】:How to set request orientation in runtime?如何在运行时设置请求方向?
【发布时间】:2019-04-24 04:57:42
【问题描述】:

我希望我的胶子应用程序能够在运行时将方向从横向更改为纵向。我检查了 Gluon Charmdown SDK,它似乎只有 getOrientation 并且没有在运行时设置方向的选项。我不想在 Manifest 中设置固定方向

【问题讨论】:

  • 当你说改变方向时,你的意思是即使用户不旋转设备也要强制方向?因此,您的清单将允许两种方向,但您想以编程方式设置给定方向,而不考虑设备?
  • @JoséPereda:是的,有点像。就像 Android 中的 setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE );

标签: gluon-mobile


【解决方案1】:

Charm Down 有一个OrientationService,但正如您所提到的,它是“只读的”,它只会监听方向变化并随时为您提供当前方向。但到目前为止,您可以通过编程方式设置方向。

要包含此功能,有两种选择:克隆 Charm Down、修改 Orientation Service、构建并使用您的自定义构建,或直接创建一个新服务,如 ExtendedOrientationService,您可以直接将其包含在您的项目中。

假设是后者,这是一个非常基本的服务实现,允许以编程方式设置方向:

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);
    }

}

对于安卓:

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);
    }

}

在 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();

}

现在从这个sample 添加ios-gradle.build 文件。

最后我们需要构建并包含原生库:

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")
}

您可以使用以下方法构建库并将其添加到项目中:

./gradlew installNativeLib 

示例

这个 sn-p 显示了如何使用这个服务:如果方向是垂直的,它将强制水平方向,否则它将释放方向:

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();
            }
        });

【讨论】:

  • 我会尝试您的解决方案,并尽快回复您。
  • 它在 Android 上运行良好,但我是 iOS 的新手。您能否详细说明链接到 *.m 文件的 Java 实现应该做什么?我也读过这个文档docs.gluonhq.com/samples/gonative
  • 我已经编辑了我的答案,ExtendedOrientation.m 标题不见了,我没有包括IOSExtendedOrientationService.java,我的错。让我知道您现在是否可以尝试一下。只需将 *.h 和 *.m 文件放在native 下,然后运行installNativeLib,您应该会看到libExtendedOrientation.a 添加到src/ios/jniLibs
  • 我仍然没有看到您在编辑后的答案中包含IOSExtendedOrientationService.java
  • 嗯,我没有点击保存编辑...现在发布了。
猜你喜欢
  • 1970-01-01
  • 2017-03-01
  • 2017-03-26
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多