Convert Figma logo to code with AI

rubensousa logoPreviewSeekBar

A SeekBar suited for showing a preview of something. As seen in Google Play Movies.

3,454
426
3,454
10

Top Related Projects

A beautiful Android custom seekbar, which has a bubble view with progress appearing upon when seeking. 自定义SeekBar,进度变化更以可视化气泡样式呈现

 A beautiful and powerful SeekBar what supports single、 range、steps、vetical、custom( 一款美观强大的支持单向、双向范围选择、分步、垂直、高度自定义的SeekBar)

:octocat:💧 A slider widget with a popup bubble displaying the precise value selected. Android library made by @Ramotion

Quick Overview

PreviewSeekBar is an Android library that provides a custom SeekBar with a preview of the content being seeked. It's designed to enhance video playback interfaces by showing a thumbnail preview as the user scrubs through the video timeline, similar to the functionality seen in YouTube and Netflix.

Pros

  • Enhances user experience in video playback applications
  • Customizable appearance and behavior
  • Seamless integration with ExoPlayer
  • Supports both local and remote video sources

Cons

  • Limited to Android platform
  • May require additional setup for custom video players
  • Potential performance impact with large video files or slow networks
  • Requires additional image loading library for remote thumbnails

Code Examples

  1. Basic setup with ExoPlayer:
val previewSeekBar = findViewById<PreviewSeekBar>(R.id.previewSeekBar)
val previewImageView = findViewById<ImageView>(R.id.previewImageView)
val player = ExoPlayer.Builder(context).build()

previewSeekBar.setPreviewLoader { currentPosition, max ->
    // Load preview image based on currentPosition
    Glide.with(previewImageView)
        .load(getPreviewUrl(currentPosition))
        .into(previewImageView)
}

previewSeekBar.attachPreviewView(previewImageView)
previewSeekBar.attachPlayer(player)
  1. Customizing appearance:
previewSeekBar.apply {
    thumbColor = ContextCompat.getColor(context, R.color.thumb_color)
    scrubberColor = ContextCompat.getColor(context, R.color.scrubber_color)
    previewFrameLayout.setBackgroundColor(Color.BLACK)
    previewAnimationEnabled = true
}
  1. Handling seek events:
previewSeekBar.addOnScrubListener(object : PreviewBar.OnScrubListener {
    override fun onScrubStart(previewBar: PreviewBar) {
        // Pause video playback
    }

    override fun onScrubMove(previewBar: PreviewBar, progress: Int, fromUser: Boolean) {
        // Update preview image
    }

    override fun onScrubStop(previewBar: PreviewBar) {
        // Resume video playback at new position
    }
})

Getting Started

  1. Add the dependency to your app's build.gradle:
dependencies {
    implementation 'com.github.rubensousa:previewseekbar:3.1.0'
    implementation 'com.github.rubensousa:previewseekbar-exoplayer:3.1.0'
}
  1. Add PreviewSeekBar to your layout:
<com.github.rubensousa.previewseekbar.PreviewSeekBar
    android:id="@+id/previewSeekBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:previewFrameLayout="@id/previewFrameLayout" />

<FrameLayout
    android:id="@+id/previewFrameLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <ImageView
        android:id="@+id/previewImageView"
        android:layout_width="120dp"
        android:layout_height="80dp" />

</FrameLayout>
  1. Initialize PreviewSeekBar in your Activity or Fragment:
val previewSeekBar = findViewById<PreviewSeekBar>(R.id.previewSeekBar)
val previewImageView = findViewById<ImageView>(R.id.previewImageView)

previewSeekBar.setPreviewLoader { currentPosition, max ->
    // Load preview image
}

previewSeekBar.attachPreviewView(previewImageView)

Competitor Comparisons

A beautiful Android custom seekbar, which has a bubble view with progress appearing upon when seeking. 自定义SeekBar,进度变化更以可视化气泡样式呈现

