Convert Figma logo to code with AI

warkiz logoIndicatorSeekBar

A custom SeekBar on Android, which can be changed the size ,color , thumb drawable , tick drawable , tick text and indicator , also , will show an indicator view with progress above SeekBar when seeking. https://github.com/warkiz/IndicatorSeekBar

2,158
417
2,158
93

Top Related Projects

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

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

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

Quick Overview

IndicatorSeekBar is an Android library that provides a customizable SeekBar with a floating bubble indicator. It offers a wide range of customization options, including different styles, colors, and text formats for the indicator and the SeekBar itself.

Pros

  • Highly customizable with numerous options for appearance and behavior
  • Smooth animation and user interaction
  • Supports both continuous and discrete (stepped) progress
  • Compatible with both Java and Kotlin Android projects

Cons

  • Limited documentation and examples for advanced use cases
  • May require additional effort to integrate with custom themes or complex layouts
  • Some reported issues with indicator positioning on certain device configurations

Code Examples

  1. Basic implementation:
val seekBar = IndicatorSeekBar.Builder(this)
    .setMax(100f)
    .setMin(0f)
    .setProgress(50f)
    .build()
  1. Customizing appearance:
val customSeekBar = IndicatorSeekBar.Builder(this)
    .setBackgroundTrackColor(Color.GRAY)
    .setProgressTrackColor(Color.BLUE)
    .setThumbColor(Color.RED)
    .setIndicatorColor(Color.GREEN)
    .setIndicatorTextColor(Color.WHITE)
    .build()
  1. Setting up a discrete SeekBar:
val discreteSeekBar = IndicatorSeekBar.Builder(this)
    .setMin(0f)
    .setMax(100f)
    .setProgress(20f)
    .setTickCount(5)
    .setShowTickMarksType(TickMarkType.OVAL)
    .setTickMarksColor(Color.parseColor("#FF0000"))
    .setTickMarksSize(13f)
    .showTickTexts(true)
    .build()

Getting Started

  1. Add the dependency to your app's build.gradle file:
dependencies {
    implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2'
}
  1. Add the IndicatorSeekBar to your layout XML:
<com.warkiz.widget.IndicatorSeekBar
    android:id="@+id/seekBar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:isb_max="100"
    app:isb_min="0"
    app:isb_progress="50" />
  1. Initialize and customize the SeekBar in your Activity or Fragment:
val seekBar = findViewById<IndicatorSeekBar>(R.id.seekBar)
seekBar.onSeekChangeListener = object : OnSeekChangeListener {
    override fun onSeeking(seekParams: SeekParams) {
        // Handle progress changes
    }
    override fun onStartTrackingTouch(seekBar: IndicatorSeekBar) {}
    override fun onStopTrackingTouch(seekBar: IndicatorSeekBar) {}
}

Competitor Comparisons

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

Pros of fluid-slider

  • Visually appealing and modern design with fluid animation
  • Customizable bubble indicator for precise value selection
  • Supports both iOS and Android platforms

Cons of fluid-slider

  • Limited customization options compared to IndicatorSeekBar
  • May have a steeper learning curve for implementation
  • Less actively maintained (last update over 2 years ago)

Code Comparison

IndicatorSeekBar:

val seekBar = IndicatorSeekBar.Builder(this)
    .setMax(100)
    .setMin(0)
    .setProgress(50)
    .setIndicatorColor(Color.RED)
    .build()

fluid-slider:

let slider = Slider()
slider.attributedTextForFraction = { fraction in
    let formatter = NumberFormatter()
    formatter.maximumIntegerDigits = 3
    formatter.maximumFractionDigits = 0
    let string = formatter.string(from: (fraction * 500) as NSNumber) ?? ""
    return NSAttributedString(string: string)
}

The code snippets demonstrate the basic setup for each library. IndicatorSeekBar offers a more straightforward configuration with a builder pattern, while fluid-slider requires more custom code for formatting and displaying values. IndicatorSeekBar provides more built-in options for customization, whereas fluid-slider may require additional implementation for similar functionality.

