Android Question Canvas draw position, how to align?

Sub7

Active Member
Licensed User
Longtime User
Hello, i'm looking for some tutorial or advice on how work with views added from code, most times i use the designer and designer script to build the layout so i never had big problems.
Now that i need to use a canvas i'm having some good troubles to align and set the position of the drawed text correctly.
For example i added an imagview using the designer and then set his position and properties with designer script.
Later using the below code i want draw some text over imageview1 in a exact position which will be the same in all screeens.

Which is the best pratice to achieve this? im getting really lost with X and Y.

The imageview is a template file of a business card, the user can input some text and save the output.

B4X:
Dim cnv1
cnv1.initialize(imageView1)
cnv1.DrawTextRotated("Text 1",250,270, Typeface.MONOSPACE,12,Colors.White,"RIGHT",4)
cnv1.DrawTextRotated("Text 2",???,???, Typeface.MONOSPACE,12,Colors.White,"RIGHT",4)
activity.invalidate

Thank you so much
 

Sub7

Active Member
Licensed User
Longtime User
@sorex Would you be so kind to post a small example please? i cannot get it work.
 

Attachments

  • test_canvas.zip
    8.1 KB · Views: 175
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Without percentages i get everything screwed up on both devices (phone/tablet), even the last code does not works perfectly, the position on the two devices is similar but different.

I can not open your project (different version of B4A).

Try to use the values expressed in percentage but not 10%x (this means 10% of screen width), 10% of the ImageView's sides!

ImageView1.Width * .1
ImageView1.Height * .2

In addition, the TextSize should be adapted.
 
Upvote 0

Sub7

Active Member
Licensed User
Longtime User
Hi luca, yes i am using an old version, will have to update someday.
The code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: B4A Example
    #VersionCode: 1
    #VersionName:
    'SupportedOrientations possible values: unspecified, landscape or portrait.
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals
End Sub

Sub Globals
Dim cnv As Canvas
    Private Button1 As Button
    Private ImageView1 As ImageView
    Private Panel1 As Panel
End Sub

Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("main")
cnv.Initialize(Panel1)

'cnv.Initialize(ImageView1)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub Button1_Click
cnv.DrawText("Text row 1",250,150, Typeface.MONOSPACE,22,Colors.white,"RIGHT")
cnv.DrawText("Text row 2",250,200, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
cnv.DrawText("Text row 3",250,250, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
Activity.Invalidate
End Sub

Designer script code:
B4X:
'All variants script
AutoScaleAll
Panel1.SetTopAndBottom(0%y,100%y)
Panel1.SetLeftAndRight(0%x,100%x)
Button1.Bottom = 100%y
Button1.HorizontalCenter = 50%x
ImageView1.Bottom = Button1.Top -5dip
ImageView1.HorizontalCenter = 50%x


On a tablet where the imageview looks bigger the text draw looks different (in size) and is not aligned like on small screen device,
sorry for all the silly questions these days!
 

Attachments

  • basefile.png
    basefile.png
    1.9 KB · Views: 185
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Don't worry, we are here to help each other.

Unfortunately I have an old version, not you (3.00).

I try to see if I can understand something, otherwise there will be the great Klaus that surely will solve your problem... as always ;)
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Allora, intanto scrivo in italiano, che mi viene molto meglio :) then i'll try to translate.

