Android Tutorial ScrollView example

The ScrollView is a very useful container which allows you to show many other views on a small screen.
The ScrollView holds an inner panel view which actually contains the other views.
The user vertically scrolls the inner panel as needed.

In this example we will load images from the sdcard and add those to a ScrollView.

scrollview1.png


Adding views to a ScrollView is done by calling:
B4X:
ScrollView.Panel.AddView(...)
In order to avoid "out of memory" errors we use LoadBitmapSample instead of LoadBitmap. LoadBitmapSample accepts two additional parameters: MaxWidth and MaxHeight. When it loads a bitmap it will first get the bitmap original dimensions and then if the bitmap width or height are larger than MaxWidth or MaxHeight the bitmap will be subsampled accordingly. This means that the loaded bitmaps will have lower resolution than the original bitmap. The width / height ratio is preserved.

The following code sets the inner panel height and adds an ImageView for each loaded bitmap:
B4X:
    ScrollView1.Panel.Height = 200dip * Bitmaps.Size 'Set the inner panel height according to the number of images.
    For i = 0 To Bitmaps.Size - 1
        Dim iv As ImageView 'create an ImageView for each bitmap
        iv.Initialize("") 'not interested in any events so we pass empty string.
        Dim bd As BitmapDrawable
        bd.Initialize(Bitmaps.Get(i))
        iv.Background = bd 'set the background of the image view.
        'add the image view to the scroll bar internal panel.
        ScrollView1.Panel.AddView(iv, 5dip, 5dip + i * 200dip, ScrollView1.Width - 10dip, 190dip)
    Next
The code that is loading the bitmaps looks for jpg files under /sdcard/Images

If you want to run this program on the emulator you will first need to create this folder and copy some images to it.
This is done with the "adb" command, that comes with Android SDK.
Open a shell console (Windows Start - Run - Cmd).
Go to the sdk tools folder and issue:
B4X:
c:\android-sdk-windows\tools> adb -e shell mkdir /sdcard/Images
The -e parameter tells adb to send the command to the only connected emulator.
The command is mkdir with the name of the folder.
Note that Android file system is case sensitive.

Now we need to copy some images to this folder.
This is done with the push command:
B4X:
adb -e push "C:\temp" /sdcard/Images
This will copy all files under c:\temp to the Images folder.

The emulator is very slow compared to a real device. While on a real device 50 large images load in 2-3 seconds. It can take a long time for the emulator to load a few small images. I recommend you to copy 2 - 3 small images at most.

Also the experience of the ScrollView on the emulator cannot be compared to a real device (with capacitive screen).

The program is available here: http://www.basic4ppc.com/android/files/tutorials/ScrollView.zip
 

little3399

Active Member
Licensed User
HI,if I want to select a image , and show it in another activity , how to do ? TKS!
in this tutorial example !
 

klaus

Expert
Licensed User
You should study the code of the tutorial to understand how it works.
Then you should look for examples with two or more activities to understand how these work.
And then try on your own to modify the tutorial to fulfill what you want.
That's the BEST way to learn.
 

Bpick

Member
Licensed User
I seem to be doing something wrong.

I've used the iv_click procedure in an app. I told it to toast message me the filename but using this:
B4X:
Dim send As View
Dim Bda As BitmapDrawable
Dim iview As ImageView

send=Sender
ToastMessageShow("Send.tag:"& send.Tag, True)
Log("Send.tag:"&send.Tag)

Bda.Initialize(Bitmaps.Get(send.Tag))

iview=ScrollView1.Panel.GetView(send.Tag)
iview.Gravity=Gravity.NO_GRAVITY
'iview.Color=Colors.Gray
'iview.Background=Bda

But I'm not getting any messages.

Any suggestions?
 

Bpick

Member
Licensed User
Erel, I'm talking straight out of the box demo on page 1/post 1 and then the code snippet above.
 

eps

Expert
Licensed User
trace through the code... using debug

or use log to 'see' where the code goes, it probably isn't reaching your code, for whatever reason.
 

Bpick

Member
Licensed User
This is my log:
LogCat connected to: B4A-Bridge: LGE LGL75C-A00000341777B1
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
** Activity (main) Pause, UserClosed = false **
** Activity (main) Resume **
** Service (service1) Create **
** Service (service1) Start **
Connected to B4A-Bridge (Wifi)
Installing file.
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:anywheresoftware.b4a.samples.scrollview
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
java.io.IOException: setDataSource failed.: status=0x80000000
at android.media.MediaPlayer.setDataSource(Native Method)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:945)
at android.media.MediaPlayer.setDataSource(MediaPlayer.java:700)
at com.android.server.NotificationPlayer$CreationAndCompletionThread.run(NotificationPlayer.java:93)
 

Bpick

Member
Licensed User
I didn't even see that in the log.

I've decided to use a different method. So far, so good.
 

santiago

Member
Licensed User
Hello Erel :

