# TextLayoutBuilder for Android layout creation and glyph caching

> TextLayoutBuilder is an Android library that wraps text layout creation in a reusable builder, with optional layout caching and FreeType glyph warming. It is aimed at custom Android views that need direct access to `Layout`, but its documented release history is more recent than its latest published version entry.

**facebook/TextLayoutBuilder** — An Android library that allows you to build text layouts more easily.

- Repository: https://github.com/facebook/TextLayoutBuilder
- Website: https://facebook.github.io/TextLayoutBuilder
- Stars: 1,471 · Forks: 131
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/facebook-textlayoutbuilder

## Why TextLayoutBuilder wraps Android `Layout` construction

TextLayoutBuilder targets Android code that creates `android.text.Layout` objects outside the usual `TextView` rendering path. It is most relevant to custom `View` implementations that need to measure, cache, or draw text themselves. The README's example assigns a `Layout` to a custom `View`, then calls `layout.draw(canvas)` from `onDraw`, which makes the ownership boundary explicit: the application configures the text, the library returns an Android `Layout`, and the view remains responsible for drawing it.

The builder also supports reuse for similarly styled layouts. Instead of repeating construction logic wherever the same typography and dimensions are needed, callers can configure one builder and build related text objects. The documentation presents caching and glyph warming as optional additions, rather than behavior imposed on every caller. That separation matters because a basic layout may be sufficient for small or rarely drawn strings, while a screen with common strings or large blocks of prose has additional use cases.

This is a narrow library rather than a complete text rendering stack. The README does not describe paragraph editing, text selection, accessibility behavior, bidirectional text configuration, or a higher-level replacement for `TextView`. Its documented scope is layout creation and the preparation work around that operation.

## The builder, `Layout`, and custom-view data flow

The documented data flow has three stages. First, a `TextLayoutBuilder` receives the string, color, width, and other applicable settings through setters. Second, `build()` produces an Android `Layout`. Third, application code stores that result and draws it through a custom view. The configuration and drawing stages are separate, so changing what is drawn still requires the application to update the view's stored `Layout`.

The minimum documented configuration is compact:

```java
TextLayoutBuilder builder = new TextLayoutBuilder()
    .setText("TextLayoutBuilder makes life easy")
    .setTextColor(Color.BLUE)
    .setWidth(400 /*, MEASURE_MODE_EXACTLY */);
```

This sets the text, selects blue, and supplies a width of 400. The commented `MEASURE_MODE_EXACTLY` indicates that width mode is also part of the API, although the README does not provide a complete explanation of its available values. The builder is then completed with:

```java
Layout layout = builder.build();
```

The resulting object is a standard Android `Layout`, which means downstream code can use the platform type rather than a TextLayoutBuilder-specific rendering abstraction. This is useful when an existing custom view already expects `Layout`. It also means callers remain responsible for ordinary Android concerns such as canvas coordinates, view invalidation, lifecycle handling, and saving state when the surrounding application requires them. The README does not show those lifecycle details.

## Adding TextLayoutBuilder through Gradle or Maven

The README documents distribution through Gradle and Maven. Its Gradle example uses the older `compile` dependency configuration rather than the `implementation` configuration used by current Android Gradle Plugin projects:

```groovy
compile 'com.facebook.fbui.textlayoutbuilder:textlayoutbuilder:1.7.0'
```

The Maven coordinates are `com.facebook.fbui.textlayoutbuilder:textlayoutbuilder`, version `1.7.0`, with packaging type `aar`:

```xml
<dependency>
  <groupId>com.facebook.fbui.textlayoutbuilder</groupId>
  <artifactId>textlayoutbuilder</artifactId>
  <version>1.7.0</version>
  <type>aar</type>
</dependency>
```

That Maven form follows the current build-tool syntax pattern for this declaration, but the README does not provide a full Gradle repository, version catalog, or modern Kotlin DSL example. The `compile` line should therefore be treated as documentation from the project's older setup style, not as proof that it will work unchanged in a current application. The repository includes `build.gradle`, `settings.gradle`, and a `sample/` directory, but the available project description does not document their exact compatibility constraints.

For a first real use, add the dependency, construct the builder with text and dimensions, call `build()`, and pass the resulting `Layout` to the custom view. There is no initialization command, background service, or application-level setup documented in the README.

## Reusing a builder inside a custom Android view

The README's view example establishes the smallest practical rendering integration. `CustomView` holds a nullable-looking field in the shown snippet, although the declaration is simply `private Layout layout;`. Its setter accepts the object produced by `build()`, and `onDraw()` calls `layout.draw(canvas)` after drawing the view background through `super.onDraw(canvas)`.

```java
public class CustomView extends View {
    private Layout layout;

    public void setLayout(Layout layout) {
        this.layout = layout;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        layout.draw(canvas);
    }
}
```

The full README also includes a constructor that accepts `Context` and calls `super(context)`. A production implementation would still need to decide when to rebuild the layout, how width changes affect it, and when the view requests redraw. Those decisions are not answered by this example. In particular, calling `setLayout()` alone does not automatically trigger `invalidate()`, and `onDraw()` does not show a null check.

Those omissions make the example instructional rather than a complete custom-view implementation. They also reveal where the library ends: TextLayoutBuilder builds the text object, while the application owns the Android view and its update behavior.

