DELPHI 12 中的 SurfaceView 始终呈现黑色背景

问题描述 投票:0回答:1

我在DELPHI 12中编写了一个用于SurfaceView绘画的Android应用程序。SurfaceView始终显示黑色背景,没有任何画笔的痕迹。以下是完整代码,请帮我找出问题所在。谢谢。

定义类TMySurfaceView_callback来实现JSurfaceHolder_Callback接口,并定义jpaint、jpath和JSurfaceHolder类型成员变量以供后续操作。 在TMySurfaceView_callback的构造方法中,使用TJSurfaceView.JavaClass.init(TAndroidHelper.Context)直接构造SurfaceView实例,并设置TMySurfaceView_callback实例的jpaint、jpath和JSurfaceHolder类型成员变量。 构建 TJFrameLayout_LayoutParams 布局并将 SurfaceView 添加到 TAndroidHelper.Activity.addContentView(Surfaceview, LayoutParams) 程序窗口。 在 TMySurfaceView_callback.SurfaceCreated(holder: JSurfaceHolder) 中绘制。获取画布并调用draw方法。事实上,进入这个方法后,SurfaceView只显示黑色背景,进入线程执行后也是如此。 我还为表面视图设置了一个触摸监听器。通过监听器,我认为surfaceview构建成功了。 但为什么总是显示黑色呢?画笔的绘画结果未显示。

unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,Androidapi.Helpers,
  Androidapi.JNI.GraphicsContentViewText,   FMX.Helpers.Android,    FMX.Surfaces
  ,  Androidapi.JNI.App,androidapi.JNIBridge,Androidapi.JNI.JavaTypes,
  FMX.Controls.Presentation, FMX.StdCtrls, FMX.Layouts,Androidapi.JNI.Embarcadero,
  Androidapi.JNI.Widget,FMX.Objects,fmx.Platform.Android,fmx.Platform,
  FMX.ListView.Types, FMX.ListView.Appearances, FMX.ListView.Adapters.Base,
  FMX.ListView,  Androidapi.JNI.Os;

type
  TForm1 = class(TForm)
    Button1: TButton;
    GridPanelLayout1: TGridPanelLayout;
    Layout1: TLayout;
    Layout2: TLayout;
    Image1: TImage;
    Button2: TButton;
    ListView1: TListView;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;


  TMySurfaceView_callback = class(TJavaLocal, JSurfaceHolder_Callback)
  private
    FSurfaceHolder: JSurfaceHolder;
    paint:jPaint;
    count:integer;
    mPath:jpath;
    isDraw:boolean;
  public
    constructor Create;
    procedure Release;
    procedure SurfaceChanged(holder: JSurfaceHolder; format: Integer; width, height: Integer); cdecl;
    procedure SurfaceCreated(holder: JSurfaceHolder); cdecl;
    procedure SurfaceDestroyed(holder: JSurfaceHolder); cdecl;
    procedure draw;
    procedure moveTo(x,y:single);
    procedure quadTo(x,y,w,h:single);
  end;
   myView_OnTouchListener = class(TJavaLocal,JView_OnTouchListener)

        public
          constructor Create;
          function onTouch(v: JView; event: JMotionEvent ) :boolean;cdecl;//override;
//          function onTouchEvent(event: jMotionEvent): boolean;
      end;
var
  Form1: TForm1;
  SurfaceView: jSurfaceView;
  mythread:tmythread;

implementation

{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}
{$R *.LgXhdpiTb.fmx ANDROID}

uses FMX.Graphics.Android;


{ TMySurfaceView }

constructor TMySurfaceView_callback.Create;
var
  LayoutParams: JFrameLayout_LayoutParams;
  SurfaceFrameLayout:jframelayout;
  myView_OnTouchListener1:myView_OnTouchListener;
begin
  inherited Create;
  SurfaceView := TJSurfaceView.JavaClass.init(TAndroidHelper.Context);
  FSurfaceHolder := Surfaceview.getHolder;
  FSurfaceHolder.addCallback(Self);
  FSurfaceHolder.setKeepScreenOn(true);
  SurfaceView.setVisibility(0);
  SurfaceView.setFocusable(true);
  SurfaceView.setFocusableInTouchMode(true);
  SurfaceView.setKeepScreenOn(true);
//  surfaceView.getHolder.setFormat(-2);  //-3 半透明
  surfaceView.setzOrderOnTop(true);
  myView_OnTouchListener1:=myView_OnTouchListener.Create;
  Surfaceview.setOnTouchListener(myView_OnTouchListener1 );
    LayoutParams := TJFrameLayout_LayoutParams.JavaClass.init(800,1000);
    LayoutParams.topMargin:=500;
    LayoutParams.leftMargin:=200;
    TAndroidHelper.Activity.addContentView(Surfaceview, LayoutParams) ;
  mpath:=tjpath.JavaClass.init;
  paint:=TJPaint.JavaClass.init;
  paint.setColor($FF0000);
  paint.setStrokeWidth(57);
  paint.setStyle(TJPaint_Style.JavaClass.FILL_AND_STROKE);
  paint.setTextSize(50);
  paint.setTextAlign(TJpaint_align.JavaClass.CENTER);