Pros of discreteSeekBar

  • Offers a more traditional Android-style seekbar with discrete steps
  • Provides better support for older Android versions
  • Simpler implementation for basic discrete seekbar functionality

Cons of discreteSeekBar

  • Less customization options compared to IndicatorSeekBar
  • Lacks advanced features like custom indicators and tick marks
  • Not actively maintained (last update was several years ago)

Code Comparison

IndicatorSeekBar:

IndicatorSeekBar seekBar = findViewById(R.id.seekBar);
seekBar.setProgress(50);
seekBar.setIndicatorTextFormat("${PROGRESS} %");
seekBar.setTickCount(10);
seekBar.setIndicatorColor(Color.RED);

discreteSeekBar:

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

Both libraries provide custom SeekBar implementations for Android, but IndicatorSeekBar offers more extensive customization options and modern features. discreteSeekBar is simpler and may be suitable for projects requiring a basic discrete seekbar, especially on older Android versions. However, IndicatorSeekBar is more actively maintained and provides a wider range of functionality for creating rich, interactive seekbars.

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

Pros of PreviewSeekBar

  • Provides a preview functionality, allowing users to see a thumbnail or video preview while seeking
  • Integrates well with ExoPlayer for video playback
  • Offers a more modern and visually appealing design

Cons of PreviewSeekBar

  • Less customization options compared to IndicatorSeekBar
  • Focused primarily on video playback, which may limit its use in other contexts
  • Requires more setup and integration with video players

Code Comparison

IndicatorSeekBar:

IndicatorSeekBar seekBar = findViewById(R.id.seekBar);
seekBar.setProgress(50);
seekBar.setOnSeekChangeListener(new OnSeekChangeListener() {
    @Override
    public void onSeeking(SeekParams seekParams) {
        // Handle seeking
    }
});

PreviewSeekBar:

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

Both libraries offer seek bar functionality, but PreviewSeekBar focuses on providing preview capabilities, while IndicatorSeekBar offers more general-purpose customization options. IndicatorSeekBar is better suited for a wider range of applications, while PreviewSeekBar excels in video playback scenarios where preview functionality is desired.

 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 thumb appearance
  • Provides built-in support for step values

Cons of RangeSeekBar

  • Less frequent updates and maintenance
  • Fewer stars and forks on GitHub, indicating potentially lower community adoption
  • Documentation is not as comprehensive as IndicatorSeekBar

Code Comparison

IndicatorSeekBar:

IndicatorSeekBar seekBar = findViewById(R.id.seekBar);
seekBar.setProgress(50);
seekBar.setOnSeekChangeListener(new OnSeekChangeListener() {
    @Override
    public void onSeeking(SeekParams seekParams) {
        // Handle seeking
    }
});

RangeSeekBar:

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

Both libraries offer easy-to-use APIs for creating customizable seek bars. IndicatorSeekBar focuses on a single thumb with an indicator, while RangeSeekBar provides dual thumb functionality for selecting ranges. The choice between the two depends on specific project requirements and desired features.

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

IndicatorSeekBar

DOWNLOAD API Android Arsenal

This is a customizable SeekBar library on Android. Also, If you don't need indicator and want to show tick texts to top of seek bar, please see the other library.

中文.md

Overview

Screenshot

Demo

download apk

Scan QR code to download:

Setup

implementation 'com.github.warkiz.widget:indicatorseekbar:2.1.2'

Usage

xml