Pros of BubbleSeekBar

  • Offers a bubble-style indicator for precise value selection
  • Provides more customization options for appearance and behavior
  • Supports both continuous and discrete (sectioned) modes

Cons of BubbleSeekBar

  • Lacks video preview functionality
  • May not be as suitable for media playback scenarios
  • Requires more setup code for basic functionality

Code Comparison

PreviewSeekBar:

PreviewSeekBar seekBar = findViewById(R.id.previewSeekBar);
seekBar.setPreviewLoader(new PreviewLoader() {
    @Override
    public void loadPreview(long currentPosition, long max) {
        // Load preview here
    }
});

BubbleSeekBar:

BubbleSeekBar bubbleSeekBar = findViewById(R.id.bubbleSeekBar);
bubbleSeekBar.getConfigBuilder()
    .min(0)
    .max(100)
    .progress(50)
    .sectionCount(5)
    .build();

PreviewSeekBar is specifically designed for media playback with video preview functionality, making it ideal for video players. It offers a simpler setup process for basic usage.

BubbleSeekBar, on the other hand, is a more versatile seek bar with extensive customization options. It's suitable for a wider range of applications beyond media playback, such as settings adjustments or value selection in various contexts.

While PreviewSeekBar focuses on providing a seamless video preview experience, BubbleSeekBar excels in offering precise value selection with its bubble indicator and supports both continuous and discrete modes.

Pros of discreteSeekBar

  • Offers discrete steps for precise value selection
  • Supports both horizontal and vertical orientations
  • Provides more customization options for tick marks and labels

Cons of discreteSeekBar

  • Less visually appealing for video preview scenarios
  • Lacks built-in thumbnail preview functionality
  • May require more setup for basic usage compared to PreviewSeekBar

Code Comparison

PreviewSeekBar:

previewSeekBar.setPreviewLoader(object : PreviewLoader {
    override fun loadPreview(currentPosition: Long, max: Long) {
        // Load preview image
    }
})

discreteSeekBar:

DiscreteSeekBar seekBar = findViewById(R.id.discrete_seek_bar);
seekBar.setNumericTransformer(new DiscreteSeekBar.NumericTransformer() {
    @Override
    public int transform(int value) {
        return value * 100;
    }
});

PreviewSeekBar is specifically designed for video preview scenarios, offering a more streamlined setup for this use case. It includes built-in thumbnail preview functionality, making it easier to implement video scrubbing with previews.

discreteSeekBar, on the other hand, is a more general-purpose seek bar with discrete steps. It offers greater flexibility for various scenarios beyond video previews, such as setting precise numeric values or creating custom scales.

The choice between these libraries depends on the specific requirements of your project. If you need a video preview seek bar, PreviewSeekBar might be more suitable. For more general-purpose seek bar functionality with discrete steps, discreteSeekBar could be the better option.

 A beautiful and powerful SeekBar what supports single、 range、steps、vetical、custom( 一款美观强大的支持单向、双向范围选择、分步、垂直、高度自定义的SeekBar)

Pros of RangeSeekBar

  • Supports dual thumb (range) selection
  • Offers more customization options for appearance
  • Provides step functionality for discrete value selection

Cons of RangeSeekBar

  • Lacks video preview functionality
  • May have a steeper learning curve due to more configuration options
  • Does not integrate directly with media players

Code Comparison

PreviewSeekBar:

PreviewSeekBar seekBar = findViewById(R.id.previewSeekBar);
seekBar.setPreviewLoader(new PreviewLoader() {
    @Override
    public void loadPreview(long currentPosition, long max) {
        // Load preview image or video
    }
});

RangeSeekBar:

RangeSeekBar rangeSeekBar = findViewById(R.id.rangeSeekBar);
rangeSeekBar.setRange(0, 100);
rangeSeekBar.setProgress(20, 80);
rangeSeekBar.setOnRangeChangedListener(new OnRangeChangedListener() {
    @Override
    public void onRangeChanged(RangeSeekBar view, float leftValue, float rightValue, boolean isFromUser) {
        // Handle range change
    }
});

