Android Firemonkey setContentView

Android Firemonkey setContentView,android,delphi,firemonkey,Android,Delphi,Firemonkey,我不知道如何通过Delphi代码在Android上设置主视图/布局 我有以下名为“activity_tv.xml”的布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" androi

我不知道如何通过Delphi代码在Android上设置主视图/布局

我有以下名为“activity_tv.xml”的布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent">

    <TextView
        android:id="@+id/text_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:text="@string/hello"/>

</LinearLayout>
我试图设置主要活动的布局,但什么也没发生。这是我正在尝试的代码:

procedure TForm1.FormCreate(Sender: TObject);
begin
  CallInUIThread(SetMainLayout);
end;

procedure TForm1.SetMainLayout;
var
  LayoutID: Integer;
begin
  LayoutID := TAndroidHelper.Activity.getResources.getIdentifier(
    TAndroidHelper.StringToJString('tvlayout'),
    TAndroidHelper.StringToJString('layout'),
    TAndroidHelper.Activity.getPackageName()
  );

  TAndroidHelper.Activity.setContentView(LayoutID);
end;
这就是整个项目。我确实在表单上有一个按钮,并试图从其单击处理程序调用
CallInUIThread(SetMainLayout)
,但同样的情况发生了:按钮停留在表单上,我看不到我的视图。我试着把按钮挪动一下,以防它碍事

我自己也尝试过用两种不同的方式来扩展布局。这两次我都得到了(我假设是)一个有效的视图指针,应用程序没有崩溃,但它也没有做任何事情:

//attempt one
inflater := TJLayoutInflater.JavaClass.from(TAndroidHelper.Context);
layoutView := inflater.inflate(LayoutID, nil);
TAndroidHelper.Activity.setContentView(layoutView);

//attempt two
InfObj := TAndroidHelper.Context.getSystemService(TJContext.JavaClass.LAYOUT_INFLATER_SERVICE);
Inflater := TJLayoutInflater.Wrap((InfObj as ILocalObject).GetObjectID);
layoutView := Inflater.inflate(LayoutID, nil);
TAndroidHelper.Activity.setContentView(layoutView);
我想也许我必须在AppManifest中添加一个活动,但我在Android Studio中重复了以下步骤,一切正常:

  • 创建带有主活动的空项目
  • 创建一个名为activity_tv.xml的新布局文件,其中包含此问题的确切代码
  • 编辑strings.xml以包含“hello”字符串
  • setContentView(R.layout.activity\u main)更改MainActivity类中的调用
    设置内容视图(R.layout.activity\u tv)
  • 为了更好的衡量,我创建了一个全新的Delphi项目,以确保我没有遗漏任何东西。此处是唯一的Delphi代码文件:

    unit Unit1;
    
    interface
    
    uses
      FMX.Forms, Androidapi.Helpers, FMX.Helpers.Android;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        procedure SetMainLayout;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CallInUIThread(SetMainLayout);
    end;
    
    procedure TForm1.SetMainLayout;
    var
      LayoutID: Integer;
    begin
      LayoutID := TAndroidHelper.Activity.getResources.getIdentifier(
        TAndroidHelper.StringToJString('activity_tv'),
        TAndroidHelper.StringToJString('layout'),
        TAndroidHelper.Activity.getPackageName()
      );
    
      TAndroidHelper.Activity.setContentView(LayoutID);
    end;
    
    end.
    
    如何让
    setContentView
    在Delphi中工作

    Delphi版本:

    Embarcadero® Delphi 10 Seattle Version 23.0.20618.2753 
    

    FMX实现自己的窗口渲染,因此很可能会干扰您使用本机布局的尝试。但是,在此之前还有另一个问题。在Delphi中,西雅图FMX UI在不同于Android UI线程的线程上运行。在Android UI线程之外调用UI方法将失败。你必须使用TAndroidHelper.Activity.runOnUiThread和setContentView。你注意到的第一件事是我担心的。但一定有办法吗?如果我不能使用,为什么还要包装所有的UI类呢?但是我确实用
    CallInUIThread
    在UI线程上调用了它。我想这会在Android UI线程上运行,但我可以尝试使用
    runOnUiThread
    。我错过了。那么,看来FMX渲染是罪魁祸首。检查一下,也许你会在那里找到答案。谢谢!几小时后我会看一看。我得去跑腿了。试着看看本机控件(如Tedit)的实现。要继续,您不能在窗口中放置任何android视觉控件,因为delphi会在窗口中绘制自身,但您可以做的是在delphi窗口的顶部放置另一个窗口,其中包含您的视觉控件(在您的视频上)。看看TALEdit作为示例是如何完成的
    unit Unit1;
    
    interface
    
    uses
      FMX.Forms, Androidapi.Helpers, FMX.Helpers.Android;
    
    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        procedure SetMainLayout;
      end;
    
    var
      Form1: TForm1;
    
    implementation
    
    {$R *.fmx}
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
      CallInUIThread(SetMainLayout);
    end;
    
    procedure TForm1.SetMainLayout;
    var
      LayoutID: Integer;
    begin
      LayoutID := TAndroidHelper.Activity.getResources.getIdentifier(
        TAndroidHelper.StringToJString('activity_tv'),
        TAndroidHelper.StringToJString('layout'),
        TAndroidHelper.Activity.getPackageName()
      );
    
      TAndroidHelper.Activity.setContentView(LayoutID);
    end;
    
    end.
    
    Embarcadero® Delphi 10 Seattle Version 23.0.20618.2753