Android implements seekBar that follows the movement of the slider.

Overview

Detailed description of the custom implementation process of the seekBar effect displayed following the movement of the slider

Details

Foreword

In the development process of Android, we sometimes use custom Seekbar, such as when sliding the slider, the text moves with the slider. Let’s talk about it today. Let’s talk about the implementation of seekBar that follows the movement of the slider.

Contents covered today:

  1. Difficulties in customizing seekbar that moves text with the slider
  2. Use of TextSeekBar in Activity
  3. Points to note
  4. Renderings and project structure diagrams

The renderings are as follows:

Rendering.gif

1. Difficulties in customizing the seekbar that moves text with the slider

Here we inherit AppCompatSeekBar to implement seekBar that displays as the slider moves. This class is called TextSeekBar. There are two difficulties in the implementation process:

  • Whether the slider can be fully displayed when moving to the leftmost and rightmost sides of TextSeekBar
  • When the slider slides, can the text above the slider be displayed normally above the slider?

In response to the above problems, when initializing the TextSeekBar control, we need to set a setPadding to leave a display margin for the left and right sliders.
When the slider slides, the coordinates of the text in the x direction must be refreshed in real time according to the progress.

2. Use of TextSeekBar in Activity

First give the code of the layout file activity_main.xml corresponding to Activity:

 <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
        <TextView
            android:id="@ + id/tv_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            android:layout_marginTop="@dimen/dp_70"/>
        <Button
            android:id="@ + id/btn_test"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Test 1"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@ + id/tv_text"
            android:layout_marginTop="@dimen/dp_20"/>
        <Button
            android:id="@ + id/btn_test2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Test n"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toBottomOf="@ + id/btn_test"
            android:layout_marginTop="@dimen/dp_20"/>
        <FrameLayout
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="20dp"
            android:layout_marginTop="14dp"
            app:layout_constraintTop_toBottomOf="@ + id/btn_test2"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_weight="1">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginStart="20dp"
                android:layout_marginEnd="20dp"
                android:scaleType="fitCenter"
                android:src="@drawable/ic_bg" />
            <com.pain.testdemo.function.TextSeekBar
                android:id="@ + id/text_seek_bar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:maxHeight="16dp"
                android:splitTrack="false"
                android:thumb="@drawable/temp_seekbar"
                app:offset_x="-2dp"
                app:offset_y="16dp"
                app:stroke_width="1.5dp"
                app:text_color="@color/red"
                app:text_size="30sp"
                app:thumb_width="60dp" />
        </FrameLayout>
    </androidx.constraintlayout.widget.ConstraintLayout>

Let’s take a look at the use of TextSeekBar in Activity:

 package com.pain.testdemo;
    import androidx.annotation.RequiresApi;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Build;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.SeekBar;
    import android.widget.TextView;
    import com.pain.testdemo.function.TextSeekBar;
    import com.pain.testdemo.util.MyUtil;
    @RequiresApi(api = Build.VERSION_CODES.O)
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
        private TextView mTv;
        private Button mBtn;
        private Button mBtn2;
        private TextSeekBar mTextSeekBar;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            MyUtil.i("=======onCreate======");
            initView();
            initData();
            setListener();
        }
        private void initView() {
            mTv = findViewById(R.id.tv_text);
            mBtn = findViewById(R.id.btn_test);
            mBtn2 = findViewById(R.id.btn_test2);
            mTextSeekBar = findViewById(R.id.text_seek_bar);
        }
        private void initData() {
            mTextSeekBar.setMax(100);
            mTextSeekBar.setMin(0);
        }
        private void setListener() {
            mBtn.setOnClickListener(this);
            mBtn2.setOnClickListener(this);
            mTextSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
                @Override
                public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
                    mTextSeekBar.updateView(i);
                }
                @Override
                public void onStartTrackingTouch(SeekBar seekBar) {
                }
                @Override
                public void onStopTrackingTouch(SeekBar seekBar) {
                }
            });
        }
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_test:
                    MyUtil.i("========test======");
                    break;
                case R.id.btn_test2:
                    MyUtil.i("=======test2=====");
                    break;
                default:
                    break;
            }
        }
    }

3. Points to note

It should be noted that when we set a solid color background for TextSeekBar, we can use the android:background attribute combined with the shape of xml to set the background, but when the background of TextSeekBar is a picture, if we set it in this way, it will cause the picture to display deformation, so we can use layout to solve this problem. That is what is written in activity_main.xml above:

 <FrameLayout
           //Other codes are omitted
           //......
           >
            <ImageView
                //Other codes are omitted
                //......
                android:src="@drawable/ic_bg" />
            <com.pain.testdemo.function.TextSeekBar
              //Other codes are omitted
              //......
                />
        </FrameLayout>

Use FrameLayout to wrap it, ImageView to base it, and then use ImageView to set the properties of the image to adjust the display of the background image.

4. Renderings and project structure diagram

Rendering.gif

ok, that’s all the knowledge about customizing seekBar for today, thank you all.