PreviewSeekBar is specifically designed for media playback with preview functionality, while RangeSeekBar offers more versatile range selection capabilities. The choice between the two depends on the specific requirements of your project, such as whether you need video preview or range selection functionality.

:octocat:💧 A slider widget with a popup bubble displaying the precise value selected. Android library made by @Ramotion

Pros of fluid-slider-android

  • Offers a more visually appealing and modern design with fluid animations
  • Provides a customizable bubble indicator for precise value selection
  • Supports both horizontal and vertical orientations

Cons of fluid-slider-android

  • May have a steeper learning curve due to its more complex implementation
  • Potentially higher performance overhead due to advanced animations
  • Limited to slider functionality, while PreviewSeekBar offers video preview capabilities

Code Comparison

PreviewSeekBar implementation:

<com.github.rubensousa.previewseekbar.PreviewSeekBar
    android:id="@+id/previewSeekBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:previewFrameLayout="@id/previewFrameLayout" />

fluid-slider-android implementation:

val slider = FluidSlider(context)
slider.positionListener = { pos -> Log.d("MainActivity", "Current position is: $pos") }
slider.beginTrackingListener = { /* Handle begin tracking */ }
slider.endTrackingListener = { /* Handle end tracking */ }

Both libraries offer unique features and design approaches. PreviewSeekBar focuses on video preview functionality, while fluid-slider-android provides a more visually appealing and customizable slider experience. The choice between the two depends on the specific requirements of your project and the desired user interface.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

PreviewSeekBar

A SeekBar suited for showing a video preview. As seen in Google Play Movies

Google Play Movies

PreviewSeekBar's sample

Build

Add the following to your app's build.gradle:

dependencies {
    // Base implementation with a standard SeekBar
    implementation 'com.github.rubensousa:previewseekbar:3.1.1'
    // Media3 extension that contains a TimeBar. 
    implementation 'com.github.rubensousa:previewseekbar-media3:1.1.1.0'
    // (Deprecated) ExoPlayer Extension that contains a TimeBar.
    implementation 'com.github.rubensousa:previewseekbar-exoplayer:2.18.1.0'
}

How to use with Media3

Add a custom controller to your PlayerView

<androidx.media3.ui.PlayerView
    android:id="@+id/playerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:controller_layout_id="@layout/exoplayer_controls"/>

Here's the sample's exoplayer_controls: https://github.com/rubensousa/PreviewSeekBar/blob/master/sample/src/main/res/layout/exoplayer_controls.xml

Change your TimeBar to a PreviewTimeBar

<FrameLayout
    android:id="@+id/previewFrameLayout"
    android:layout_width="@dimen/video_preview_width"
    android:layout_height="@dimen/video_preview_height"
    android:background="@drawable/video_frame">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</FrameLayout>

<com.github.rubensousa.previewseekbar.exoplayer.PreviewTimeBar
    android:id="@+id/exo_progress"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:layout_marginEnd="8dp"
    app:previewAnimationEnabled="true"
    app:previewFrameLayout="@id/previewFrameLayout"/>

Place the View you want to use to display the preview in the FrameLayout above. In this example it's an ImageView but you can place any View inside. PreviewTimeBar will animate and show that FrameLayout for you automatically.

The FrameLayout must have the same parent as the PreviewTimeBar if you want the default animations to work

Create a PreviewLoader and pass it to the PreviewTimeBar

Note: A PreviewLoader is an interface that you need to implement yourself. This library isn't opinionated about how you actually show a preview. Check the sample code for an example on how it can be done using thumbnail sprites.

PreviewLoader imagePreviewLoader = ImagePreviewLoader();

previewTimeBar.setPreviewLoader(imagePreviewLoader);

In this project's sample, Glide is used with a custom transformation to crop the thumbnails from a thumbnail sprite.

GlideThumbnailTransformation

