小虾米资讯

AD1
当前位置:网站首页 / android / 正文

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

2020-12-06 01:13:48 / 我要吐槽 查看是否已被百度收录 查看是否已被谷歌收录 查看是否已被搜狗收录 查看是否已被360收录
AD2
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;implementationprocedure MyHook(const UserContext: Pointer; const DensityScale, DensityDPI: Single; var ScreenScale: Single);begin ScreenScale := ScreenScale / 2;end;initializationSetScreenScaleOverrideHook(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;

顶。

mark

好辛苦 JAVA下已经很多蛋疼BUG了

10.4.1 已经修复了。之前这个 SetScreenScaleOverrideHook 帮了我大忙,哈哈。

Powered By © 小虾米资讯 2015

(本站部分文章来源于网络或网友爆料,不代表本站观点,如有侵权请联系及时删除 )