Освой Android играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

SeekBar (Слайдер)

SeekBar - это обычный слайдер, когда пользователь может передвигать ползунок пальцем на экране. Ползунок также можно двигать при помощи клавиш-стрелок.

Компонент SeekBar находится в разделе Widgets и наследуется от класса ProgressBar. В Android Studio 3.0 представлен в двух вариантах: SeekBar и SeekBar (Discrete).

Для отслеживания перемещения ползунка SeekBar необходимо реализовать интерфейс-слушатель SeekBar.OnSeekBarChangeListener с методами-заглушками:

  • onProgressChanged() — уведомляет об изменении положения ползунка;
  • onStartTrackingTouch() — уведомляет о том, что пользователь начал перемещать ползунок;
  • onStopTrackingTouch() — уведомляет о том, что пользователь закончил перемещать ползунок

Заготовка для Kotlin (на Java будет ниже в статье).


val seekBar: SeekBar = findViewById(R.id.seekBar)
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener{
    override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
        // Ваш код
    }
    override fun onStartTrackingTouch(seekBar: SeekBar?) {    }
    override fun onStopTrackingTouch(seekBar: SeekBar?) {     }
})

Создадим новый проект и добавим компоненты SeekBar и TextView:


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="ru.alexanderklimov.as23.MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:textSize="24sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        tools:text="90"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="8dp"
        app:layout_constraintHorizontal_bias="0.501"/>

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="368dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:max="100"
        android:progress="3"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/textView"/>

</android.support.constraint.ConstraintLayout>

Напишем код, чтобы в текстовом поле отображалось текущее значение ползунка после того, как пользователь отпустит его.



package ru.alexanderklimov.seekbar;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SeekBar.OnSeekBarChangeListener {

    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        final SeekBar seekBar = (SeekBar)findViewById(R.id.seekBar);
        seekBar.setOnSeekBarChangeListener(this);

        mTextView = (TextView)findViewById(R.id.textView);
        mTextView.setText("0");
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        mTextView.setText(String.valueOf(seekBar.getProgress()));
    }
}

Ниже представлены вариант на Android 5.0 и старый вариант на Android 2.3 до появления Material Design, чтобы вы видели, как менялся интерфейс.

SeekBar

SeekBar

Меняем задний фон экрана

Усложним пример и будем менять цвет у фона экрана. Добавим на форму три компонента SeekBar:


<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:id="@+id/constrainLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="ru.alexanderklimov.as23.MainActivity">

    <SeekBar
        android:id="@+id/seekBar_Red"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:max="255"
        app:layout_constraintBottom_toTopOf="@+id/seekBar_Green"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />

    <SeekBar
        android:id="@+id/seekBar_Green"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:max="255"
        app:layout_constraintBottom_toTopOf="@+id/seekBar_Blue"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/seekBar_Red"/>

    <SeekBar
        android:id="@+id/seekBar_Blue"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:max="255"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/seekBar_Green"/>

</android.support.constraint.ConstraintLayout>

Напишем код, меняющий значение цвета через значения ползунка:


package ru.alexanderklimov.seekbar;

import android.os.Bundle;
import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.widget.SeekBar;

public class MainActivity extends AppCompatActivity {

    private SeekBar mRedSeekBar, mGreenSeekBar, mBlueSeekBar;
    private ConstraintLayout mScreenLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mScreenLayout = (ConstraintLayout) findViewById(R.id.constrainLayout);
        mRedSeekBar = (SeekBar) findViewById(R.id.seekBar_Red);
        mGreenSeekBar = (SeekBar) findViewById(R.id.seekBar_Green);
        mBlueSeekBar = (SeekBar) findViewById(R.id.seekBar_Blue);
        updateBackground();

        mRedSeekBar.setOnSeekBarChangeListener(seekBarChangeListener);
        mGreenSeekBar.setOnSeekBarChangeListener(seekBarChangeListener);
        mBlueSeekBar.setOnSeekBarChangeListener(seekBarChangeListener);
    }

    private SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            updateBackground();
        }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) {

        }

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) {

        }
    };

    private void updateBackground() {
        int redValue, greenValue, blueValue;
        redValue = mRedSeekBar.getProgress();
        greenValue = mGreenSeekBar.getProgress();
        blueValue = mBlueSeekBar.getProgress();
        // меняем фон через формат RGB
        mScreenLayout.setBackgroundColor(0xff000000 + redValue * 0x10000 + greenValue * 0x100
                + blueValue);
    }
}

Кот Рыжик попросил выставить цвет, наиболее подходящий цвету его шкурки. Я решил ему немного польстить:

SeekBar

SeekBar

Дополнительное чтение

Продвинутые примеры для слайдера

GitHub - lukelorusso/VerticalSeekBar: [AndroidLib] A nicer, redesigned and vertical SeekBar for Android 🎛

patryk1007/ShootingSlider - прикольный слайдер, напоминающий стрельбу из пушки в играх

bernaferrari/EmojiSlider: A slider widget rich in emoji and highly customisable. - слайдер с эмодзи-значками

MarcinMoskala/ArcSeekBar: Good looking curved Android SeekBar

AnderWeb/discreteSeekBar - интересная реализация

neild001/SeekArc - круговой ползунок. Пост автора.

Android Custom Seekbar with animation Example - ещё один пример кругового ползунка

GoodieBag/ProtractorView: A semicircular seekbar view for selecting angle from 0° to 180° - ползунок в виде полукруга.

oli107/material-range-bar: Android widget for selecting a range of values. - не совсем ползунок, позволяет выбрать диапазон значений.

lawloretienne/DiscreteSlider: A slider that allows a user to select a value at one of the specified tickmarks - слайдер для выбора значений.

akaita/CircularSeekBar: Simple custom Android View providing a Circular spin to SeekBars

Реклама