12.3 C
New York
Sunday, December 8, 2024

Constructing Jetcaster on all Type Components | by Chris Arriola | Android Builders


12 min learn

Jun 13, 2024

Written by: Chris Arriola, Chiara Chiappini, and Chiko Shimizu

Do you know that you could not solely construct cellular apps with Jetpack Compose but additionally TV apps, Put on apps, and in addition Widgets? We advocate that you simply use Compose to construct UI for all these type components.

On this weblog submit, we’ll go over the work that we did to replace certainly one of our samples — Jetcaster — to help further type components. We’ll focus on the strategy we took so as to add help for different type components in a means that promotes code sharing and reusability so to do the identical in your software.

Jetcaster is a pattern podcast app which lets you view podcasts, subscribe to a couple, and play an episode from a podcast. Like lots of our different Compose samples, the first objective of Jetcaster is to exhibit the capabilities of constructing UI with Compose. So, something non-UI associated, akin to taking part in audio, is solely mocked.

Jetcaster was chosen out of the ten Compose pattern apps on GitHub to increase to further type components as media apps are usually helpful not simply on telephones, however on TV and Put on, too.

You should utilize Jetpack Compose to construct apps on cellular, TV, and Put on. You may as well use Jetpack Look to construct widgets with Compose-like syntax.

When constructing for a particular type issue, it’s essential to differentiate which precise Compose dependencies are vital. Use the checklist beneath as a information to widespread dependencies you want for a given type issue:

Cellular (Telephones, Giant Screens, Foldables, and Chrome OS)

  • androidx.compose.material3:material3 — Dependency offering Materials Design 3 parts
  • androidx.navigation:navigation-compose — Dependency for dealing with navigation between screen-level composables (additionally can be utilized by TV)
  • androidx.compose.ui:ui-tooling — Dependency for Compose previews (additionally can be utilized by TV)
  • androidx.compose.material3.adaptive:adaptive — Dependency offering layouts for creating adaptive UIs

TV

  • androidx.television:tv-material — TV dependency offering Materials Design 3 parts. This ought to be used as an alternative of the cellular dependency
  • androidx.television:tv-foundation — TV dependency offering extensions to the Basis library. This ought to be used as well as to the Compose Basis library

Put on OS

  • androidx.put on.compose:compose-material — Put on OS dependency offering Materials Design 2.5 parts. This ought to be used as an alternative of the cellular dependency
  • androidx.put on.compose:compose-navigation — Put on OS dependency for navigation. This ought to be used as an alternative of the cellular Navigation Compose library
  • androidx.put on.compose:compose-foundation — Put on OS dependency offering extensions to the Basis library. This ought to be used as well as to the Compose Basis library
  • androidx.put on.compose:compose-ui-tooling — Put on OS dependency for previews

Widgets (Look)

  • androidx.look:glance-appwidget — Dependency offering core Look composables

Jetpack Compose consists of a variety of layers, offering totally different performance. For instance, UI parts tailor-made to totally different type components are offered by the Materials libraries for Cellular, TV, and Put on OS. These Materials libraries share the Compose basis layer and layers beneath. Compose basis gives the constructing blocks for setting up extra opinionated UI parts discovered within the Materials Compose libraries. However, Look relies on a decrease layer, the runtime layer, and gives a very totally different set of parts.

Compose on all Type Components libraries

Understanding how these dependencies are associated is essential for understanding the Compose code you’ll be able to share throughout totally different type components and what ought to be particular to a single type issue. Subsequent, let’s look into the challenge and module structure of Jetcaster.

Jetcaster initially had a single-module structure that solely focused cellular gadgets (a facet be aware: Jetcaster was optimized for foldables and even had customized logic for tabletop mode, however extra on that later). Step one was to interrupt this single-module structure into a number of modules to advertise code sharing (earlier than and after).

Jetcaster was modularized in order that core elements of the cellular app such because the area, knowledge, and design system layer, will be shared. Doing so avoids any duplication and in addition allows consistency throughout type components.

Finally, we determined to create 3 library modules which are shared by the applying (:cellular, :television and :put on) modules:

  • :core:knowledge — this module represents the knowledge layer containing repositories and networking and native persistence knowledge sources
  • :core:area — this module represents the area layer containing use instances and area objects
  • :core:designsystem — this module accommodates the design system together with colours, typographies, shapes, and shared composables

In addition to 2 testing-specific modules:

  • :core:data-testing— this module gives mock implementations for interfaces outlined within the knowledge layer
  • :core:domain-testing — this module gives mock knowledge for area fashions which have been useful to make use of in composable previews

The dependency graph for Jetcaster appears one thing like this:

Jetcaster dependency graph

Including new app modules

As soon as we had the library and testing modules arrange, including app modules akin to TV and Put on OS have been merely a matter of:

  1. Creating a brand new module,
  2. Including the shape factor-specific dependencies as talked about above, and
  3. Creating the mandatory screens and flows for that particular type issue.

With this construction, Jetcaster can reuse the info layer and customary design components which made it quick to help an extra type issue. You confer with the pull requests that added Put on OS help, and TV help, to dive deeper.

Type factor-specific nuances

Whereas reusing as a lot code as doable is fascinating, most composables within the UI layer weren’t shared. As a substitute, every type issue might present a form-factor particular element which was used as an alternative. Taking lazy lists for example, cellular makes use of LazyColumn/LazyRow, whereas Put on makes use of ScalingLazyColumn (no equal lazy row is offered on Put on). Equally, TV additionally gives a handful of TV-specific parts within the tv-material library.

One query you would possibly then ask is that this: why was it vital to offer a special composable as an alternative of utilizing the identical composable all all through?

The reason being as a result of every type issue has particular UX and UI nuances.

For instance, on cellular UI interactions are generally completed by faucets and gestures. However, TV interactions are generally completed with a controller (utilizing a directional pad or arrow keys). As a result of these enter variations, the scrolling conduct when navigating with gestures versus utilizing a controller can be totally different (i.e. quick scrolling vs. center-focused scrolling). To account for this, TV provides TV-specific Materials parts which are optimized for controller-driven navigation.

Equally, Put on provides ScalingLazyColumn to extend the visibility of things on spherical screens by scaling and fading as gadgets enter/exit the display. Moreover, Put on helps rotary enter which may occur from a special supply relying on the machine: a rotating facet button, a bodily bezel, or a contact bezel.

It’s for this exact motive that totally different type components might have a special composable implementation of a UI idea.

There are, nonetheless, some situations the place UI parts will be shared. For Jetcaster, the parts which are shared throughout cellular, TV and Put on need to do with loading photographs over the community and dealing with HTML formatted textual content. In these use instances, the implementation is precisely the identical for all type components and thus could possibly be shared. Moreover, the parts wanted to implement these use instances solely rely on androidx.compose.basis, and layers beneath it, which all type factor-specific Compose APIs already rely on.

Jetcaster optimizes for giant screens within the following methods:

  1. Through the use of a lazy grid as an alternative of a lazy column when displaying a listing of things, like within the house and podcast particulars display,
  2. By adopting the supporting pane canonical structure to show 2 panes (main and secondary) when operating Jetcaster in expanded layouts.

Be aware that :cellular helps massive screens.

Utilizing grids

Displaying a grid as an alternative of a column is good for expanded screens. Doing so takes benefit of the extra display actual property permitting customers to view extra info and decreasing the variety of interactions required to make use of the app.

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles