如何在运行时设置请求方向?
How to set request orientation in runtime?
我希望我的 gluon 应用程序能够在 运行 时间内将方向从横向更改为纵向。我已经检查了 Gluon Charmdown SDK,它似乎只有 getOrientation 并且没有在 运行time 中设置方向的选项。我不想在 Manifest
中设置固定方向
Charm Down 有一个 OrientationService,但正如您提到的,它是 "read only",它只是监听方向变化并随时为您提供当前方向。但到目前为止,您可以通过编程方式设置方向。
要包含此功能,有两种选择:克隆 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);
}
}
对于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);
}
}
在 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
样本
此代码段显示了如何使用此服务:如果方向是垂直的,它将强制水平方向,否则它将释放方向:
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();
}
});
我希望我的 gluon 应用程序能够在 运行 时间内将方向从横向更改为纵向。我已经检查了 Gluon Charmdown SDK,它似乎只有 getOrientation 并且没有在 运行time 中设置方向的选项。我不想在 Manifest
中设置固定方向Charm Down 有一个 OrientationService,但正如您提到的,它是 "read only",它只是监听方向变化并随时为您提供当前方向。但到目前为止,您可以通过编程方式设置方向。
要包含此功能,有两种选择:克隆 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);
}
}
对于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);
}
}
在 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
样本
此代码段显示了如何使用此服务:如果方向是垂直的,它将强制水平方向,否则它将释放方向:
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();
}
});