Synchronizing 2 Scrollviews

Bill Norris

Active Member
Licensed User
Longtime User
I have two scroll views, both same size. I have them synchronized using scrollposition, so that when either is scrolled, the scrollposition of the other one is set to equal. It works fine. I was concerned as it seems as though I am creating a loop, but apparently that is not the case. Is this a dangerous way to do this? I know I could put all the information on one scrollview, but I have a reason to keep them separate/

B4X:
sub sv1_scrollchanged(Position as int)
     sv2.scrollposition=sv1.scrollposition
end sub


sub sv2_scrollchanged(Position as int)
     sv1.scrollposition=sv2.scrollposition
end sub
 

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Your code is fine. ScrollView internally checks whether the new position is different than the old one. The event will not be raised if they are equal (which happens all the time in your code).

Is this true with ScrollView2D as well?

I have a ScrollView, HorizontalScrollView and a ScrollView2D and am trying to keep them all in Sync and seem to be getting in a loop.


B4X:
Sub cGrid_FixedColumns_VSV_ScrollChanged(Position As Int)
    If mInScrollChange Then Return

    Do While mGrid_Body_SV2D.ScrollingIsFinished = False
	   DoEvents
    Loop
	
	'#If _Debug Then 
	'    Log("Vert ScrollChange:" &Position)
    '#end if				
	
	mInScrollChange = True

	mGrid_Body_SV2D.Enabled                = False
    mGrid_Body_SV2D.VerticalScrollPosition = Position
	mGrid_Body_SV2D.Enabled                = True
		
    DoEvents		
	
	mInScrollChange = False		
End Sub

Sub cGrid_FixedHeader_HSV_ScrollChanged(Position As Int)
    If mInScrollChange Then Return

    Do While mGrid_Body_SV2D.ScrollingIsFinished = False
	   DoEvents
    Loop


	'#If _Debug Then 
	'    Log("Horz ScrollChange:" &Position)
    '#end if				

	mInScrollChange = True	

	mGrid_Body_SV2D.Enabled                   = False	
    mGrid_Body_SV2D.HorizontalScrollPosition = Position
    mGrid_Body_SV2D.HorizontalScrollPosition = Position	
	mGrid_Body_SV2D.Enabled                   = True
	
	DoEvents
	
	mInScrollChange = False	
End Sub
#End Region

Sub cGrid_Body_SV2D_ScrollChanged(PosX As Int, PosY As Int)
    Return
    If mInScrollChange Then Return
	
    Do While mGrid_Body_SV2D.ScrollingIsFinished = False
	   DoEvents
    Loop
	
    'Log("Both ScrollChange:" &PosX & " / " & PosY)
	
	mInScrollChange = True	

	mGrid_FixedHeader_HSV.Enabled         = False
	mGrid_FixedColumns_VSV.Enabled        = False
	
    mGrid_FixedHeader_HSV.ScrollToNow(PosX)
'	mGrid_FixedHeader_HSV.ScrollPosition  = PosX
'	mGrid_FixedColumns_VSV.ScrollPosition = PosY
	mGrid_FixedColumns_VSV.ScrollToNow(PosY)
	
	mGrid_FixedHeader_HSV.Enabled         = True
	mGrid_FixedColumns_VSV.Enabled        = True
	
    DoEvents	
	
	mInScrollChange = False		
End Sub

There is a lot of code above that I added to try and stop this but I keep getting into a bounce effect (HSV moves then SV2D then HSV moves back then SV2D moves back)

Is there ANY way of linking these where one moves then other so the move on the screen at the same time? One is always lagging.

Thanks for any help

BobVal
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
What I wound up doing is saving the last scroll positions and setting a timer for 350ms and then processing the last Scroll Position
Which is working well but not what I would like

What I am trying to do: (Remember I am retired and just trying to learn)

I want a Grid with Fixed Columns and Scrolling Header columns so this is what a did

Made a Panel to whole everything
Made a Panel for the Header of the Fixed Columns (must start with fixed columns if using them) and Make a HSV for the scrolling Header Columns
Made a SV for the Fixed Columns so the rows can scroll and Made a ScrollView2D to house the Scrolling Grid Rows / Columns

I am Attaching what I have working and you will sett the First Column will Scroll up and down but never left and right and the Header of the other columns will scroll left and right but never off the screen.

Right now I am using Red for the Cell Grid and Blue for the Cell Padding (just so I can see them while playing around) The colors and size are all changeable.

Just a days work so it is just a start.

Thanks for helping.

BobVal
 

Attachments

  • Grid.zip
    5.6 KB · Views: 266
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Nice work.

I see the problem you are getting into. The question is whether it is a must to a allow scrolling the side bars? If not then the solution becomes very simple:
B4X:
Sub s2d_ScrollChanged(PosX As Int, PosY As Int)
   ScrollView1.ScrollToNow(PosY)
   HorizontalScrollView1.ScrollToNow(PosX)
End Sub

You can add transparent panels over the side bars and handle their touch events to make them unscrollable.
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
Informatix:
I looked at that code and that gives me a fixed header on top for the Vertical but I also want on locked for the Horizontal.
The example did not have synchronizing but I will need to read the whole thread.

Erel:
To me the real problem is there is no way to set a position (in code) and not have the ScrollChange event fire.
Is there ANY way to disable an Event from being fired and then Enabling it again?
I will play around with your idea of transparent panels, after I bang my head against the wall more.

Grids with Fixed Columns and Fixed Headers are real world items, would not thought this would be so hard.

Was thinking of Disabling ALL the scroll bars and adding my own (kind of like Windows does on the left and right and using them to scroll / sync all the windows

Thanks for trying

BobVal
 
Upvote 0

RandomCoder

Well-Known Member
Licensed User
Longtime User
Is there ANY way to disable an Event from being fired and then Enabling it again
When you set the position in code, also set a global boolean. When the position changed event is fired, check if the boolean is set and if so ignore the rest of the sub. Reset the boolean within the position changed sub. That should work.

Regards,
RandomCoder
 
Upvote 0

Robert Valentino

Well-Known Member
Licensed User
Longtime User
OK, this is how I handled this. I did some what Erel suggested but then so.

I Put a Panel OVER the whole screen (right now using Colors.ARGB(20, 0, 0, 32) as it's color)

Then I get the Touch's and set the scroll positions on the 3 different Scrolls. I try to snap to Columns / Rows if possible

The movement is not bad and it gives me what I need a N amount of fixed starting columns and a Fixed header that scrolls.

I might have to discard every N movement so it is not so touchy


It's a start of something, now I have to turn it into a complete Grid with all the flavors.

Thanks for all the help guys

BobVal

PS: Attaching latest version, in Release mode works real nice in Debug mode I have a lot of Log commands that make it a little sluggest.
 

Attachments

  • Grid.zip
    6.4 KB · Views: 240
Upvote 0
Top