<com.warkiz.widget.IndicatorSeekBar
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:isb_max="100"
    app:isb_min="-1.0"
    app:isb_progress="25"
    app:isb_seek_smoothly="true"
    app:isb_ticks_count="5"
    app:isb_show_tick_marks_type="oval"
    app:isb_tick_marks_size="13dp"
    app:isb_tick_marks_drawable="@mipmap/ic_launcher"
    app:isb_show_tick_texts="true"
    app:isb_tick_texts_size="15sp"
    app:isb_tick_texts_color="@color/color_blue"
    app:isb_thumb_color="@color/color_green"
    app:isb_thumb_size="20dp"
    app:isb_show_indicator="rounded_rectangle"
    app:isb_indicator_color="@color/color_gray"
    app:isb_indicator_text_color="@color/colorAccent"
    app:isb_indicator_text_size="18sp"
    app:isb_track_background_color="@color/color_gray"
    app:isb_track_background_size="2dp"
    app:isb_track_progress_color="@color/color_blue"
    app:isb_track_progress_size="4dp"
    app:isb_only_thumb_draggable="false"/>

Java


 IndicatorSeekBar seekBar = IndicatorSeekBar
                .with(getContext())
                .max(110)
                .min(10)
                .progress(53)
                .tickCount(7)
                .showTickMarksType(TickMarkType.OVAL)
                .tickMarksColor(getResources().getColor(R.color.color_blue, null))
                .tickMarksSize(13)//dp
                .showTickTexts(true)
                .tickTextsColor(getResources().getColor(R.color.color_pink))
                .tickTextsSize(13)//sp
                .tickTextsTypeFace(Typeface.MONOSPACE)
                .showIndicatorType(IndicatorType.ROUNDED_RECTANGLE)
                .indicatorColor(getResources().getColor(R.color.color_blue))
                .indicatorTextColor(Color.parseColor("#ffffff"))
                .indicatorTextSize(13)//sp
                .thumbColor(getResources().getColor(R.color.colorAccent, null))
                .thumbSize(14)
                .trackProgressColor(getResources().getColor(R.color.colorAccent,null))
                .trackProgressSize(4)
                .trackBackgroundColor(getResources().getColor(R.color.color_gray))
                .trackBackgroundSize(2)
		.onlyThumbDraggable(false)
                .build();

Indicator stay always

Put IndicatorSeekBar into a IndicatorStayLayout can make the indicator stayed always. By the way, make sure you had called the attr to show the indicator before.

Xml

<com.warkiz.widget.IndicatorStayLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <!--your layout-->
    <com.warkiz.widget.IndicatorSeekBar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:isb_show_indicator="rectangle" <!--show indicator can not be NONE-->
        ....../>
    <!--your layout-->
</com.warkiz.widget.IndicatorStayLayout>

Java

IndicatorSeekBar seekBar = IndicatorSeekBar
                .with(getContext())
                .max(50)
                .min(10)
                .showIndicatorType(IndicatorType.RECTANGLE) //show indicator can not be NONE
                ...
                .build();

new IndicatorStayLayout(getContext()).attachTo(seekBar);

Custom indicator's View

You can custom the indicator View by below way:

If you want to replace the indicator's View on top part, you can call:

 seekBar.getIndicator().setTopContentView(yourTopView);

or want to custom the indicator's View you want , you can call:

seekBar.getIndicator().setContentView(yourView);

Custom indicator's text

Set a format string with placeholder ${PROGRESS} or ${TICK_TEXT} to IndicatorSeekBar, the indicator's text would change. For example: If you want to show the progress with suffix: % ,the code like:

seekBar.setIndicatorTextFormat("${PROGRESS} %")

Kotlin:
seekBar.setIndicatorTextFormat("\${PROGRESS} %")

or want to show the tick text with prefix: I am ,the code like:

seekBar.setIndicatorTextFormat("I am ${TICK_TEXT}")

Kotlin:
seekBar.setIndicatorTextFormat("I am \${TICK_TEXT}")

Custom section tracks color

The color of every block of seek bar can also be custom.

seekBar.customSectionTrackColor(new ColorCollector() {
    @Override
    public boolean collectSectionTrackColor(int[] colorIntArr) {
        //the length of colorIntArray equals section count
        colorIntArr[0] = getResources().getColor(R.color.color_blue, null);
        colorIntArr[1] = getResources().getColor(R.color.color_gray, null);
        colorIntArr[2] = Color.parseColor("#FF4081");
        ...
        return true; //True if apply color , otherwise no change
    }
});