end;

procedure TMySurfaceView_callback.draw;
var
  Canvas: JCanvas;
  NewThread: TThread;
begin
//  while isDraw do
   begin
   NewThread := TThread.CreateAnonymousThread(
    procedure
    begin
    TRY
      count:=count+1;
     Canvas := FSurfaceHolder.lockCanvas;
     Canvas.drawColor($FA8072,TJPorterDuff_Mode.JavaClass.clear) ;
     Canvas.drawCircle(100,100,100,paint);
     Canvas.drawCircle(200,200,20,paint);
     Canvas.drawText(stringtoJstring('canvas text:--'+inttostr(count)),500,300,paint) ;
     Canvas.drawPath(mPath, Paint);
     TThread.Synchronize(nil,
        procedure
        begin
          // 更新UI组件
          form1.Button2.Text:='Runing...';
        end
         );

     finally
      FSurfaceHolder.unlockCanvasAndPost(Canvas);
      end;
      end
    );
    NewThread.FreeOnTerminate := True; // 确保线程执行完毕后自动释放资源
    NewThread.Start; // 启动新线程
  end
end;

procedure TMySurfaceView_callback.moveTo(x, y: single);
begin
   mPath.moveTo(x, y);
end;

procedure TMySurfaceView_callback.quadTo(x, y, w, h: single);
begin
  mPath.quadTo(x, y, (x + w) / 2, (y + h) / 2);
end;

procedure TMySurfaceView_callback.Release;
begin
  FSurfaceHolder.removeCallback(Self);
  inherited;
end;

procedure TMySurfaceView_callback.SurfaceChanged(holder: JSurfaceHolder; format, width, height: Integer);
var
  Canvas: JCanvas;
begin
//   showmessage('SurfaceChanged');
end;

procedure TMySurfaceView_callback.SurfaceCreated(holder: JSurfaceHolder);
var
  Canvas: JCanvas;
  bmp:jbitmap;
begin
  // 获取画布并绘制内容
   showmessage('SurfaceCreated');
  if not (FSurfaceHolder.getSurface.isValid) then
    begin
      showmessage('播放器设置或销毁显示区域失败!');
      end;
  isDraw:=true;
  bmp:=tjbitmap.JavaClass.createBitmap(800,1000,TJBitmap_Config.JavaClass.ARGB_8888);
  bmp.eraseColor($FA8072);
  Canvas := FSurfaceHolder.lockCanvas;
  Canvas.drawBitmap(bmp,0,0,paint);
//  Canvas.drawColor($FA8072) ;
  FSurfaceHolder.unlockCanvasAndPost(Canvas);
  draw;
end;

procedure TMySurfaceView_callback.SurfaceDestroyed(holder: JSurfaceHolder);
begin
  // 释放资源
   showmessage('SurfaceDestroyed');
   isDraw:=false;
end;


// 在你的TSurfaceView的事件中使用TCustomCanvas来绘制动画
procedure TForm1.Button1Click(Sender: TObject);
// 使用TMySurfaceView
var
  MySurfaceView: TMySurfaceView_callback;
begin
  MySurfaceView := TMySurfaceView_callback.Create;
 end;

procedure TForm1.Button2Click(Sender: TObject);
begin
//  TSurfaceView.mSurfaceHolder_Callback.isDraw:=false;
end;


{ myView_OnTouchListener }

constructor myView_OnTouchListener.Create;
begin
  inherited Create;
end;

function myView_OnTouchListener.onTouch(v: JView;event: jMotionEvent): boolean;
var
  x,y,dx,dy,mLastX,mLasty:single;
begin
   form1.ListView1.items.Clear;
    x := event.getX;
    y := event.getY;
//   showmessage('touch me at x,y: '+FloatToStr(x)+','+FloatToStr(y));
        case  (event.getAction)  of
            0:    //tjMotionEvent.JavaClass.ACTION_DOWN     TSurfaceView.
               begin
                mLastX := x;
                mLastY := y;
//                TMySurfaceView_callback.moveTo(mLastX, mLastY);
               end;
            2: //tjMotionEvent.JavaClass.ACTION_MOVE
                begin
                dx :=abs(x - mLastX);
                dy := abs(y - mLastY);
                if (dx >= 3) and (dy >= 3)   then
//                    TMySurfaceView_callback.quadTo(mLastX, mLastY, (mLastX + x) / 2, (mLastY + y) / 2);

                mLastX := x;
                mLastY := y;
                form1.ListView1.items.Add.Text:='X:'+FloatToStr(x)+','+ 'y:'+FloatToStr(y)
                end;
            1:  //tjMotionEvent.JavaClass.ACTION_UP
                ;
            end;

        result:=true;

end;

end.


应用程序

android delphi java-native-interface surfaceview
1个回答
0
投票
  1. 列出项目

这就是解决方案 编辑-->

paint.setStyle(TJPaint_Style.JavaClass.FILL_AND_STROKE);

到 --->

paint.setStyle(TJPaint_Style.JavaClass.FILL);

© www.soinside.com 2019 - 2024. All rights reserved.