Spannable

repository·master·Indexed 20 days ago

https://github.com/liangjingkanji/spannable

An Android library for simplifying the construction of rich text, mixed text/image layouts, emojis, and icons. It provides core API functions like setSpan, addSpan, and replaceSpan, along with specialized implementations such as CenterImageSpan for advanced image alignment and scaling, GlideImageSpan for network images and GIFs, ColorSpan for text coloring, HighlightSpan for clickable styled text, and MarginSpan for adding spacing.

Tokens
3.3K
Snippets
10
Records
14
Agent score
71%

What's inside spannable

  1. Install Spannable via JitPack

    master

    To use Spannable in your Android project, you need to add the JitPack repository to your settings.gradle file and then add the dependency to your module's build.gradle file.

    1. Add the JitPack repository in settings.gradle:
    dependencyResolutionManagement {
        repositories {
            // ...
            maven { url 'https://jitpack.io' }
        }
    }
    1. Add the dependency in your module's build.gradle:
    implementation 'com.github.liangjingkanji:spannable:1.2.7'
    implementation 'com.github.liangjingkanji:spannable:1.2.7'
  2. Core API functions for Spannable

    master

    Spannable provides four primary functions to manipulate text with Spans. All implementations use the CharSequence interface, making them as easy to use as standard strings.

    FunctionDescription
    setSpanSets a Span
    addSpanAdds or inserts a Span or string
    replaceSpanReplaces a Span or string using regex matching
    replaceSpanFirst / replaceSpanLastReplaces the first or last matching Span or string
  3. Available Span effects

    master

    The library includes several built-in Span implementations for common text effects:

    • CenterImageSpan: Handles image alignment (vertical), width/height, fixed aspect ratios, displaying text, adaptive text sizing, and support for Shape or .9 (nine-patch) images.
    • GlideImageSpan: Supports network images and GIF animations with alignment, sizing, and aspect ratio options. Requires Glide.
    • MarginSpan: Adds spacing between text.
    • ColorSpan: Quickly creates colored text.
    • HighlightSpan: Creates text color, font styles, and clickable effects.
    • ClickableMovementMethod: An alternative to LinkMovementMethod that does not show a clickable background color.
  4. Use GlideImageSpan to load and display images in TextView

    master

    GlideImageSpan is a ReplacementSpan that uses the Glide library to load and display images (including GIFs) directly within a TextView. It allows for advanced styling such as vertical alignment, custom sizing, margins, padding, and even overlaying text on top of the image.

    Prerequisites You must include the Glide dependency in your project to use this class.

    Key Features

    • Vertical Alignment: Choose between Align.CENTER (default), Align.BASELINE, or Align.BOTTOM.
    • Sizing: Set custom widths and heights. Use -1 to match the text width/height or 0 for the image's original size.
    • Text Overlay: You can display text on top of the image by enabling setTextVisibility and configuring textGravity and textOffset.
    • GIF Support: Supports playing GIFs with configurable loop counts.
    • Glide Integration: Pass custom RequestOptions to control placeholders, error drawables, and transformations (e.g., centerCrop).
    // Example usage (Conceptual)
    val span = GlideImageSpan(textView, "https://example.com/image.jpg")
        .setAlign(GlideImageSpan.Align.CENTER)
        .setDrawableSize(200, 200)
        .setMarginHorizontal(10)
        .setTextVisibility(true)
        .setTextGravity(Gravity.CENTER)
    
    textView.text = "Some text " + span + " more text"
    
    // To use custom Glide options
    val options = RequestOptions().placeholder(R.drawable.placeholder).centerCrop()
    span.setRequestOption(options)
  5. Use HighlightSpan to style text and add click listeners

    master

    HighlightSpan is a custom ClickableSpan used to apply font color, typeface (style), and click events to specific text segments.

    Important Requirement: To make the onClick event functional, you must set either ClickableMovementMethod (from this library) or the standard Android LinkMovementMethod on the TextView containing the spannable text. This is an Android framework limitation.

    Constructors

    1. Color Int: Use an integer color (e.g., from Color.RED or Color.parseColor()).

      • HighlightSpan(color: Int?, typeface: Typeface?, onClick: ((View) -> Unit)?)
    2. Color String: Use a hex color string (e.g., "#FF0000").

      • HighlightSpan(color: String, typeface: Typeface?, onClick: ((View) -> Unit)?)
    3. Color Resource: Use a color resource ID from your Android resources.

      • HighlightSpan(context: Context, @ColorRes colorRes: Int, typeface: Typeface?, onClick: ((View) -> Unit)?)
    // Example 1: Using a color string and a click listener
    val span = HighlightSpan("#FF0000", typeface = Typeface.DEFAULT_BOLD) {
        // Handle click event
    }
    
    // Example 2: Using a color resource
    val spanRes = HighlightSpan(context, R.color.primary_color) {
        // Handle click event
    }
    
    // CRITICAL: You must apply a movement method to the TextView for onClick to work
    textView.movementMethod = ClickableMovementMethod()
  6. Use CenterImageSpan for enhanced image display in text

    master

    CenterImageSpan is an improved version of the standard Android ImageSpan. It provides advanced features for displaying images within text, including:

    • Vertical Alignment: Control how the image aligns with the text baseline.
    • Proportional Scaling: Set specific widths or heights while maintaining the image's aspect ratio.
    • Spacing Control: Configure both external margins and internal padding for the image.
    • Text Overlay: Display text on top of the image with customizable gravity, offset, and size.

    Note: For complex loading requirements (like Gaussian blur or diamond shapes), use GlideImageSpan instead.

    Constructors

    • CenterImageSpan(drawable: Drawable)
    • CenterImageSpan(drawable: Drawable, source: String)
    • CenterImageSpan(context: Context, uri: Uri)
    • CenterImageSpan(context: Context, resourceId: Int)
    • CenterImageSpan(context: Context, bitmap: Bitmap)
    // Example usage
    val drawable = ContextCompat.getDrawable(context, R.drawable.my_image)!!
    val span = CenterImageSpan(drawable)
        .setAlign(CenterImageSpan.Align.CENTER)
        .setDrawableSize(100)
        .setMarginHorizontal(10)
        .setTextVisibility(true)
        .setTextGravity(Gravity.CENTER)
    
    val spannable = SpannableString("Text with image").apply {
        setSpan(span, 6, 11, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
    }
  7. Configure GlideImageSpan image properties

    master

    Use these methods to control how the image itself is rendered within the text flow:

    MethodDescription
    setAlign(align: Align)Sets vertical alignment. Options: Align.BASELINE, Align.CENTER (default), Align.BOTTOM.
    setDrawableSize(width: Int, height: Int = width)Sets image dimensions. width > 0: fixed size. width == -1: use text width. width == 0: use original image width.
    setMarginHorizontal(left: Int, right: Int = left)Sets horizontal spacing around the image.
    setMarginVertical(top: Int, bottom: Int = bottom)Sets vertical spacing around the image.
    setPaddingHorizontal(left: Int, right: Int = left)Sets horizontal internal padding for the image area.
    setPaddingVertical(top: Int, bottom: Int = bottom)Sets vertical internal padding for the image area.
    setRequestOption(requestOption: RequestOptions)Passes Glide RequestOptions (e.g., for placeholders or transformations like centerCrop).
    setLoopCount(loopCount: Int)Sets the loop count for GIF animations (default is GifDrawable.LOOP_FOREVER).
  8. Configure GlideImageSpan text overlay properties

    master

    If you enable text visibility on a GlideImageSpan, use these methods to control the overlay text:

    MethodDescription
    setTextVisibility(visibility: Boolean)Enables or disables displaying text on top of the image.
    setTextOffset(left: Int, top: Int, right: Int, bottom: Int)Sets the offset for the text relative to the image area.
    setTextGravity(gravity: Int)Sets the alignment of the text within the image area (e.g., Gravity.CENTER, Gravity.BOTTOM). Use standard Android Gravity constants.
    setTextSize(size: Int)Sets the text size. When used with AbsoluteSizeSpan, it aligns the image/text to the baseline; otherwise, it centers them.
  9. Configure CenterImageSpan margins and padding

    master

    You can control the spacing around the image using margins (external) and padding (internal).

    Margins (External spacing)

    • setMarginHorizontal(left: Int, right: Int = left)
    • setMarginVertical(top: Int, bottom: Int = bottom)

    Padding (Internal spacing)

    • setPaddingHorizontal(left: Int, right: Int = left)
    • setPaddingVertical(top: Int, bottom: Int = bottom)
    span.setMarginHorizontal(8)
        .setPaddingVertical(4, 4)
  10. Display text on top of CenterImageSpan

    master

    CenterImageSpan allows you to render text directly over the image area.

    Key Methods:

    • setTextVisibility(visibility: Boolean): Enables or disables text rendering on the image. Defaults to true.
    • setTextGravity(gravity: Int): Sets the alignment of the text within the image bounds (e.g., Gravity.CENTER, Gravity.BOTTOM).
    • setTextOffset(left: Int, top: Int, right: Int, bottom: Int): Fine-tune the text position using offsets.
    • setTextSize(size: Int): Sets the text size in pixels. This is used for centering the text relative to the image rather than the text baseline.
    span.setTextVisibility(true)
        .setTextGravity(Gravity.CENTER)
        .setTextOffset(top = 2)
        .setTextSize(20)
  11. Use MarginSpan to apply margins to text

    master

    The MarginSpan class is a ReplacementSpan used to insert a colored rectangular area (a margin) into a text sequence. It occupies a specific width and can be colored to create visual spacing or background blocks.

    Parameters

    • width: The width of the margin in pixels.
    • color: The color of the margin. Defaults to Color.TRANSPARENT.
    // Example usage of MarginSpan
    val margin = MarginSpan(width = 20, color = Color.RED)
    // This span would then be applied to a SpannableString using the Spannable library's DSL
  12. Apply text color with ColorSpan

    master

    Use ColorSpan to quickly apply a text color to a string. It extends Android's ForegroundColorSpan and provides multiple constructors to support different color formats: integer color values, hex color strings, or color resource IDs from Android resources.

    Available constructors:

    • ColorSpan(color: Int): Uses a direct integer color value.
    • ColorSpan(color: String): Uses a hex color string (e.g., "#FF0000") parsed via Color.parseColor.
    • ColorSpan(context: Context, @ColorRes colorRes: Int): Uses a color resource ID from the provided Context.
    // Using an integer color
    val span1 = ColorSpan(Color.RED)
    
    // Using a hex string
    val span2 = ColorSpan("#FF0000")
    
    // Using a color resource
    val span3 = ColorSpan(context, R.color.my_color)