I run the example but I added a button to delete a selected row.

When I click on the row, I know its number (xrow)
Then in the button_click add this code :

Table.RemoveViewAt(xrow)

I have no error , but :

a) The table don´t delete the row
b) from that moment , when I click in a row a message appear : Object should be initialized (view)

I try table.initialize(0) but the same problem .

I beg your pardon if is a simple mistake but it is aproblem for me
Thanks for your time
Santiago
 

santiago

Member
Licensed User
Dear Sir :
Thanks for your quick response.

First I must tell you that ypur example fits my needs, because must use a table.(I think the customListview is no good ).On the other hand I used your example and it is working fine ( the truth , I don't understand it well ,but I customize to my needs.Thanks )
The problem I have , and maybe I did not explain well , is I am not able to delete a row . I am 'insvestigating' a lot but I am not able to fix the problem.

I have a table.It has 3 columns. And 5 rows.

If I want to delete the 2th row and I wrote this code :

sub removerow (nrow as int)

'nrow will be 1
Table.RemoveViewAt(nrow)
end sub

Happens to delete only a cell ( or at real, only the central cell is on white) The others cells does not change,not moves.

Could you help ?
Thanks in advance for your patience and your time.

Santiago
 

santiago

Member
Licensed User
Dear Klaus and Erel

Thanks.

I just solved the issue five minutes ago.
I will relate how I did it.

In the example Erel wrote I only change the original 4 columns to 3 columns .
When I click a row I adquire its number in nnrows variable


Well , first I dicovered how to delete the entire row, not a cell , but when I did that , the empty row did not dissapear, it was in "blank"
Then I moved all cells to "cover " the row I want to eliminate and then delete the last row .


I added a button to delete named Bdel

In the event Bdel_click add this code :

Dim a5,a2,a3 As Int
Dim c1,c2,c3 As String
a5=nnrows

For n=a5+1 To NumberOfRows-1

c1=GetCell(n,0)
c2=GetCell(n,1)
c3=GetCell(n,2)
SetCell(n-1,0,c1)
SetCell(n-1,1,c2)
SetCell(n-1,2,c3)

Next

a5=NumberOfRows-1
a2=a5*3
a3=a2+2

'here I delete the last row
For n=a3 To a2 Step -1
Table.RemoveViewAt(n)
Next
SelectedRow = -1

I move the information from each cell up one step , at last I remove the 3 panel in the row (table.removeviewat(n) )
and it woks fine.
The only problem it is the user can view the las line in white .I mean , the last line I removed don't "go away" but if I add a new row it is added in that line without problem .And if I save the grid the system does not count the blank line .

It works for me , but by the moment I don't know how to clean the grid and take off in a visual way the last row .


Well I beg my pardon for my English . I am not able to explain well .
And Thanks for your interes and your time

If you need it , I will send the file

Sincerely :
Santiago
 

klaus

Expert
Licensed User
Then I moved all cells to "cover " the row I want to eliminate and then delete the last row .
You must adjust the height of the internal Panel of the ScrollView.
 

oceanwanderlust

Member
Licensed User
How do I keep the images from being distorted when I expand this example to full screen? I'm trying the following:

ScrollView1.Height = 100%y
ScrollView1.Width = 100%x
.
.
ScrollView1.Panel.AddView(iv, 5dip, 5dip + i * 200dip, iv.Width, 190dip)

iv.Width is undefined at runtime, but at runtime iv.mBitmapHeight has the value I need.

ANSWER: I've moved on to the CustomListViewClass, using the TextPlusImage example:
http://www.basic4ppc.com/android/fo...-based-on-scrollview.19567/page-6#post-163703
 
Last edited:

sasetcolombia

Member
Licensed User
how to detect the click event of the charged images?
solution 1:
....
For i = 0To Bitmaps.Size - 1
Dim iv AsImageView'create an ImageView for each bitmap
' iv.Initialize("") 'not interested in any events so we pass empty string.
iv.Initialize("imgEvent"&i)' creating an event, according to the value of i
Dim bd AsBitmapDrawable
bd.Initialize(Bitmaps.Get(i))
iv.Background = bd 'set the background of the image view.
....
methods associated with each imageview would be like this ...
Sub imgEvent0_Click
ToastMessageShow("0",False)
End Sub
Sub imgEvent1_Click
ToastMessageShow("1",False)
End Sub
Sub imgEvent2_Click
ToastMessageShow("2",False)
End Sub
....
Solution 2:
...
iv.Initialize("imgEvent")' create the same event for all imageview
iv.Tag=""&i 'associated as tag, the value of i
...
in the event ...

Sub imgEvent_Click
Dim send As ImageView '
send = Sender

Select Case send.Tag
Case "0"
ToastMessageShow("0",False)
Case "1"
ToastMessageShow("1",False)
Case "2"
ToastMessageShow("2",False)
'...

End Select
End Sub
 
Last edited:
Top