Selector drawable&color were supported

You can set the StateListDrawable or ColorStateList for the thumb, tickMarks; also, ColorStateList for tickTexts is supported, too. Usage's format according to:

Thumb selector drawable:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--this drawable is for thumb when pressing-->
    <item android:drawable="@mipmap/ic_launcher_round" android:state_pressed="true" />
    <!--for thumb in normal-->
    <item android:drawable="@mipmap/ic_launcher" />
</selector>

Thumb selector color:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--this color is for thumb which is at pressing status-->
    <item android:color="@color/colorAccent" android:state_pressed="true" />
    <!--for thumb which is at normal status-->
    <item android:color="@color/color_blue" />
</selector>

TickMarks selector drawable:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--this drawable is for tickMarks those are at start side of thumb-->
    <item android:drawable="@mipmap/ic_launcher_round" android:state_selected="true" />
    <!--for tickMarks in normal-->
    <item android:drawable="@mipmap/ic_launcher" />
</selector>

TickMarks selector color:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--this color is for marks those are at start side of thumb-->
    <item android:color="@color/colorAccent" android:state_selected="true" />
    <!--for marks those are at right side of thumb-->
    <item android:color="@color/color_gray" />
</selector>

TickTexts selector color:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!--this color is for texts those are at start side of thumb-->
    <item android:color="@color/colorAccent" android:state_selected="true" />
    <!--for tick text which is stopped under thumb -->
    <item android:color="@color/color_blue" android:state_hovered="true" />
    <!--for texts those are at right side of thumb-->
    <item android:color="@color/color_gray" />
</selector>

Listener

seekBar.setOnSeekChangeListener(new OnSeekChangeListener() {
            @Override
            public void onSeeking(SeekParams seekParams) {
                Log.i(TAG, seekParams.seekBar);
                Log.i(TAG, seekParams.progress);
                Log.i(TAG, seekParams.progressFloat);
                Log.i(TAG, seekParams.fromUser);
                //when tick count > 0
                Log.i(TAG, seekParams.thumbPosition);
                Log.i(TAG, seekParams.tickText);
            }

            @Override
            public void onStartTrackingTouch(IndicatorSeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(IndicatorSeekBar seekBar) {
            }
        });

Attributes

attr.xml

Donation by Paypal , thanks

So happy to receive your donation or encouraging words , and I will post this on my thanks-lists , thanks.

打赏( 支付宝 )( 微信支付 )

自从文档里公布了二维码,我收到国内的朋友的一些打赏,虽然金额不大,但是一些支持和鼓励的话语还是让我感到开心,非常感谢。

感谢所有之前支持我的朋友。如果下次你要给我打赏,可以顺带写上你的github地址,我会在这里用 链接 贴出来,算是相互鼓励。

Thanks-lists

非常感谢列表中的朋友,你们的肯定和支持是我前进的最大动力!

Thanks for all the friends on the lists!

Name/昵称Date/日期Payment Tools/方式Words/留言Friendly link/友情连接
[E*e]2019-06-27微信
[*●]2019-06-14微信
[*宣]2019-06-05支付宝
[*圆]2019-05-29支付宝加油GitHub/SaltedFish999
[*兴明]2019-02-12支付宝GitHub/jdpxiaoming
[*j!n]2019-01-08微信666GitHub/jincom
[*乐]2018-12-19支付宝
[*勇]2018-12-05微信
[*天佑]2018-11-05支付宝
[*勇]2018-10-16支付宝
[*利成]2018-05-22支付宝

Contact me

Feel free to contact me if you have any trouble on this project:

  1. Create an issue.
  2. Send mail to me, "warkiz".concat("4j").concat("@").concat("gmail.com")

License

Copyright (C) 2017 zhuangguangquan

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.