Skip to content

Repository files navigation

storyviewer-android

A full-screen story viewer for Android (Instagram/Stories-style): progress bars on top, timer-based auto-advance, tap left/right to navigate, pause/mute, image and video support (with an on-disk video cache for instant opening). Available as a View flavor and a Jetpack Compose flavor, sharing the same underlying model and video cache.

The library has no dependency on any specific backend or DI framework: "story viewed" and "link clicked" events are reported back through the Activity result (registerForActivityResult), not through direct API calls.

Modules

Module What it is
storyviewer-core Shared, UI-toolkit-agnostic code: StoryItem, StoryVideoCache, the custom VideoViewNoAudioFocus video view. Not meant to be depended on directly.
storyviewer View-based StoryViewerActivity + XML layouts/theme.
storyviewer-compose Compose StoryViewerScreen composable + a StoryViewerActivity wrapper with the same Intent contract as the View flavor.

Screenshots

Feed Viewer Video
Feed Viewer Video

See the sample module for a runnable, self-contained example (bundled placeholder images/video, no network access required).

Installation

// root build.gradle
repositories {
    maven { url 'https://jitpack.io' }
}

// app module's build.gradle — pick one flavor (or both)
dependencies {
    implementation 'com.github.btctcn.storyviewer-android:storyviewer:v1.1.0'         // View
    implementation 'com.github.btctcn.storyviewer-android:storyviewer-compose:v1.1.0' // Compose
}

Usage — View flavor

val items = listOf(
    StoryItem(id = "1", imageUrl = "https://...", linkUrl = "https://..."),
    StoryItem(id = "2", videoUrl = "https://..."),
)

val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    val viewedIds = result.data?.getStringArrayListExtra(StoryViewerActivity.EXTRA_VIEWED_IDS)
    val clickedLink = result.data?.getStringExtra(StoryViewerActivity.EXTRA_CLICKED_LINK)
    // mark viewedIds as viewed in your own model, handle clickedLink yourself
}

launcher.launch(StoryViewerActivity.newIntent(context, items, startIndex = 0))

Optionally, prefetch the first N stories' videos in the background (e.g. right after loading the feed) so opening the viewer doesn't wait on network buffering:

StoryVideoCache.getInstance(context, okHttpClient)
    .prefetch(videoUrls, onDownloadError = { e -> /* your own analytics, optional */ })

Theming (View)

The host app can override the Theme.StoryViewer theme (or set its attributes on its own theme) without touching the library's code or layouts:

<style name="Theme.StoryViewer" parent="Theme.AppCompat.NoActionBar">
    <item name="storyViewerIconTintColor">@color/your_accent</item>
    <item name="storyViewerWatchButtonBackground">@drawable/your_button_bg</item>
    <item name="storyViewerWatchButtonTextColor">@color/your_text_color</item>
    <item name="storyViewerFontFamily">@font/your_font</item>
</style>

Usage — Compose flavor

Call StoryViewerScreen directly if your app already uses Compose Navigation:

StoryViewerScreen(
    stories = items,
    startIndex = 0,
    style = StoryViewerStyle.Default.copy(watchButtonTextColor = MyColors.accent),
    onFinished = { viewedIds, clickedLink ->
        // mark viewedIds as viewed in your own model, handle clickedLink yourself
    },
)

Or launch the bundled StoryViewerActivity — same Intent/extras contract as the View flavor — if you're not on Compose Navigation yet:

val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
    val viewedIds = result.data?.getStringArrayListExtra(StoryViewerActivity.EXTRA_VIEWED_IDS)
    val clickedLink = result.data?.getStringExtra(StoryViewerActivity.EXTRA_CLICKED_LINK)
}
launcher.launch(StoryViewerActivity.newIntent(context, items, startIndex = 0))

License

MIT

About

Full-screen story viewer for Android (Instagram-style). Both view-based and Compose, no DI.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages