Image for post
Image for post
Photo by Manuel Capellari on Unsplash

In this post, I talk a little about the difference between two top-level functions used to create an Ambient, the ambientOf and the staticAmbientOf, and how to choose which one to use.

The Jetpack Compose version using in this post is 1.0.0-alpha06.

Ambient Introduction

The Ambient API in Jetpack Compose is used to pass some data implicitly to child components. If you are familiar with other declarative frameworks, you can think of the Ambient API as the Context in React, Provider in Flutter, or EnvironmentObject in SwiftUI.

The basic usage of Ambient is very simple. First, we declare a global Ambient:


Glide allows us to load images asynchronously. However, the asynchronous loading behavior is not testable which can become a pain. In some instrumented test scenarios, if the execution of the test code and the loading task of Glide cannot ensure synchronization, then the test result can become uncontrollable. Thankfully, Espresso provides IdlingResource to help us executing asynchronous work in test code synchronously which can solve this problem.

In this post, I will show you how to synchronize the image loading task of Glide in test code with minimal impact on the production code. Some codes are inspired by this issue.

Synchronize with CountingIdlingResource and Target

Image for post
Image for post


Add material design dependency in Gradle file:

implementation "<latest-version>"

Make sure your AppTheme inherited from a material theme like:

<style name="AppTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">


Create a custom alert dialog theme that inherited from ThemeOverlay.MaterialComponents.MaterialAlertDialog:

<style name="AlertDialogTheme" parent="ThemeOverlay.MaterialComponents.MaterialAlertDialog"></style>

Then you can then customize the style of the title, body, button, or other elements by overriding the corresponding item in the alert dialog theme.

For example, customize the text color and font size of the title by creating a materialAlertDialogTitleTextStyle that inherited from MaterialAlertDialog.MaterialComponents.Title.Text:

<style name="AlertDialogTheme" parent="..."> <item name="materialAlertDialogTitleTextStyle">@style/TitleTextStyle</item> </style> <style name="TitleTextStyle" parent="MaterialAlertDialog.MaterialComponents.Title.Text"> <item name="android:textColor">#fafafa</item> <item name="android:textSize">20sp</item> </style>…

In this post I will show you how to implement two types of transition animations for the floating action button (FAB):

Both animations are implemented via the CoordinatorLayout.Behavior so CoordinatorLayout is required to be used.

Speed dial

When pressed, a FAB can display three to six related actions in the form of a speed dial.

Image for post
Image for post


Create a CoordinatorLayout that contains a dial view and a FAB. The show/hide animation of the dial view is done through the behavior class. …

ConstraintLayout:2.0.0-alpha5 brings a new helper class Flow which can perfectly replace the linear layout in a handy way.

Sometimes we may just want to create a list with some fixed items distributed vertically:

Image for post
Image for post
Create a list with LinearLayout

Previous Approaches

LinearLayout with vertical orientation can simply create a list like this. However, if we want to embed the list into a complex layout creating with ConstraintLayout, the XML layout file can lead to a deep view hierarchy.

To flat the view hierarchy, we can set the constraint of each item view to achieving the same result:

However, this approach has some drawbacks:

  • Each item view needs…

Image for post
Image for post

Install in cygwin

  1. Download cygwin installer and execute:
./setup-x86_64.exe -q -P git,vim,curl,wget,zsh,chere

2. Open cygwin and install oh-my-zsh:

git clone ~/.oh-my-zsh
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc

3. Make zsh as the default shell. Edit ~/.bashrc and add the following line to the top:

exec zsh

4. (Optional) Add cygwin to right-click context menu. Run cygwin as administrator and execute:

chere -i -t mintty -s bash

5. (Optional) Use cygwin as integrated terminal in IDE (IDEA, VS Code, etc.)

Create a bat file named Cygwin-integrated.bat under C:\cygwin64 and add the following code:

@echo offset CHERE_INVOKING=1C:\cygwin64\bin\bash.exe --login -i

Make it executable

chmod +x Cygwin-integrated.bat

Use cygwin in VS Code (other IDEs are similar). Edit user settings and modify/add:

"": "C:\\cygwin64\\Cygwin-integrated.bat"


Android developer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store