Android Question Center an ImageView on a Panel

schemer

Active Member
Licensed User
I made a full size panel and added a smaller ImageView to it. I am trying to center the ImageView on the panel but it seems using the SetLayout it always centers on the left edge of the ImageView. What am I missing?
Thanks,
schemer
 

schemer

Active Member
Licensed User
without seeing what you have done and how it i hard to give advices.

Maybe you set the horizontal anchor to left
B4X:
'SetLayout
    Panel1.SetLayout(0%x,0%y,100%x,100%y)
   
    ImageView1.SetLayout(50%x,60%y,100dip,100dip)
I tried changing the anchor setting earlier but it did not seem to matter.
Thanks,
schemer
 

schemer

Active Member
Licensed User
Ahhh, ok. Let me try that. ;)
Thanks,
schemer
Still having the same result. Question: When an imageview is added and no image is specified in the designer, I still get a white box showing on the screen when I run the app. The box is in the same position as when I tried setting the imageview with the setLayout. Now I have :

B4X:
ImageView1.Left = 50%x
ImageView1.Top = 50%y
What controls the size of that white box? Can I change it? How do I center the white box (or image)? I tried /2 etc but no luck. I must be missing something simple here. If I change the anchor it just moves the 200 around so I am assuming that is the default spacing from the edge.
Thanks,
schemer
 

NJDude

Expert
Licensed User
If you are using the designer scripts then you should have thing like this:
B4X:
thePanel.SetLeftAndRight(0dip, 100%x)
thePanel.SetTopAndBottom(0dip, 100%y)

myImageView.HorizontalCenter = thePanel.Width / 2
myImageView.VerticalCenter = thePanel.Height / 2
Assuming of course you have the ImageView inside the panel.
 
Last edited:

schemer

Active Member
Licensed User
If you are using the designer scripts then you should have thing like this:
B4X:
thePanel.SetLeftAndRight(0dip, 100%x)
thePanel.SetTopAndBottom(0dip, 100%y)

myImageView.HorizontalCenter = thePanel.Width / 2
myImageView.VerticalCenter = thePanel.Height / 2
Assuming of course you have the ImageView inside the panel.
I was reading about the .SetLeftAndRight but in the IDE (main code editor) it does not show up on autocomplete? I guess I am supposed to be in the designer script section. :confused: So this cannot be done in the IDE?
Thanks,
schemer

p.s. That works great as I just tested it. Thank you. :)
 

schemer

Active Member
Licensed User
The code I posted is to be used with the designer scripts.
Yes and it works great. But I am still wondering if the same can be done in the main code editor or if I should just focus on the designer scripts from now on? Is that the preferred way of doing it? I want to develop good habits right away with B4A.
Thanks again,
schemer
 

NJDude

Expert
Licensed User
The best way is to use the designer, keeps your code tidy, all the "layout" stuff is on the designer and the "logic" on the IDE, however, if you still want to create your layouts by code then the code I posted has to be modified, so yes, it is also possible.
 

schemer

Active Member
Licensed User
The best way is to use the designer, keeps your code tidy, all the "layout" stuff is on the designer and the "logic" on the IDE, however, if you still want to create your layouts by code then the code I posted has to be modified, so yes, it is also possible.
Thank you. That will be the way I proceed for now as it looks easier.
schemer
 

Anser

Well-Known Member
Licensed User
If you are using the designer scripts then you should have thing like this:
B4X:
thePanel.SetLeftAndRight(0dip, 100%x)
thePanel.SetTopAndBottom(0dip, 100%y)

myImageView.HorizontalCenter = thePanel.Width / 2
myImageView.VerticalCenter = thePanel.Height / 2
Assuming of course you have the ImageView inside the panel.
If I am not using designer script, ie I am adding views via code, then what would be the best way to center the Image view on a Panel. When we add views by code, I don't find the HorizontalCenter property in the ImageView.

I am also using the following code to adjust the imageview's position based on the Picture/Bitmaps aspect ratio. Thanks to Klaus for the code snippet
B4X:
Sub AdjustImageView(oImgView As ImageView, oBitmap As Bitmap)
    Dim Delta, Height, Width As Int
    If oBitmap.Width / oBitmap.Height > oImgView.Width / oImgView.Height Then
        Height = oBitmap.Height / oBitmap.Width * oImgView.Width
        Delta = (oImgView.Height - Height) / 2
        oImgView.Height = Height
        oImgView.Top = oImgView.Top + Delta
    Else
        Width = oBitmap.Width / oBitmap.Height * oImgView.Height
        Delta = (oImgView.Width - Width) / 2
        oImgView.Width = Width
        oImgView.Left = oImgView.Left + Delta
    End If
    oImgView.Gravity = Gravity.FILL
    oImgView.Bitmap = oBitmap
