Mobile Development 11 min read

Design and Implementation of a Unified Rich Media Animation Control for Android Apps

This document presents the background, objectives, research findings, design principles, API specifications, caching strategy, implementation details, XML usage, memory impact analysis, and conclusions of a unified rich‑media animation component that consolidates image, GIF, Lottie, pager and video handling for efficient reuse in Android RecyclerView lists.

58 Tech
58 Tech
58 Tech
Design and Implementation of a Unified Rich Media Animation Control for Android Apps

Rich‑media controls in current mobile applications are fragmented, with inconsistent APIs and numerous widget variations, making development cumbersome; a unified component is needed to standardize interfaces and simplify usage.

The goal is to create a single control that can handle multiple media types (static images, GIFs, Lottie animations, pagers, videos) and support efficient switching in single‑operation scenarios as well as template reuse in feed‑style lists.

Benefits include reducing the number of feed templates, lowering the learning curve for developers, and providing a consistent API for media handling.

Research on two major e‑commerce apps (JD and Taobao) revealed that both use Fresco/Glide for static images, LottieAnimationView directly from the Lottie library, ijkplayer for video, and differ in how they wrap GIFs and animations; JD relies more on property animations while Taobao builds composite widgets.

Based on the research, the following preliminary components were defined: MultiImageView (Fresco/Glide), MultiGifView (Fresco), MultiLottieView (Lottie), MultiPagerView (ViewPager), MultiVideoView (LeadingVideoView), MultiLiveView (WPlayer), and the overall wrapper WubaMultiView.

Three design concerns were addressed:

Uniformity: All media types share a common interface with four core methods – setMediaType, setUrl, playback control (play/pause/stop), and cache toggle.

Reusability: A global static cache pool stores media view instances, allowing app‑wide reuse and configurable cache sizes per type.

Efficiency: Integration with RecyclerView enables multi‑level caching, reducing template types to a single unified view and minimizing memory overhead.

Example enum defining supported media types:

public final enum class MediaType private constructor() : kotlin.Enum<MediaType> {
    IMAGE,
    GIF,
    LOTTIE,
    PAGER,
    VIDEO;
}

Key API exposed by the component:

// Set media type
fun setMediaType(mediaType: MediaType)

// Get current view interface
fun getIView() : IView?

// Set request URLs
fun setUrl(vararg url: String)

// Set image scale type
fun setActualImageScaleType(scaleType: ScalingUtils.ScaleType)

// Set placeholder image
fun setPlaceholderImage(resourceId: Int, scaleType: ScalingUtils.ScaleType?)

// Set request status listener
fun setOnRequestStatusListener(listener: WubaMultiView.OnRequestStatusListener)

// Playback controls
fun play()
fun pause()
fun stop()
fun isPlaying(): Boolean

// Cache control
fun setUseCache(useCache: Boolean)

The unified interface for all media views:

interface IView {
    fun getMediaType() : MediaType
    fun getView(context: Context) : View
    fun setUrl(vararg url: String) { /* implementation */ }
    fun setUrl(urls: List<String>)
    fun setActualImageScaleType(scaleType: ScalingUtils.ScaleType)
    fun setPlaceholderImage(resourceId: Int, scaleType: ScalingUtils.ScaleType?)
    fun setFailureImage(resourceId: Int, scaleType: ScalingUtils.ScaleType?)
    fun play()
    fun pause()
    fun stop()
    fun isPlaying() : Boolean
    fun setOnRequestStatusListener(listener: WubaMultiView.OnRequestStatusListener)
}

Cache pool implementation (simplified):

enum class MediaType {
    IMAGE { override fun getViewCacheSize() = 10 }
    // ... other types
    companion object {
        private val CACHE_VIEWS = mutableMapOf<String, ArrayList<IView>>()
    }
    internal abstract fun getViewClass() : Class<IView>
    internal abstract fun getViewCacheSize() : Int
    internal fun getView(useCache: Boolean): IView { /* retrieve or create */ }
    internal fun addViewCache(view: IView) { /* add to pool */ }
}

XML usage requires specifying the media_type attribute, e.g.:

<com.wuba.views.media.WubaMultiView
    android:id="@+id/iv_feed_nopic_avator"
    android:layout_width="30dp"
    android:layout_height="30dp"
    app:media_type="IMAGE"
    app:scaleType="centerCrop"
    app:placeholderImage="@drawable/xxx"
    app:placeholderImageScaleType="centerCrop"
    app:failureImage="@drawable/xxx"
    app:failureImageScaleType="centerCrop" />

Memory‑usage testing showed that before the refactor two separate media controls caused two memory spikes, while after consolidating to the unified control only one spike occurred, confirming reduced memory fluctuation.

In summary, the unified rich‑media animation control simplifies RecyclerView templates, enables high‑efficiency item reuse, lowers development and maintenance costs, reduces app‑level memory consumption, and offers a minimal, developer‑friendly API for rich media scenarios.

CacheAndroidKotlinrich mediadesignRecyclerViewUI Component
58 Tech
Written by

58 Tech

Official tech channel of 58, a platform for tech innovation, sharing, and communication.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.