Se il codice che hai pubblicato nel #24 funziona bene su un tuo dispositivo, tu dovresti calcolare la percentuale di quei valori:
B4X:
cnv.DrawText("Text row 1",250,150, Typeface.MONOSPACE,22,Colors.white,"RIGHT")
cnv.DrawText("Text row 2",250,200, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
cnv.DrawText("Text row 3",250,250, Typeface.MONOSPACE,22,Colors.White,"RIGHT")

(250,150) (250,200) (250,250) rispetto alle dimensioni di Panel1, sul quale stai scrivendo.

Quindi, poniamo il caso che il Panel1, nel tuo progetto funzionante, abbia Width = 320 e Height = 480,
il primo testo (250,150) sarà nella posizione (250/Panel1.Width,150/Panel1.Height).

Dovrebbe essere così, se sbaglio, sparami pure, tanto non mi cogli, hehehe

(al variare delle dimensioni del Panel1 perché variano quelle del display, le proporzioni rimangono le stesse. L'unico problema è adattare il TextSize. Questo non è facile, almeno non per me; dipende anche dalle dimensioni del display, un conto è un 3.5", altro un 12").
Intanto prova così, in attesa del più esperto e dotato (di versione di B4A recente :)).

Now I should translate, sigh and sob :(
___________________________________________________________________________________________________________________________

If the code you posted in #24 works well on your device, you should calculate the percentage of those values:
B4X:
cnv.DrawText("Text row 1",250,150, Typeface.MONOSPACE,22,Colors.white,"RIGHT")
cnv.DrawText("Text row 2",250,200, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
cnv.DrawText("Text row 3",250,250, Typeface.MONOSPACE,22,Colors.White,"RIGHT")

(250,150) (250,200) (250,250) relative to the size of Panel1 on which you are writing.

So, let's say that the Panel1, in your working project, has Width = 320 and Height = 480:
the first text (250,150) will be in position (250/Panel1.Width, 150/Panel1.Height).

Should be so; if I'm wrong, shoot me, I do not think you hit me, hehehe.

(When the size of Panel1 vary, as those of the display vary, the proportions remain the same. The only problem is to adapt the TextSize. This is not easy, at least not for me, it depends also on the size of the display).

Meanwhile, you could try so, waiting for the more experienced and equipped (more recent B4A) Klaus.
 
Last edited:
Upvote 0

Sub7

Active Member
Licensed User
Longtime User
Allora, intanto scrivo in italiano, che mi viene molto meglio :) then i'll try to translate.

Se il codice che hai pubblicato nel #24 funziona bene su un tuo dispositivo, tu dovresti calcolare la percentuale di quei valori:
B4X:
cnv.DrawText("Text row 1",250,150, Typeface.MONOSPACE,22,Colors.white,"RIGHT")
cnv.DrawText("Text row 2",250,200, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
cnv.DrawText("Text row 3",250,250, Typeface.MONOSPACE,22,Colors.White,"RIGHT")

(250,150) (250,200) (250,250) rispetto alle dimensioni di Panel1, sul quale stai scrivendo.

Quindi, poniamo il caso che il Panel1, nel tuo progetto funzionante, abbia Width = 320 e Height = 480,
il primo testo (250,150) sarà nella posizione (250/Panel1.Width,150/Panel1.Height).

Dovrebbe essere così, se sbaglio, sparami pure, tanto non mi cogli, hehehe

(al variare delle dimensioni del Panel1 perché variano quelle del display, le proporzioni rimangono le stesse. L'unico problema è adattare il TextSize. Questo non è facile, almeno non per me; dipende anche dalle dimensioni del display, un conto è un 3.5", altro un 12").
Intanto prova così, in attesa del più esperto e dotato (di versione di B4A recente :)).

Now I should translate, sigh and sob :(
___________________________________________________________________________________________________________________________

If the code you posted in #24 works well on your device, you should calculate the percentage of those values:
B4X:
cnv.DrawText("Text row 1",250,150, Typeface.MONOSPACE,22,Colors.white,"RIGHT")
cnv.DrawText("Text row 2",250,200, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
cnv.DrawText("Text row 3",250,250, Typeface.MONOSPACE,22,Colors.White,"RIGHT")

(250,150) (250,200) (250,250) relative to the size of Panel1 on which you are writing.

So, let's say that the Panel1, in your working project, has Width = 320 and Height = 480:
the first text (250,150) will be in position (250/Panel1.Width, 150/Panel1.Height).

Should be so; if I'm wrong, shoot me, I do not think you hit me, hehehe.

(When the size of Panel1 vary, as those of the display vary, the proportions remain the same. The only problem is to adapt the TextSize. This is not easy, at least not for me, it depends also on the size of the display).

Meanwhile, you could try so, waiting for the more experienced and equipped (more recent B4A) Klaus.

Thank you Luca! kind as always! I'm gonna try this night.
For text size i could get the device size and then change the textsize according the device size, average solution but better than nothing. no?
Thanks for your effort in explaining the thing in both languages.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Is this what you are looking for ?
At least for your example code.
You need to adjust the positioning in percentage of the ImageView !
B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("main")
    cnv.Initialize(ImageView1)
End Sub

Sub Button1_Click
    Dim x0, y0, h As Int
    x0 = 0.07 * ImageView1.Width
    y0 = 0.16 * ImageView1.Height
    h = 0.285 * ImageView1.Height
    cnv.DrawText("Text row 1", x0, y0, Typeface.MONOSPACE,22,Colors.white,"LEFT")
    cnv.DrawText("Text row 2", x0, y0 + h, Typeface.MONOSPACE,22,Colors.White,"LEFT")
    cnv.DrawText("Text row 3", x0,y0 + 2 * h, Typeface.MONOSPACE,22,Colors.White,"LEFT")
    ImageView1.Invalidate
End Sub
 

Attachments

  • test_canvas_1.zip
    8.2 KB · Views: 170
  • Test1.png
    Test1.png
    14.2 KB · Views: 201
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Allora, intanto scrivo in italiano, che mi viene molto meglio :) then i'll try to translate.

Se il codice che hai pubblicato nel #24 funziona bene su un tuo dispositivo, tu dovresti calcolare la percentuale di quei valori:
B4X:
cnv.DrawText("Text row 1",250,150, Typeface.MONOSPACE,22,Colors.white,"RIGHT")
cnv.DrawText("Text row 2",250,200, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
cnv.DrawText("Text row 3",250,250, Typeface.MONOSPACE,22,Colors.White,"RIGHT")

(250,150) (250,200) (250,250) rispetto alle dimensioni di Panel1, sul quale stai scrivendo.

Quindi, poniamo il caso che il Panel1, nel tuo progetto funzionante, abbia Width = 320 e Height = 480,
il primo testo (250,150) sarà nella posizione (250/Panel1.Width,150/Panel1.Height).

Dovrebbe essere così, se sbaglio, sparami pure, tanto non mi cogli, hehehe

(al variare delle dimensioni del Panel1 perché variano quelle del display, le proporzioni rimangono le stesse. L'unico problema è adattare il TextSize. Questo non è facile, almeno non per me; dipende anche dalle dimensioni del display, un conto è un 3.5", altro un 12").
Intanto prova così, in attesa del più esperto e dotato (di versione di B4A recente :)).

Now I should translate, sigh and sob :(
___________________________________________________________________________________________________________________________

If the code you posted in #24 works well on your device, you should calculate the percentage of those values:
B4X:
cnv.DrawText("Text row 1",250,150, Typeface.MONOSPACE,22,Colors.white,"RIGHT")
cnv.DrawText("Text row 2",250,200, Typeface.MONOSPACE,22,Colors.White,"RIGHT")
cnv.DrawText("Text row 3",250,250, Typeface.MONOSPACE,22,Colors.White,"RIGHT")

(250,150) (250,200) (250,250) relative to the size of Panel1 on which you are writing.

So, let's say that the Panel1, in your working project, has Width = 320 and Height = 480:
the first text (250,150) will be in position (250/Panel1.Width, 150/Panel1.Height).

Should be so; if I'm wrong, shoot me, I do not think you hit me, hehehe.

(When the size of Panel1 vary, as those of the display vary, the proportions remain the same. The only problem is to adapt the TextSize. This is not easy, at least not for me, it depends also on the size of the display).

Meanwhile, you could try so, waiting for the more experienced and equipped (more recent B4A) Klaus.


As I watched the football game, I thought that the code was wrong.

In short, that "250" should be multiplied by the ratio of the width of the "original" panel and that of the "panel of various screens".


It is not clear, but I'm in a hurry

(fortunately arrived Klaus ... without trying, I'm sure that his code works :))
 
Upvote 0

Sub7

Active Member
Licensed User
Longtime User
Thanks for the patience and help
B4X:
x0 = 0.07 * ImageView1.Width  'Position from left
y0 = 0.16 * ImageView1.Height 'Position from the top
h = 0.285 * ImageView1.Height 'Spacing applied between the rows

I need to study better the things :)
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Comunque, dato che io "mi sono perso qualcosa" (frase grammaticamente sbagliata, ma ormai utilizzata da tutti... e poi, io mi sono perso davvero :))
perché ho visto che tu inizializzi il Canvas con un Panel, Klaus con una ImageView...

Summary translation: You have initialized the Canvas on a Panel, Klaus on an ImageView, so I did not follow the thread well :)

upload_2014-9-23_13-1-3.png
 
Last edited:
Upvote 0

Sub7

Active Member
Licensed User
Longtime User
Luca i was initializing the canvas over the panel because i did not know how to align it over the imageview, so the text was draw over the red panel just to make it visible, this has generate confusion.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I set the Canvas reference to ImageView1 because in the program the image is in ImageView1 !
Sure, this x1 = x * w1/w (and y1 = y * h1/h) works.
But you need to know the coordinates of x and y !
I adjusted x0, y0 , h to write the text at the right place on Sub7s' specific image.
And as they are proportional to the image dimensions they will fit in any view with this specific image in any View size using Gravity.Fill.
 
Last edited:
Upvote 0
Top