问题
I want button size (width and height) to be as small as possible, but I want it to fit the text. Any code example? Delphi XE4 FireMonkey Mobile Application.
回答1:
FireMonkey renders text via methods using TTextLayout class.
We can access this methods via a class helper and then change the buttons size based on the information provided by the layout.
uses FMX.TextLayout;
type
TextHelper = class helper for TText
function getLayout : TTextLayout;
end;
function TextHelper.getLayout;
begin
result := Self.fLayout;
end;
procedure ButtonAutoSize(Button : TButton);
var
bCaption : TText;
m : TBounds;
begin
bCaption := TText(Button.FindStyleResource('text',false));
bCaption.HorzTextAlign := TTextAlign.taLeading;
bCaption.VertTextAlign := TTextAlign.taLeading;
m := bCaption.Margins;
Button.Width := bCaption.getLayout.Width + m.Left + m.Right;
Button.Height := bCaption.getLayout.Height + m.Top + m.Bottom;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ButtonAutoSize(Sender as TButton);
end;
Update
Here is a more future proof solution that doesn't require exposing private class fields.
uses FMX.Objects;
procedure ButtonAutoSizeEx(Button: TButton);
var
Bitmap: TBitmap;
Margins: TBounds;
Width, Height: Single;
begin
Bitmap := TBitmap.Create;
Bitmap.Canvas.Font.Assign(Button.TextSettings.Font);
Width := Bitmap.Canvas.TextWidth(Button.Text);
Height := Bitmap.Canvas.TextHeight(Button.Text);
Margins := (Button.FindStyleResource('text', false) as TText).Margins;
Button.TextSettings.HorzAlign := TTextAlign.Leading;
Button.Width := Width + Margins.Left + Margins.Right;
Button.Height := Height + Margins.Top + Margins.Bottom;
end;
This example omits any word wrapping or character trimming.
回答2:
Based on the answer of @Peter, but no need to create a bitmap:
//...
type
TButtonHelper = class helper for TButton
procedure FitToText(AOnlyWidth: Boolean = False);
end;
implementation
//...
// Adapt button size to text.
// This code does not account for word wrapping or character trimming.
procedure TButtonHelper.FitToText(AOnlyWidth: Boolean = False);
var
Margins: TBounds;
TextWidth, TextHeight: Single;
Obj: TFmxObject;
const
CLONE_NO = False;
begin
Obj := FindStyleResource('text', CLONE_NO);
if Obj is TText then //from Stackoverflow comments: Some time FindStyleResource returns nil making the app crash
begin
Margins := (Obj as TText).Margins;
TextWidth := Canvas.TextWidth(Text);
if not AOnlyWidth then
TextHeight := Canvas.TextHeight(Text);
TextSettings.HorzAlign := TTextAlign.taLeading; //works in XE4
//later FMX-Versions ?: TextSettings.HorzAlign := TTextAlign.Leading;
Width := TextWidth + Margins.Left + Margins.Right;
if not AOnlyWidth then
Height := TextHeight + Margins.Top + Margins.Bottom;
end;
end;
来源:https://stackoverflow.com/questions/18430290/how-to-adjust-button-size-to-fit-the-text-in-delphi-firemonkey