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: 433
Last edited:

Star-Dust

Expert
Licensed User
Longtime User
I cannot say that this is something that has never been seen before :p

 

LucaMs

Expert
Licensed User
Longtime User
I cannot say that this is something that has never been seen before :p

Is not the same thing; it is not changing the color of a panel in a certain way, by an animation. Look at the color of the views.
 

Star-Dust

Expert
Licensed User
Longtime User
Is not the same thing; it is not changing the color of a panel in a certain way, by an animation. Look at the color of the views.
Yes. They are two different layouts. I was talking about the effect.

Obviously I would have liked to have a similar effect between two B4XPage..Even if I have an idea
 

AnandGupta

Expert
Licensed User
Longtime User
I cannot say that this is something that has never been seen before :p

Thanks for the lead.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Another example:

B4X:
Private Sub UpdateTheme
    Dim TextColor As Int = IIf(CurrentThemeIsLight, xui.Color_Black, xui.Color_White)
    Dim Background As Int = IIf(CurrentThemeIsLight, xui.Color_White, xui.Color_Black)
    Dim Background2 As Int = IIf(CurrentThemeIsLight, 0xFFF1F1F1, 0xFF7A7A7A)
    Dim Background3 As Int = IIf(CurrentThemeIsLight, 0xFFC5C0C0, 0xFF969696)
    B4XImageView1.Bitmap = xui.LoadBitmap(File.DirAssets, IIf(CurrentThemeIsLight, "wp2319076-natural-full-hd-wallpapers.jpg", "wp2601997-hd-wallpaper-free-downlod.jpg"))
    Root.Color = Background
    CustomListView1.AsView.Color = IIf(CurrentThemeIsLight, 0x22C5C0C0, 0x22969696)
    For Each button As SwiftButton In SwiftButtons
        button.xLBL.TextColor = TextColor
        button.SetColors(Background2, Background3)
    Next
    For i = 0 To CustomListView1.Size - 1
        CustomListView1.GetPanel(i).GetView(0).TextColor = TextColor
    Next
End Sub

Private Sub UpdateTitle 'b4a code
    Dim cd As ColorDrawable
    cd.Initialize(IIf(CurrentThemeIsLight, xui.Color_White, xui.Color_Black), 0)
    B4XPages.GetManager.ActionBar.RunMethod("setBackgroundDrawable", Array(cd))
    Dim title As CSBuilder
    title.Initialize.Color(IIf(CurrentThemeIsLight, xui.Color_Black, xui.Color_White)).Append("Sweep Example").PopAll
    B4XPages.SetTitle(Me, title)
End Sub
Note that the title is updated at the end of the animation effect.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Last one for today:


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
    If CurrentThemeIsLight Then UpdateTitle
    For y = 0 To bc1.mHeight Step 30dip
        Dim yy As Int = IIf(CurrentThemeIsLight, y, bc1.mHeight - y)
        Dim r As B4XRect
        r.Initialize(0, yy, bc1.mWidth, yy + 30dip)
        Dim task As DrawTask = bc1.AsyncDrawRect(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(10)
    Next
    ImageViewForAnimation.As(B4XView).RemoveViewFromParent
    If CurrentThemeIsLight = False Then UpdateTitle
    Return True
End Sub
 

AnandGupta

Expert
Licensed User
Longtime User
As I understand, we need to have two or more images of the themes to show in animation.
Now how can we make different images for different phone sizes before hand ?

Can we create the images in the phone itself on first run, say.
 

AnandGupta

Expert
Licensed User
Longtime User
There is no difference between the examples. This code transitions between two layouts. The layouts can have images in them. The way to create such nice background images is with B4XImageView where the resize mode is set to FILL_NO_DISTORTIONS.
Understood. Thanks.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
The "core" of this code is:
B4X:
bc1.CopyPixelsFromBitmap(Root.Snapshot)
    UpdateTheme
    bc2.CopyPixelsFromBitmap(Root.Snapshot)
    Root.AddView(ImageViewForAnimation, 0, 0, Root.Width, Root.Height)
    bc1.SetBitmapToImageView(bc1.Bitmap, ImageViewForAnimation)
It takes a snapshot of the old layout, updates the layout, takes another snapshot and shows the old layout with the image view. The new layout will not be visible at all as the message queue needs to be processed for it to be drawn on the screen.

The next step is to use BitmapCreator (async) drawing methods to draw the new layout over the old one. When it is done, the image view is removed.
 
Top