Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีสร้าง Vertical SeekBar (แนวตั้ง) ใน Android

บทความนี้สาธิตวิธีทำ Vertical SeekBar ใน Android โดยการหมุน SeekBar ปกติ 270 องศา (Rotation)

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → File → New Project

ขั้นตอนที่ 2: Layout (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:rotation="270"
        android:max="100"
        android:progress="50" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:text="50"
        android:textSize="24sp"
        android:textStyle="bold" />

</RelativeLayout>

ขั้นตอนที่ 3: MainActivity.java

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

public class MainActivity extends AppCompatActivity {
    SeekBar seekBar;
    TextView textView;
    int min = 0, max = 100;

    @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.setMax(max - min);
        seekBar.setProgress(50 - min);
        textView.setText(String.valueOf(50));

        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                int currentValue = progress + min;
                textView.setText(String.valueOf(currentValue));
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                // เริ่มลาก
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                // หยุดลาก
            }
        });
    }
}

⚠️ ข้อควรระวังเรื่อง Rotation

  • android:rotation="270" หมุน SeekBar 270 องศา (หรือ -90) ทำให้แนวตั้ง
  • Touch area อาจไม่ตรงกับรูปเห็น (เพราะ rotation แค่ visual) - ทดสอบบนอุปกรณ์จริง
  • Progress bar จะเติมจาก "ขวาไปซ้าย" (เพราะหมุน) - คำนวณค่าให้ถูกต้อง

วิธีที่ดีกว่า: Custom Vertical SeekBar (API 21+)

Android 5.0+ รองรับ android:rotation ได้ดี แต่สำหรับ Production ควรใช้ Custom View:

1. ใช้ Library (แนะนำ)

// build.gradle
implementation 'com.github.hotchemi:android-rate:1.0.1' // หรือ library อื่นๆ
// หรือ
implementation 'com.github.warkiz:indicator-seekbar:2.0.0'

2. Custom View แบบง่าย (extends AppCompatSeekBar)

public class VerticalSeekBar extends AppCompatSeekBar {
    public VerticalSeekBar(Context context) { super(context); }
    public VerticalSeekBar(Context context, AttributeSet attrs) { super(context, attrs); }
    public VerticalSeekBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(h, w, oldh, oldw); // สลับ w/h
    }

    @Override
    protected synchronized void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(heightMeasureSpec, widthMeasureSpec);
        setMeasuredDimension(getMeasuredHeight(), getMeasuredWidth());
    }

    @Override
    protected void onDraw(Canvas c) {
        c.rotate(-90);
        c.translate(-getHeight(), 0);
        super.onDraw(c);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!isEnabled()) return false;
        // สลับ X/Y สำหรับ touch
        float x = event.getY();
        float y = event.getX();
        event.setLocation(x, y);
        return super.onTouchEvent(event);
    }
}

3. ใช้ใน XML

<com.example.VerticalSeekBar
    android:id="@+id/verticalSeekBar"
    android:layout_width="wrap_content"
    android:layout_height="200dp"
    android:max="100"
    android:progress="50" />

Material Slider (Material Components - ใหม่กว่า SeekBar)

implementation 'com.google.android.material:material:1.9.0'</pre>
<com.google.android.material.slider.Slider
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:rotation="270"
    android:valueFrom="0"
    android:valueTo="100"
    android:value="50" />

Slider ใหม่กว่า SeekBar รองรับ Range (2 thumbs), Labels, Ticks, และ Accessibility ดีกว่า