Android Code Snippet [B4X] Animated change of theme / layouts


This is an example that demonstrates how Root.Snapshot + 2 BitmapCreators, with the old and new layouts can be used to create a nice transition between two layouts.

B4X:
Private Sub SetNewTheme As ResumableSub
    If bc1.IsInitialized = False Then
        bc1.Initialize(Root.Width, Root.Height)
        bc2.Initialize(Root.Width, Root.Height)
        ImageViewForAnimation.Initialize("")
    End If
    If ImageViewForAnimation.As(B4XView).Parent.IsInitialized Then Return True 'already in progress...
    bc1.CopyPixelsFromBitmap(Root.Snapshot)
    UpdateTheme
    bc2.CopyPixelsFromBitmap(Root.Snapshot)
    Root.AddView(ImageViewForAnimation, 0, 0, Root.Width, Root.Height)
    bc1.SetBitmapToImageView(bc1.Bitmap, ImageViewForAnimation)
    Dim brush As BCBrush = bc1.CreateBrushFromBitmapCreator(bc2)
    brush.BlendBorders = False
    For r = 1 To Max(bc1.mWidth, bc1.mHeight) / 2 * 1.5 Step 20dip
        Dim task As DrawTask = bc1.AsyncDrawCircle(bc1.mWidth / 2, bc1.mHeight / 2, r, brush, True, 0)
        bc1.DrawBitmapCreatorsAsync(Me, "BC", Array(task))
        Wait For BC_BitmapReady (bmp As B4XBitmap)
        If xui.IsB4J Then bmp = bc1.Bitmap
        bc1.SetBitmapToImageView(bc1.Bitmap, ImageViewForAnimation)
        Sleep(16)
    Next
    ImageViewForAnimation.As(B4XView).RemoveViewFromParent
    Return True
End Sub

Test the transition in release mode.
 

Attachments

  • Project.zip
    182.1 KB · Views: 435
Last edited:

asales

Expert
Licensed User
Longtime User
Is it possible to use this as a transition between B4XPages?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Attached is a B4A implementation of transition based on this code.

You need to call B4XPages.MainPage.PrepareTransition and call ShowPage.

1. Disable the default transition with:
B4X:
B4XPages.GetManager.TransitionAnimationDuration = 0
2. The page background shouldn't be transparent.
3. Create the pages with AddPageAndCreate.
 

Attachments

  • Project.zip
    183 KB · Views: 225

AnandGupta

Expert
Licensed User
Longtime User
Attached is a B4A implementation of transition based on this code.
Ahh..I thought your answer will be 'No' but you made it.

Sometimes I think if you are saying 'No' then you are concentrating on more pressing job than the one requested for.
 

ilan

Expert
Licensed User
Longtime User
Attached is a B4A implementation of transition based on this code.

You need to call B4XPages.MainPage.PrepareTransition and call ShowPage.

1. Disable the default transition with:
B4X:
B4XPages.GetManager.TransitionAnimationDuration = 0
2. The page background shouldn't be transparent.
3. Create the pages with AddPageAndCreate.

hi erel, in b4a this code works fine but will it also work in b4i?
calling AddPageAndCreate will only call the B4XPage_Created event but not the B4XPage_Resize event so you will not be able to make a screenshot of the next page before it knows it width and height. And this is known only after calling B4XPage_Resize event.

my class is crashing because of that, any idea how i could solve it? like forcing to call B4XPage_Resize before i show the page?

thanx
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
B4A + B4i
B4X:
Public Sub PrepareTransition (CurrentPageRoot As B4XView, NewPageRoot As B4XView) As ResumableSub
    If bc1.IsInitialized = False Then
        bc1.Initialize(Root.Width, Root.Height)
        bc2.Initialize(Root.Width, Root.Height)
        ImageViewForAnimation.Initialize("")
    End If
    bc1.CopyPixelsFromBitmap(CurrentPageRoot.Snapshot)
    ImageViewForAnimation.As(B4XView).RemoveViewFromParent
    NewPageRoot.AddView(ImageViewForAnimation, 0, 0, Root.Width, Root.Height)
    bc1.SetBitmapToImageView(bc1.Bitmap, ImageViewForAnimation)
    Do While NewPageRoot.Width = 0 
        Sleep(10)
    Loop
    ImageViewForAnimation.Visible = False
    bc2.CopyPixelsFromBitmap(NewPageRoot.Snapshot)
    ImageViewForAnimation.Visible = True
    Dim brush As BCBrush = bc1.CreateBrushFromBitmapCreator(bc2)
    brush.BlendBorders = False
    For r = 1 To Max(bc1.mWidth, bc1.mHeight) / 2 * 1.5 Step 20dip
        Dim task As DrawTask = bc1.AsyncDrawCircle(bc1.mWidth / 2, bc1.mHeight / 2, r, brush, True, 0)
        bc1.DrawBitmapCreatorsAsync(Me, "BC", Array(task))
        Wait For BC_BitmapReady (bmp As B4XBitmap)
        If xui.IsB4J Then bmp = bc1.Bitmap
        bc1.SetBitmapToImageView(bc1.Bitmap, ImageViewForAnimation)
        Sleep(16)
    Next
    ImageViewForAnimation.As(B4XView).RemoveViewFromParent
    Return True
End Sub

Better to remove AutoScaleAll in B4i layouts.
 

Attachments

  • Project.zip
    184 KB · Views: 169

ilan

Expert
Licensed User
Longtime User
thanx erel, i will try it when i get home and update the class to make it work on b4a and b4i correctly.
 
Top