Scrollview widget .. can I change params after initial creation?

I’m trying to create a scrollview object before I know how big an area I really need.  Is it possible to create the scrollview object first, then either:

  1. Resize the object – i.e. reset scrollHeight to the value I really need
  2. Set/unset “isLocked” after creation – i.e. start it with “isLocked=true”, then I can un-lock it when I know if the content will spill over one screen
  3. Custom event listener – i.e. I could set a file-local variable that is the “max-scroll” setting, and if the scrollview-listener exceeds that, I could maybe stop it from scrolling further

Any thoughts?

Are any scrollview settings re-configurable after the initial object creation?

John

Hi John, 

I don’t believe you can change the size of scrollView once its set. I have a similar use case to handle device orientation change and I end up doing a purgeScene and gotoScene to recreate the whole deal. 

As for #2, the isLocked is not exposed after creation but we were told at some point this will be fixed. In the meanwhile you can use 

scrollView._view._isVerticalScrollingDisabled = true to lock vertical and 

scrollView._view._isHorizontalScrollingDisabled = true for horizontal or both as you need.

For #3, not sure if this will do the trick but play with the scrollWidth, scrollHeight settings of your scrollView. These are supposed to create a limit of scrollable content so it sounds like it might do what you are trying to do with a listener etc. 

Best of luck. Regards,

Kerem

Hey John,

I had the same problem, I was creating the scrollView before I knew my content height.

FWIW, I’ma newb, so your mileage may vary.

I haven’t migrated to widget 2.0, but for widget-v1, you can set the scrollHeight to the proper size you need “after” the scrollView is created.  It couldn’t be done if Corona hadn’t open sourced the widget-v1 code, thank you guys!  I had to add my own function to the scrollview widget-v1 to make it happen and so can you.

I can’t believe this feature wasn’t ever implemented.  I would think this strategy could be used with widget2.0, but not sure.

Here’s how I did it, it’s quite simple.  You need to modify the open source widget module and add it to your project.

In your main.lua or whatever module.lua you are in…

I’m assuming you are spawning your content into a table.

Implement a “Count” variable and for each iteration of your content you spawn to keep track of how large you want your scrollHeight to be.

<code>

local function createDynamicScrollView()

    local CatagoryScroll = widgetV1.newScrollView{
        hideBackground = true,
        width = 420,
        height = 300,
        left = 0,
        top = 50,
        scrollWidth = 420,
        scrollHeight = 3000,   --original scrollHeight doesn’t matter, it will be changed later    
        friction, .935,  --default is .935
        --onEvent = onButtonEvent,
        bgColor = {255,255,255, 0},  --make transparent here, set value to “0”
        maskFile=“CatagoryMask440x300.png”,
        --listener = onButtonEvent,
    }
    
    print("----------Flag1–CatagoryScrolll.widgetScrollHeight == ", CatagoryScroll.widgetScrollHeight)  --should be 3000, the value declared when the scrollview was created.  I added the .widgetScrollHeight variable to the scrollView widget-v1 so I could dynamically alter it after it was created.
    
    CatagoryScroll.isHitTestMasked = true
  
    ScrollViewReportsGroup:insert(CatagoryScroll)

– now spawn your content

Count = 0

for i = 1, #table do  --table holds your content in this example

Count = Count + 1  --keep track of how many “content lines or spaces you need”