@Override
public void loadPreview(long currentPosition, long max) {
    GlideApp.with(imageView)
            .load(thumbnailsUrl)
            .override(GlideThumbnailTransformation.IMAGE_WIDTH,
                    GlideThumbnailTransformation.IMAGE_HEIGHT)
            .transform(new GlideThumbnailTransformation(currentPosition))
            .into(imageView);
}

Listen for scrub events to control playback state

When the user starts scrubbing the PreviewTimeBar, you should pause the video playback After the user is done selecting the new video position, you can resume it.

previewTimeBar.addOnScrubListener(new PreviewBar.OnScrubListener() {
    @Override
    public void onScrubStart(PreviewBar previewBar) {
        player.setPlayWhenReady(false);
    }

    @Override
    public void onScrubMove(PreviewBar previewBar, int progress, boolean fromUser) {
        
    }

    @Override
    public void onScrubStop(PreviewBar previewBar) {
        player.setPlayWhenReady(true);
    }
});

Customize the PreviewTimeBar

Available XML attributes:

<attr name="previewAnimationEnabled" format="boolean" />
<attr name="previewEnabled" format="boolean" />
<attr name="previewAutoHide" format="boolean" />
// Disables auto hiding the preview. 
// Default is true, which means the preview is hidden 
// when the user stops scrubbing the PreviewSeekBar
previewTimeBar.setAutoHidePreview(false);

// Shows the preview
previewTimeBar.showPreview();

// Hides the preview
previewTimeBar.hidePreview();

// Disables revealing the preview
previewTimeBar.setPreviewEnabled(false);

// Disables the current animation
previewTimeBar.setPreviewAnimationEnabled(false);

// Change the default animation
previewTimeBar.setPreviewAnimator(new PreviewFadeAnimator());

// Changes the color of the thumb
previewTimeBar.setPreviewThumbTint(Color.RED);

// Listen for scrub touch changes
previewTimeBar.addOnScrubListener(new PreviewBar.OnScrubListener() {
    @Override
    public void onScrubStart(PreviewBar previewBar) {
        
    }

    @Override
    public void onScrubMove(PreviewBar previewBar, int progress, boolean fromUser) {
        
    }

    @Override
    public void onScrubStop(PreviewBar previewBar) {
        
    }
});

// Listen for preview visibility changes
previewTimeBar.addOnPreviewVisibilityListener(new PreviewBar.OnPreviewVisibilityListener() {
    @Override
    public void onVisibilityChanged(PreviewBar previewBar, boolean isPreviewShowing) {
        
    }
});

How to use with a standard SeekBar

Setup your layout like the following:

<FrameLayout
  android:id="@+id/previewFrameLayout"
  android:layout_width="160dp"
  android:layout_height="90dp">

  <ImageView
      android:id="@+id/imageView"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />

</FrameLayout>

<com.github.rubensousa.previewseekbar.PreviewSeekBar
  android:id="@+id/previewSeekBar"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  android:layout_marginTop="24dp"
  android:max="800"
  app:previewFrameLayout="@id/previewFrameLayout"/>

Place the View you want to use to display the preview in the FrameLayout above. In this example it's an ImageView but you can place any View inside. PreviewSeekBar will animate and show that FrameLayout for you automatically.

The FrameLayout must have the same parent as the PreviewSeekBar if you want the default animations to work

Create a PreviewLoader and pass it to the PreviewSeekBar


PreviewSeekBar previewSeekBar = findViewById(R.id.previewSeekBar);

PreviewLoader imagePreviewLoader = ImagePreviewLoader();

previewSeekbar.setPreviewLoader(imagePreviewLoader);

Customization

Available XML attributes for styling:

<attr name="previewAnimationEnabled" format="boolean" />
<attr name="previewEnabled" format="boolean" />
<attr name="previewThumbTint" format="color" />
<attr name="previewAutoHide" format="boolean" />

Important note

This library is just an UI component for displaying previews. It doesn't handle generating thumbnail sprites from videos.

License

Copyright 2017 The Android Open Source Project
Copyright 2020 Rúben Sousa

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.