End Sub
It is working almost fine in Portrait mode, but when I rotate the device to Landscape the ImageView is left aligned in the Panel.

I need the ImageView to be displayed Horizontaly Centered in both Portrait and Landscape mode and the ImageView should adjust itself based on the Bitmap's/picture's ratio, so that the image is not stretched and distorted.

Any help will be appreciated

Regards
Anser
 
Last edited:

Anser

Well-Known Member
Licensed User
I am herewith sharing the code.

Using CustomListView and MSCardView is added to the CustomListView
B4X:
Sub BuildCustomListView(result As DBResult)
    'This is the CustomList View Control
    clvSchemes.Clear
    For Each records() As Object In result.Rows
    
        'Creating the Panel and other views to be placed on the Panel. Finally this Panel is added to the CustomListView
        Dim oPanel As Panel
        oPanel.Initialize("")
        oPanel.Color = Colors.White
    
        'This MSCardView will hold the Image Title and the Image. This CardView will be added to the above Panel
        Dim oMsCardView As MSCardView
        oMsCardView.Initialize("")
        oMsCardView.MaxElevation = 4dip
        oMsCardView.Elevation = 4dip
        oMsCardView.Radius = 12    
    
        'The label used to display the ImageTitle on the MSCardView
        Dim oLblSchemeName As Label
        oLblSchemeName.Initialize("")
        oLblSchemeName.Text = records(result.Columns.Get("Title"))
        oLblSchemeName.Gravity = Gravity.CENTER_HORIZONTAL
        oLblSchemeName.TextSize = 18
        oLblSchemeName.TextColor = Colors.Gray
        oLblSchemeName.Typeface = Typeface.DEFAULT_BOLD    

    'This is to read image Data from Table and convert it to a Bitmap and the Bitmap will be displayed on the ImageView
        Dim Buffer() As Byte
        Dim oBitmap As Bitmap
      Buffer = records(result.Columns.Get("Picture_Small"))
        If Buffer = Null Then
        Else
            oBitmap = reqManager.BytesToImage(Buffer)
        End If
    
        Dim oImgView As ImageView
        oImgView.Initialize("")
        oImgView.Bitmap = oBitmap
        oImgView.Gravity = Gravity.FILL
    
    ' Adding MSCardView to the Panel. This should be done first before setting the height and other properties of MsCardView
        oPanel.AddView(oMsCardView  ,0%x  , 05dip, 98%x , 225dip )

        'Setting up MsCardView Properties. Please note that this can be done only after adding MsCardView to the Panel as given above
        oMsCardView.Height = 245dip
        oMsCardView.Panel.AddView(oLblSchemeName  ,0%x  , 10dip, 100%x , 25dip )
        oMsCardView.Panel.AddView(oImgView        ,02%x , 30dip, 330dip, 200dip)

        ' Now Add Panel to the CustomListView
        clvSchemes.Add(oPanel, 255dip, records(result.Columns.Get("ID")) )

        'Adjust the ImageView based on the Picture's display ratio
        AdjustImageView(oImgView, oBitmap, oPanel)
    
    Next

End Sub

Sub AdjustImageView(oImgView As ImageView, oBitmap As Bitmap, oPanel As Panel)
  Dim Delta, Height, Width As Int
  If oBitmap.Width / oBitmap.Height > oImgView.Width / oImgView.Height Then
  Height = oBitmap.Height / oBitmap.Width * oImgView.Width
  Delta = (oImgView.Height - Height) / 2
  oImgView.Height = Height
  oImgView.Top = oImgView.Top + Delta
  Else
  Width = oBitmap.Width / oBitmap.Height * oImgView.Height
  Delta = (oImgView.Width - Width) / 2
  oImgView.Width = Width
  oImgView.Left = oImgView.Left + Delta
  End If
  oImgView.Gravity = Gravity.FILL
     'oImgView.Left = ( oPanel.Width - Width)/2  'Not Working so commented out
     'oImgView.Top = (oPanel.Height - Height)/2  'Not Working so commented out
  oImgView.Bitmap = oBitmap
End Sub
It is working almost fine in Portrait mode, but when I rotate the device to Landscape the ImageView is left aligned in the Panel.
If I uncomment the lines 'oImgView.Left = ( oPanel.Width - Width)/2 in the Sub AdjustImageView, then ImageView is Right Aligned

I need the ImageView to be displayed Horizontaly Centered in both Portrait and Landscape mode and the ImageView should adjust itself based on the Bitmap's/picture's ratio, so that the image is not stretched and distorted.

Any help will be appreciated.

Regards
Anser
 

Ohanian

Active Member
Licensed User
Hi,

try this :
B4X:
oImgView.Gravity = Bit.OR(Gravity.FILL , Gravity.CENTER)
 

Anser

Well-Known Member
Licensed User
try this :
B4X:
oImgView.Gravity = Bit.OR(Gravity.FILL , Gravity.CENTER)
Ohanian,Thank you for the help. Unfortunately Bit.OR(Gravity.FILL , Gravity.CENTER) did not resolve the issue.

Can you post a small project showing the problem so we could test it.
Shall try to post as a project to test it here.

Regards

Anser
 

Anser

Well-Known Member
Licensed User
Can you post a small project showing the problem so we could test it.
Here is a sample project that demonstrates the issue.

Screen Snapshot Portrait Mode



Screen Snapshot Landscape Mode



B4X:
#Region  Project Attributes
    #ApplicationLabel: ImgView Centered
    #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
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.

End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.

    Private clvSchemes As CustomListView
End Sub

Sub Activity_Create(FirstTime As Boolean)
    'Do not forget to load the layout file created with the visual designer. For example:
    Activity.LoadLayout("Main")
  
    PrepareClv
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub

Sub PrepareClv
    Dim i As Int : i=1
    Dim cImageName As String
  
    clvSchemes.Clear
  
    For i=1 To 6
      
        'Image File names. For Eg Picture1.png, Picture2.png, Picture3.png
        cImageName="Picture" & i & ".png"
      
        'Creating the Panel and other views to be placed on the Panel. Finally this Panel is added to the CustomListView
        Dim oPanel As Panel
        oPanel.Initialize("")
        oPanel.Color = Colors.White      
      
        'The label used to display the Image Title
        Dim oLblTitle As Label
        oLblTitle.Initialize("")
        oLblTitle.Text = cImageName
        oLblTitle.Gravity = Gravity.CENTER_HORIZONTAL
        oLblTitle.TextSize = 18
        oLblTitle.TextColor = Colors.Gray
        oLblTitle.Typeface = Typeface.DEFAULT_BOLD      
      
        ' Create Bitmap
        Dim oBitmap As Bitmap
        oBitmap.Initialize(File.DirAssets, cImageName)
      
        Dim oImgView As ImageView
        oImgView.Initialize("")
        oImgView.Bitmap = oBitmap  
        'oImgView.Gravity = Gravity.FILL  
      
        oPanel.AddView(oLblTitle  ,0%x  , 10dip, 100%x , 25dip )
        oPanel.AddView(oImgView   ,02%x , 30dip, 330dip, 200dip)      
      
        'Adjust ImageView based on the the Original Pictures aspect Ratio, so that the image is not stretched or disorted
        AdjustImageView(oImgView, oBitmap, oPanel)                  
      
        ' Now Add Panel to the CustomListView
        clvSchemes.Add(oPanel, 255dip, i )  

      
    Next
End Sub

Sub AdjustImageView(oImgView As ImageView, oBitmap As Bitmap, oPanel As Panel)
    Dim Delta, Height, Width As Int
    If oBitmap.Width / oBitmap.Height > oImgView.Width / oImgView.Height Then
        Height = oBitmap.Height / oBitmap.Width * oImgView.Width
        Delta = (oImgView.Height - Height) / 2
        oImgView.Height = Height
        oImgView.Top = oImgView.Top + Delta
    Else
        Width = oBitmap.Width / oBitmap.Height * oImgView.Height
        Delta = (oImgView.Width - Width) / 2
        oImgView.Width = Width
        oImgView.Left = oImgView.Left + Delta
    End If
    'oImgView.Gravity = Gravity.FILL
    oImgView.Gravity = Bit.Or(Gravity.FILL , Gravity.CENTER)
    'oImgView.Left = ( oPanel.Width - Width)/2
    'oImgView.Top = (oPanel.Height - Height)/2
    oImgView.Bitmap = oBitmap
End Sub
The Project is also attached herewith

Any help will be appreciated.

Thanks & Regards

Anser
 

Attachments

klaus

Expert
Licensed User
Attached you find a modified version of your code.
In your code you called AdjustImageView before adding the Panel !
The width of the panel was not known and throught an error.
Made some other changes for the vertical position of the image.
 

Attachments

Top