Connect with us

Tech News

Exploring Images in Jetpack Compose



Colin White

Jetpack Compose was announced at Google IO 2019 and is going to change how we do UI development on Android. I’ve been working a lot with the Android image APIs as I’ve been developing Coil and was curious how it treats images and how the concept of image loaders would fit in.

In the current Android UI framework ImageView is the main way to show an image on screen. Images are represented as Drawables, which often (though not always) wrap Bitmaps. Bitmaps are raw, uncompressed pixel data stored in memory.

In Jetpack Compose there is no ImageView because there is no View. Instead, views are replaced by Composables which define a composable piece of UI to add to the view hierarchy. Likewise, there are no Drawables. Instead, it’s replaced by Image which is a minimal interface that wraps a NativeImage. At the moment NativeImage is defined as a typealias to Bitmap. Interestingly, NativeImage is prefixed with a commented out expect declaration, which is a Kotlin Multiplatform keyword ?. Currently there isn’t any support for animated images, though I’d expect AnimatedImage to be added later. Here are the rough API analogs:

  • View -> Composable
  • ImageView -> DrawImage
  • Drawable -> Image
  • Bitmap -> NativeImage

Creating Images

At the moment, there is only one Image creation function, imageResource, which synchronously loads an image from resources. The API is noted as transient and will be replaced with an asynchronous API (likely using Coroutines) in the future. However, if we want to create an Image from a URL, a file, a URI, or another data source we’ll have to write it ourselves for now. Fortunately, we can offload the heavy lifting to an image loading library.

The easiest way to accomplish this is to write an effect. Effects are positionally memoized blocks of code that have a return value. They can be called from a Composable and will cause the composition (basically the view hierarchy) to rebuild if its output value is updated. Here’s an image effect implementation backed by Coil:

What do these functions do?

  • image(data: Any) is a simple version of image(request: GetRequest) that uses the default options to launch an image request.
  • When image is called as part of a Composable it will emit a null Image and begin asynchronously loading the given data .
  • It will update the image state when it’s successful and Jetpack Compose will re-render the Composable with the updated Image.
  • If the request is in-flight and the Composable is removed from the composition, the request will be automatically cancelled.

Cool, now let’s take a look at the JetNews sample app. At the moment it eagerly loads all its resources in MainActivity.onCreate. Using image, we can replace all the eager loading with lazy, non-blocking, asynchronous calls. Additionally, we can replace all the hardcoded resources with URLs! Here’s what PostImage looks like after being converted:

Great! We’re done, right? While this will theoretically work (currently Coroutines doesn’t work with the Jetpack Compose compiler), the image function is missing a number of features and can be optimized:

  • Automatic sizing: At the moment, Coil will load the image at its original size (bounded by the size of the display) since it has no way to resolve the size of the parent container. One way to solve this would be to write our own Composable to render the images. However, that’s analogous to writing a custom ImageView which is more restrictive for API consumers.
  • Bitmap pooling: Coil.get prevents recycling the returned drawable’s Bitmap since Coil doesn’t know when it’s safe to return it to the pool. When you load an image into an ImageView Coil knows it’s safe to recycle the Bitmap when either View.onViewDetachedFromWindow occurs, Lifecycle.onDestroy occurs, or another image load request is started on that ImageView. Jetpack Compose provides CommitScope.onDispose as a lifecycle callback to clean up your components and Coil (and other image loaders) will need to treat that as a valid request disposal callback.

Most of these issues stem from the clean separation between Compose and the traditional UI framework classes like View and Drawable. That said, separating from those classes is absolutely the right idea since they are tied to the platform, rely on inheritance, and hold a lot of internal state (View is almost 30k lines long!). Composable and Image aren’t tied to the platform, favour composition over inheritance, and hold minimal to no internal state.

Overall I’m extremely excited by the progress on Jetpack Compose and look forward to ensuring Coil works effortlessly with Compose (when it’s ready). Also, if you want to see my fork of the JetNews app with the lazy loading changes, you can find it here.

Source link

Continue Reading
Click to comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Tech News

T-Mobile launches GoTo, its own line of smartphone accessories





The market for smartphone accessories is a big one, helping you to protect your expensive smartphone, keep it charged up, and more. And today T-Mobile is getting into that market with its own line of mobile accessories.

GoTo is a new line of accessories from T-Mobile. They’re available starting today, January 24th, both online and in T-Mobile stores nationwide.

There’s a number of products available in the GoTo family of accessories. Those include USB-C, microUSB, and Lightning cables, car chargers and wall chargers, a wireless charging pad, and portable battery packs. There are cases and screen protectors for a variety of phones, too, including the OnePlus 7T, iPhone 11 and 11 Pro, Galaxy S10 series, Galaxy Note 10 and Note 10+, Revvlry and Revvlry Plus, Pixel 3a, and LG K40, among others.

Pricing for the cables starts at $9.99 while the chargers start at $14.99. Cases start at $19.99 each while the tempered glass screen protectors start at $39.99 apiece. Compared to accessories from other well-known brands, these GoTo products seem similarly priced if not a little more expensive than some other brands available elsewhere online, but they’re a bit cheaper than some of the other accessories sold in T-Mobile stores.

While T-Mo does already sell accessories from several other companies, the launch of GoTo gives customers more options when looking to outfit their phone with a case or charger. That’s especially true for devices like the Revvlry or LG K40 that may not have as many accessories available as something like the iPhone 11 or Galaxy Note 10.

Source: T-Mobile

Source link

Continue Reading