ScrollViewObject[i] = display.newText("table[i].text, 0, 0, “Helvetica”, 18)

ScrollViewObject[i].x = 20

ScrollViewObject[i].y = i * 35

CatagoryScroll:insert(ScrollViewObject[i])

end

print("----------Flag1–CatagoryScroll.widgetScrollHeight == ", CatagoryScroll.widgetScrollHeight)

    CatagoryScroll.widgetScrollHeight = (Count * 25) + 80  --here is where you mutiply (Count * whatever spacing you need) to dynamically set the proper scrollHeight you want.  In my case, I need 25 pixels for each line and I have 80 pixels worth of text above the dynamically generated content I need to account for.

    print("----------Flag2–CatagoryScrolll.widgetscrollHeight == ", CatagoryScroll.widgetScrollHeight)    --should display the new value that was just set

 
    CatagoryScroll:changeScrollHeight()  --dynamically sets scrollHeight!!!   This calls the function I added to the scrollView widget-v1,  I’ll show it below.

end

</code>

Here’s how I modified the scrollView widget in widget-v1.

<code>

–@ widget-v1 line 1871, in local function createScrollView( options ) ,I add this variable I can modifiy from the lua module where the dynamic scrollView was created

        scrollView.widgetScrollWidth = scrollWidth  --I added this variable to dynamically set the scrollWidth value from another module

        scrollView.widgetScrollHeight = scrollHeight  --I added this variable to dynamically set the scrollHeight value from another module

– then below the " local function createScrollView( options ) " I added this function that destorys the contentBg object (this determines the scrollHeight of the scrollView), and replaces the scrollWidth and scrollHeight orginally declared when the scrollView was created with the new dynamic values and spawns the new contentBg object needed.

–my function to change scrollHeight, warning, I haven’t checked this for memory leaks.

        function scrollView:changeScrollHeight()  --this function gets called from the last line of my module.lua above
            scrollHeight = scrollView.widgetScrollHeight
            scrollWidth = scrollView.widgetScrollWidth
            print("scrollHeight == ", scrollHeight)
            
            display.remove(contentBg)
            contentBg = nil
            
            – create a background for actual content
            local contentBg = display.newRect( 0, 0, scrollWidth, scrollHeight )
            contentBg:setFillColor( 255, 100 )
            contentBg.isVisible = false
            content:insert( 1, contentBg )
            
            --contentBg.height = scrollView.widgetScrollHeight
            print("contentBg.height == ", contentBg.height)  --should print your new dynamically created scrollHeight value :slight_smile:
        end

</code>

Nice!  Now you have perfectly sized scrollViews that properly display your dynamically created content perfectly which bounces back at the bottom of you content just as a user would expect.

I hope this helps or at least points you in the right direction.

Ahhh!!  Thank you to both ksan and xnailbender!

I had started thinking about a background image to get around some other scrollview issue (doesn’t always stay scrolled if there is dynamic content past the end of the window).

I think I’ve got everything working now … or at least close enough to get me hacking again.

Glad you are getting it sorted. You can also try 

bottomPadding = 150,

in your scrollView definition. This helped me with the issue of not staying scrolled down at the end of the range. 

Hi John, 

I don’t believe you can change the size of scrollView once its set. I have a similar use case to handle device orientation change and I end up doing a purgeScene and gotoScene to recreate the whole deal. 

As for #2, the isLocked is not exposed after creation but we were told at some point this will be fixed. In the meanwhile you can use 

scrollView._view._isVerticalScrollingDisabled = true to lock vertical and 

scrollView._view._isHorizontalScrollingDisabled = true for horizontal or both as you need.

For #3, not sure if this will do the trick but play with the scrollWidth, scrollHeight settings of your scrollView. These are supposed to create a limit of scrollable content so it sounds like it might do what you are trying to do with a listener etc. 

Best of luck. Regards,

Kerem

Hey John,

I had the same problem, I was creating the scrollView before I knew my content height.

FWIW, I’ma newb, so your mileage may vary.

I haven’t migrated to widget 2.0, but for widget-v1, you can set the scrollHeight to the proper size you need “after” the scrollView is created.  It couldn’t be done if Corona hadn’t open sourced the widget-v1 code, thank you guys!  I had to add my own function to the scrollview widget-v1 to make it happen and so can you.

I can’t believe this feature wasn’t ever implemented.  I would think this strategy could be used with widget2.0, but not sure.

Here’s how I did it, it’s quite simple.  You need to modify the open source widget module and add it to your project.

In your main.lua or whatever module.lua you are in…

I’m assuming you are spawning your content into a table.

Implement a “Count” variable and for each iteration of your content you spawn to keep track of how large you want your scrollHeight to be.

<code>

local function createDynamicScrollView()

    local CatagoryScroll = widgetV1.newScrollView{
        hideBackground = true,
        width = 420,
        height = 300,
        left = 0,
        top = 50,
        scrollWidth = 420,
        scrollHeight = 3000,   --original scrollHeight doesn’t matter, it will be changed later    
        friction, .935,  --default is .935
        --onEvent = onButtonEvent,
        bgColor = {255,255,255, 0},  --make transparent here, set value to “0”
        maskFile=“CatagoryMask440x300.png”,
        --listener = onButtonEvent,
    }
    
    print("----------Flag1–CatagoryScrolll.widgetScrollHeight == ", CatagoryScroll.widgetScrollHeight)  --should be 3000, the value declared when the scrollview was created.  I added the .widgetScrollHeight variable to the scrollView widget-v1 so I could dynamically alter it after it was created.
    
    CatagoryScroll.isHitTestMasked = true
  
    ScrollViewReportsGroup:insert(CatagoryScroll)

– now spawn your content

Count = 0

for i = 1, #table do  --table holds your content in this example

Count = Count + 1  --keep track of how many “content lines or spaces you need”

ScrollViewObject[i] = display.newText("table[i].text, 0, 0, “Helvetica”, 18)

ScrollViewObject[i].x = 20

ScrollViewObject[i].y = i * 35

CatagoryScroll:insert(ScrollViewObject[i])

end

print("----------Flag1–CatagoryScroll.widgetScrollHeight == ", CatagoryScroll.widgetScrollHeight)

    CatagoryScroll.widgetScrollHeight = (Count * 25) + 80  --here is where you mutiply (Count * whatever spacing you need) to dynamically set the proper scrollHeight you want.  In my case, I need 25 pixels for each line and I have 80 pixels worth of text above the dynamically generated content I need to account for.

    print("----------Flag2–CatagoryScrolll.widgetscrollHeight == ", CatagoryScroll.widgetScrollHeight)    --should display the new value that was just set

 
    CatagoryScroll:changeScrollHeight()  --dynamically sets scrollHeight!!!   This calls the function I added to the scrollView widget-v1,  I’ll show it below.

end

</code>

Here’s how I modified the scrollView widget in widget-v1.

<code>

–@ widget-v1 line 1871, in local function createScrollView( options ) ,I add this variable I can modifiy from the lua module where the dynamic scrollView was created

        scrollView.widgetScrollWidth = scrollWidth  --I added this variable to dynamically set the scrollWidth value from another module

        scrollView.widgetScrollHeight = scrollHeight  --I added this variable to dynamically set the scrollHeight value from another module

– then below the " local function createScrollView( options ) " I added this function that destorys the contentBg object (this determines the scrollHeight of the scrollView), and replaces the scrollWidth and scrollHeight orginally declared when the scrollView was created with the new dynamic values and spawns the new contentBg object needed.

–my function to change scrollHeight, warning, I haven’t checked this for memory leaks.

        function scrollView:changeScrollHeight()  --this function gets called from the last line of my module.lua above
            scrollHeight = scrollView.widgetScrollHeight
            scrollWidth = scrollView.widgetScrollWidth
            print("scrollHeight == ", scrollHeight)
            
            display.remove(contentBg)
            contentBg = nil
            
            – create a background for actual content
            local contentBg = display.newRect( 0, 0, scrollWidth, scrollHeight )
            contentBg:setFillColor( 255, 100 )
            contentBg.isVisible = false
            content:insert( 1, contentBg )
            
            --contentBg.height = scrollView.widgetScrollHeight
            print("contentBg.height == ", contentBg.height)  --should print your new dynamically created scrollHeight value :slight_smile:
        end

</code>

Nice!  Now you have perfectly sized scrollViews that properly display your dynamically created content perfectly which bounces back at the bottom of you content just as a user would expect.

I hope this helps or at least points you in the right direction.

Ahhh!!  Thank you to both ksan and xnailbender!

I had started thinking about a background image to get around some other scrollview issue (doesn’t always stay scrolled if there is dynamic content past the end of the window).

I think I’ve got everything working now … or at least close enough to get me hacking again.

Glad you are getting it sorted. You can also try 

bottomPadding = 150,

in your scrollView definition. This helped me with the issue of not staying scrolled down at the end of the range. 

I had a very similar question for v2 widgets - posted it here:  http://forums.coronalabs.com/topic/44938-newscrollview-does-it-support-resizing-for-orientation-changes-within-storyboardcomposer/

I had a very similar question for v2 widgets - posted it here:  http://forums.coronalabs.com/topic/44938-newscrollview-does-it-support-resizing-for-orientation-changes-within-storyboardcomposer/

I also have problems using a tableVIew with a scrollView. Adding the second one messes up all views on android device.

I also have problems using a tableVIew with a scrollView. Adding the second one messes up all views on android device.