본문 바로가기
Android

[Android] (androidx) Vertical SeekBar (세로 Seekbar)

by bryan.oh 2020. 7. 22.
반응형

이런 Vertical SeekBar 와 ChangeEvent 를 만들어보겠습니다.

 

이전 버전의 android 에서는 단순히 Seekbar 를 rotate 만 하면 됐나봅니다.

샘플 소스들을 찾아보면 rotate 하라는 말 밖에 없네요.

따라 해봤는데 아래와 같이 나옵니다.

Try 1.

이 화면의 layout 은

    <SeekBar
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_dark"
        android:max="100"
        android:min="0"
        android:progress="50"
        android:rotation="270"
        android:splitTrack="true"
        app:layout_constraintLeft_toLeftOf="parent" />

Background 가 Rotation 기준으로 나옵니다. layout 은 width, height 가 그대로 나오는데요.

그리고 이상한건, Seekbar 의 길이가 아주 짧다는겁니다.

 

여기서 width 와 height 를 바꿔볼까요?

Try 2.

이 layout 은 아래와 같습니다.

    <SeekBar
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@android:color/holo_blue_dark"
        android:max="100"
        android:min="0"
        android:progress="50"
        android:rotation="270"
        android:splitTrack="true"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent" />

이것도 좀 이상합니다. left_toLeftOf = parent 로 했는데 왼쪽으로 안붙네요.
width 가 match_parent 라서 그런거 같습니다.

width 를 wrap_content 로 바꿔볼까요?

Try 3.

이건 뭐....

이래저래 잘 안됩니다. 

 

결론 

그럼 아래와 같이 원하는 위치에 Background 와  seekbar 가 일치하도록 생성해보겠습니다.

Try 4.

layout 을 먼저 보면 아래와 같습니다.

여기서 중요한건 LinearLayout 안에 SeekBar 가 있고, SeekBar 의 옵션중에 translationX 를 사용했습니다.

<LinearLayout
        android:layout_width="50dp"
        android:layout_height="match_parent"
        android:background="@android:color/holo_blue_dark"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent">

        <SeekBar
            android:id="@+id/seekbar"
            android:layout_width="400dp"
            android:layout_height="match_parent"
            android:translationX="-175dp"
            android:max="100"
            android:min="0"
            android:progress="50"
            android:rotation="270"
            android:splitTrack="true" />

    </LinearLayout>

SeekBar 의 width 가 어느정도 길이가 되야 SeekBar 의 progress 길이가 길더군요.

그래서 width 를 넓게하고 translationX 를 마이너스 값으로 줬습니다.

width 에 따라서 translationX 값이 달라집니다. layout 화면에서 바꿔가면서 맞추시면 됩니다.

 

이렇게 layout 을 만들고 소스에서 seekbar change event 는 아래를 참고하여 코딩하시면 됩니다.

package ai.bryan.hellobryansamples;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    private SeekBar seekBar;

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

        textView = findViewById(R.id.textview);
        seekBar = findViewById(R.id.seekbar);
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                if( fromUser ){
                    textView.setText(String.format("%d", progress));
                }
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
    }
}

setOnSeekBarChangeListener 안에 있는 event method 들을 이용하시면 됩니다.

 

※ 참고

onProgressChanged 의 parameter 인 fromUser 는 

true일 경우 사용자가 직접 seekbar 를 움직였을 때고,

코드상으로 SeekBar 의 Value 를 수정할때는 fromUser 가 false 로 됩니다.

 

이게 필요한 이유는?

예를들면 아래와 같이 event 가 발생해야할때

- SeekBar -> 볼륨조절 변경
- 볼륨조절변경 -> SeekBar 값위치 변경

이때 fromUser 를 안썼다면 무한 루프에 빠지게되겠죠.

 

 

728x90
반응형

댓글