Android筆記(18):UI元件 SeekBar & RatingBar 拉桿及評分條

Photo by Tandem X Visuals on Unsplash


[SeekBar]

在操作 Android 過程中,常會讓使用者透過介面互動方式進行設定,如音量或螢幕亮度等,這時多會採用 SeekBar 讓使用者拖曳橫桿上的按鈕調整設定。在 Android 中,如果想在螢幕中增加 SeekBar,可以在XML佈局檔中使用 <seekbar> 標記添加,基本語法格式如下:
<SeekBar
   android:屬性 = "值"> 
</SeekBar>

SeekBar 元件間接繼承自 ProgressBar 元件,因此 ProgressBar 的屬性也可使用在 SeekBar 元件,其他常用屬性還包括:
XML屬性描 述
max設定最大值。
progress設定目前的值。
secondaryProgress第二個 SeekBar 的進度。
thumb設定拖曳按鈕的圖案。

SeekBar 有個屬性是 secondaryProgress,表示在一條 SeekBar 上的第二個拖桿進度,例如:下載多個文件時,secondaryprogress 可以表示當前文件下載進度,progress 表示所有文件下載進度。

由於 SeekBar 可以讓使用者控制,因此程式中通常會用 OnSeekBarChangeListener 監聽器,設定監聽器後,定義三個方法:
  • onProgressChanged():當 SeekBar 值改變時觸發的方法。
  • onStartTrackingTouch():移動 SeekBar 時會觸發。
  • onStopTrackingTouch():放開 Seekbar 時會觸發。


[RatingBar]

RatingBar 與 SeekBar 類似,都允許使用者透過拖曳的方式改變進度,不同的是 RatingBar 是以星星的圖案來表示進度。通常 RatingBar 用在對服務提供者的評分或評估一件事物的支持程度,一般總星數為 5 顆,選擇間距為 0.5 顆。在Android 中,如果想增加 RatingBar 可以在 XML 佈局檔中使用 <RatingBar> 標記,基本語法格式如下:
<RatingBar
   屬性清單 > 
</RatingBar>

RatingBar 元件間接繼承自 ProgressBar 元件,因此 ProgressBar 的屬性也可使用在 RatingBar 元件,其他常用屬性還包括:
XML屬性描 述
isIndicator 設定 RatingBar 是否允許用戶改變,true 為不允許改變,預設為 false。
numStars設定星級評分總共有多少個星,必須為整數。
rating預設評分值,需為浮點數。
stepSize設定每次增加的值,預設為 0.5,必須是浮點數。
style設定星星圖案的樣式。
thumb將星星改成其他的 Drawable 圖案。

RatingBar 元件允許使用者改變星星圖案,可以使用 android:thumb 屬性來更換。style 可以設定的樣式有以下兩種:
  • style="?android:attr/ratingBarStyleSmall"
  • style="?android:attr/ratingBarStyleIndicator"

這兩種 RatingBar 的樣式及呈現結果如下:
RatingBar 提供了以下 3 個比較常用的方法:
  • getRating():獲取等級,表示選中了幾顆星。
  • getStepSize():取得每次最少要改變多少個星級。
  • getProgress():取得進度值,得到的進度值為 getRating()方法的值除以 getStepSize()方法的值。

以下程式範例在 SeekBar 使用監聽器監聽進度改變,並搭配數字百分比來呈現 ProgressBar 進度,而 RatingBar 則在按了星級數後,呈現級數在上方。


[程式範例]

(1)新建一個模組 Module,進入 res/layout 目錄下點選佈局檔 activity_main.xml。將預設的內容刪除,建立 2 個 TextView 文字框顯示 SeekBar 及 RatingBar 當時的值,1 個 SeekBar,以及 1 個 RatingBar,以下是完整 XML 的內容。
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="8dp"
    android:orientation="vertical" >

    <SeekBar
        android:id="@+id/sb"
        android:layout_marginTop="50sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100"
        android:progress="50" />

    <TextView
        android:id="@+id/vol"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20sp"
        android:textSize="22sp"
        android:text="目前音量: 50/100" />

    <TextView
        android:id="@+id/star"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="100sp"
        android:textSize="22sp"
        android:text="給予評分: 4.5" />

    <RatingBar
        android:id="@+id/rb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20sp"
        android:numStars="5"
        android:rating="4.5"
        android:stepSize="0.5" />

</LinearLayout>

(2)在 MainActivity.java 在 onCreate() 方法內,先建立與佈局檔的物件,用 findValueById 連結元件,設定 setOnSeekBarChangeListener 監聽器,在onProgressChanged 的方法內將值指定給名為 vol 的 TextView,以及偵測螢幕是否觸碰的方法。針對 RatingBar 設定 setOnRatingBarChangeListener 監聽器,在 onRatingChanged 的方法內將值指定給名為 star 的 TextView。程式碼如下:
package com.example.myseekbar;

import androidx.appcompat.app.AppCompatActivity;

import android.media.Rating;
import android.os.Bundle;
import android.widget.RatingBar;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

public class sb_MainActivity extends AppCompatActivity {
    private SeekBar sb;
    private TextView vol, star;
    private RatingBar rb;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sb_main);
        sb = (SeekBar) findViewById(R.id.sb);
        vol = (TextView) findViewById(R.id.vol);
        rb = (RatingBar) findViewById(R.id.rb);
        star = (TextView) findViewById(R.id.star);

        sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                vol.setText("目前音量:"+progress+"/100");
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                Toast.makeText(sb_MainActivity.this, "開始拖動 SeekBar...", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                Toast.makeText(sb_MainActivity.this, "已放開 SeekBar...", Toast.LENGTH_SHORT).show();
            }
        });

        rb.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
            @Override
            public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
                star.setText("給予評分: "+rating);
            }
        });
    }
}

執行的結果如下:

[參考資料]


Post a Comment

較新的 較舊