android 页面缩放比例缩放,FireMonkey下android系统设置屏幕缩放比例失效的原因及解决方法...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

BambooCaep原创,转载请注明。

目前许多手机的屏幕分辨率大小不一,可以相差两三倍,但是屏幕尺寸并不会同比增加。为了使得显示出的界面能够适应不同的分辨率,英巴在FMX平台使用了

TWindowManager.Scale这个属性来进行屏幕缩放调整。

在FMX.Platform.Android.pas文件里,是使用SetScreenScaleOverrideHook来更改屏幕缩放比例的。

type

TScreenScaleOverrideHook = procedure(const UserContext: Pointer; const DensityScale, DensityDPI: Single;

var ScreenScale: Single);

procedure SetScreenScaleOverrideHook(const UserContext: Pointer; const Hook: TScreenScaleOverrideHook);

begin

ScreenScaleOverrideHook := Hook;

ScreenScaleOverrideHookContext := UserContext;

end;

function TPlatformAndroid.GetScreenScale: Single;

const

// Default values taken from Android SDK reference:

// http://developer.android.com/reference/android/util/DisplayMetrics.html#density

DefaultDensityScale = 1;

DefaultDensityDPI = 160;

var

Metrics: JDisplayMetrics;

DensityScale, DensityDPI: Single;

begin

if SameValue(FScreenScale, 0, TEpsilon.Scale) then

begin

Metrics := GetJDisplayMetrics;

if Assigned(Metrics) then

begin

DensityScale := Metrics.density; // API level 1

DensityDPI := Metrics.densityDpi; // API level 4

end

else

begin

DensityScale := DefaultDensityScale;

DensityDPI := DefaultDensityDPI;

end;

FScreenScale := DensityScale;

if Assigned(ScreenScaleOverrideHook) then

begin

ScreenScaleOverrideHook(ScreenScaleOverrideHookContext, DensityScale, DensityDPI, FScreenScale);

if FScreenScale < 1 then

FScreenScale := 1

else if FScreenScale > 3 then

FScreenScale := 3;

end;

end;

Result := FScreenScale;

end;

constructor TWindowManager.Create;

begin

......

FScale := PlatformAndroid.GetScreenScale;

......

end;

看起来相当美好。然而下述代码并不能生效,引用该单元后屏幕缩放比例并未改变。

unit TestScreenScale;

uses

FMX.Platform.Android;

implementation

procedure MyHook(const UserContext: Pointer; const DensityScale, DensityDPI: Single;

var ScreenScale: Single);

begin

ScreenScale := ScreenScale / 2;

end;

initialization

SetScreenScaleOverrideHook(nil, MyHook);

end.

原因就在于,调用SetScreenScaleOverrideHook必须引用FMX.Platform.Android。而FMX.Platform.Android引用了FMX.Platform,但是FMX.Platform在初始化时调用了

RegisterCorePlatformServices方法,在Android系统下就是调用FMX.Platform.Android里面的RegisterCorePlatformServices方法。

于是,在我们SetScreenScaleOverrideHook之前,PlatformAndroid实例已经被创建了。

constructor TPlatformAndroid.Create;

begin

......

PlatformAndroid := Self;

TWindowManager.Current;

......

end;

于是,TWindowManager也有了实例,不会再创建。

结果就是:在我们SetScreenScaleOverrideHook之前,就已经注定不会再使用到这个Hook了!

解决方法倒是简单:

procedure SetScreenScaleOverrideHook(const UserContext: Pointer; const Hook: TScreenScaleOverrideHook);

begin

ScreenScaleOverrideHook := Hook;

ScreenScaleOverrideHookContext := UserContext;

PlatformAndroid.FScreenScale := 0; //保证GetScreenScale时会重新计算

TWindowManager.Current.FScale := PlatformAndroid.GetScreenScale; //重新获取Hook后的Scale。

end;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值