## Optional layout caching for recurring strings

For strings that are built repeatedly, the builder exposes an opt-in caching switch. The README describes this as caching layouts for commonly used strings:

```java
textLayoutBuilder.setShouldCacheLayout(true);
```

This flag is set on the builder before its layouts are needed. The documentation does not state the cache key, capacity, eviction policy, synchronization model, or relationship between builder instances. It also does not say whether changing text, color, width, or style properties after caching has been enabled clears previous results. Those omissions limit how precisely cache behavior can be planned.

The likely use case is repetitive application text with stable layout inputs, but the project only establishes that caching exists and that it is optional. It does not promise a particular memory bound or speed improvement. Developers should not infer that `setShouldCacheLayout(true)` improves every workload. Short, unique strings may add bookkeeping without creating useful reuse, while large layouts held in a cache can affect memory use. Those are engineering trade-offs to evaluate, not documented benchmark results.

The flag also does not replace application-level lifetime management. The README does not describe a static cache, a context-bound cache, or a documented clear operation, so it would be wrong to claim that builders automatically manage the whole application cache.

## FreeType cache warming for large blocks of text

TextLayoutBuilder can optionally warm the FreeType glyph cache. The README recommends this for large blocks of text and says it can provide a significant performance boost. Enabling it requires both the warming switch and a `GlyphWarmer` implementation:

```java
textLayoutBuilder
    .setShouldWarmText(true)
    .setGlyphWarmer(new GlyphWarmerImpl());
```

`GlyphWarmerImpl` is not defined in the README, and the available documentation does not explain how it selects glyphs, how much text it processes, or whether warming occurs during `build()` or another call. Based on the names and documented flow, warming text feeds glyph work into Android's font machinery before repeated rendering. The exact mechanism beyond that should be verified in the library source before an application depends on scheduling, threading, or memory behavior.

The distinction from layout caching is important. Layout caching reuses complete `Layout` objects for common strings. Glyph warming prepares glyph data in the font cache. A screen could use either option independently, both options together, or neither. The README does not document a requirement to call an explicit warm-up method or a background-thread API.

Its wording is a project claim rather than a published benchmark. No workload, device, Android version, typeface, or measurement method is given, so the performance effect cannot be quantified from the documentation.

## XML style import and license boundaries

Applications can populate a builder from an XML style resource through `ResourceTextLayoutHelper`. The documented call takes the builder, an Activity `Context`, and a style resource ID:

```java
ResourceTextLayoutHelper.updateFromStyleResource(
    textLayoutBuilder,
    context,
    resId);
```

This can reduce divergence between a declared Android style and a programmatically created layout. However, the README does not enumerate which text attributes are read, whether unsupported attributes are ignored, or whether style inheritance and theme resolution behave exactly like normal Android view inflation. The method name also specifically documents an Activity context, so callers should not assume that every custom `Context` is interchangeable.

TextLayoutBuilder is licensed under Apache-2.0. The repository includes a `LICENSE` file, and the README explicitly identifies the project as Apache-2-licensed. That notice identifies the project's stated licensing model; it does not provide legal advice about compatibility with a particular application, dependency tree, or distribution method.

Maintenance history deserves attention alongside the code. The repository is not archived, and the last push was on 2026-10-03. The latest listed release is `v1.7.0`, dated 2023-03-27, after earlier entries `1.5.0` and `1.4.0`. A push does not itself establish a new package release, and the README's dependency declaration still points to `1.7.0`.

## Conclusion

Android developers building custom text views should consider TextLayoutBuilder when they need a reusable configuration object, optional caching, or glyph warming. Developers requiring current Android Gradle Plugin conventions, a Kotlin-first API example, or a recent release record should first verify integration against their toolchain. The most important checks are library compatibility, AndroidX usage, cache behavior, and whether `GlyphWarmerImpl` is available in the chosen dependency setup.

## FAQ

### How do I install TextLayoutBuilder in an Android project?

The README documents the Gradle coordinate `com.facebook.fbui.textlayoutbuilder:textlayoutbuilder:1.7.0` and an equivalent Maven dependency. Its Gradle example uses `compile`, an older configuration that may need to be checked against the current Android build setup.

### How does TextLayoutBuilder create and draw text?

Set properties such as text, color, and width on `TextLayoutBuilder`, call `build()`, and receive an Android `Layout`. Application code can store that object in a custom view and call `layout.draw(canvas)` from `onDraw()`.

### Does TextLayoutBuilder support caching and glyph warming?

The API exposes `setShouldCacheLayout(true)` for commonly used strings and `setShouldWarmText(true)` with a `GlyphWarmer` for FreeType glyph cache warming. The README does not document cache eviction, cache keys, or the internal behavior of `GlyphWarmerImpl`.

## Sources

- [facebook/TextLayoutBuilder on GitHub](https://github.com/facebook/TextLayoutBuilder)
- [License: Apache-2.0](https://github.com/facebook/TextLayoutBuilder/blob/main/LICENSE)
- [Project website](https://facebook.github.io/TextLayoutBuilder)
- [README](https://github.com/facebook/TextLayoutBuilder/blob/main/README.md)
- [Releases](https://github.com/facebook/TextLayoutBuilder/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/facebook-textlayoutbuilder
