单击标记后,“导航”和“GPS 指针”按钮将显示在组件的右下角。客户希望阻止这些按钮在他们的应用程序中显示。
应用程序正在使用 Delphi 12.1 构建,并使用 FireMonkey 框架中提供的默认 TMapView 组件。
我们发现可以通过
map.getUiSettings().setMapToolbarEnabled(false);
禁用此 MapToolBar
但是我们无论如何都找不到使用默认的 TMapView 来执行此操作。
在FireMonkey框架代码中搜索后,我们在Androidapi.JNI.PlayServices.Maps单元中找到了JGoogleMap接口。该接口具有如上所述的所需方法。 所以下一步就是找到这个接口在哪里被使用。该接口的实例在 TAndroidMapView 实现中内部使用。我们假设 MapView 组件中正在使用此类的实例。 但无法从类实现外部访问此实例。
我们尝试使用 Rtti 访问此实例,但没有成功
class function TFrameAndroidViewMap.DisableMapToolBarRtti(const MapView: TMapView): Boolean;
begin
Result := False;
var RttiContext := TRttiContext.Create;
try
var MapViewControlRttiType := RttiContext.GetType(MapView.ClassType);
var FieldMapView: TRttiField;
if not TryGetRttiFieldByName(MapViewControlRttiType, 'FMapView', FieldMapView) then
Exit;
var FieldMapViewValue := FieldMapView.GetValue(MapView);
var MapViewInstance: TMapViewBase;
if not FieldMapViewValue.TryAsType<TMapViewBase>(MapViewInstance) then
Exit;
var MapViewInstanceClassType := MapViewInstance.ClassType;
var MapViewInstanceClassName := MapViewInstance.ClassName;
var MapViewInstanceRttiType := RttiContext.GetType(MapViewInstanceClassType);
var FieldGoogleMap: TRttiField;
if not TryGetRttiFieldByName(MapViewInstanceRttiType, 'FGoogleMap', FieldGoogleMap) then
Exit;
var GoogleMapFieldValue := FieldGoogleMap.GetValue(MapViewInstance);
var GoogleMapField: JGoogleMap;
if GoogleMapFieldValue.TryAsType<JGoogleMap>(GoogleMapField) then
begin
GoogleMapField.getUiSettings().setMapToolbarEnabled(False);
Result := True;
end;
finally
RttiContext.Free;
end;
end;
您实际上可以访问底层Android引用,但不能访问
JGoogleMap
引用,至少不能直接访问。但是,您可以通过使用 JMapView
上的 JMapViewWithGestures
方法来访问 JMapView
引用(实际上是 Supports
,但它只是 TMapView
的后代)。从那里,可以调用 getMapAsync
方法来获取 JGoogleMap
引用。长话短说 - 这是一个例子:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Maps,
Androidapi.JNI.PlayServices.Maps;
type
TForm1 = class(TForm)
MapView1: TMapView;
procedure FormCreate(Sender: TObject);
private
FMap: JGoogleMap;
FMapReadyCallback: JOnMapReadyCallback;
procedure MapReady(AMap: JGoogleMap);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
uses
Androidapi.JNIBridge;
type
TMapReadyCallback = class(TJavaLocal, JOnMapReadyCallback)
private
FCallback: TProc<JGoogleMap>;
public
{ JOnMapReadyCallback }
procedure onMapReady(googleMap: JGoogleMap); cdecl;
public
constructor Create(const ACallback: TProc<JGoogleMap>);
end;
{ TMapReadyCallback }
constructor TMapReadyCallback.Create(const ACallback: TProc<JGoogleMap>);
begin
inherited Create;
FCallback := ACallback;
end;
procedure TMapReadyCallback.onMapReady(googleMap: JGoogleMap);
begin
FCallback(googleMap);
end;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
LMapView: JMapView;
begin
if Supports(MapView1, JMapView, LMapView) then
begin
FMapReadyCallback := TMapReadyCallback.Create(MapReady);
LMapView.getMapAsync(FMapReadyCallback);
end;
end;
procedure TForm1.MapReady(AMap: JGoogleMap);
begin
FMap := AMap;
FMap.getUiSettings.setMapToolbarEnabled(False);
end;
end.
说明:
顾名思义,getMapAsync
是一个异步调用,它获取对回调的引用,当 onMapReady
引用可用时,将调用 JGoogleMap
。 TMapReadyCallback
类实现了具有此方法的 JOnMapReadyCallback
。它依次调用回调方法MapReady
,该方法被传递给构造函数中的类。
在
MapReady
中,您现在可以访问 JGoogleMap 引用并可以调用其上的方法,如示例所示。