[android : kotlin] 코틀린 RatingBar (별점주기) 사용방법 및 예제 – OnRatingBarChangeListener
RatingBar는 ProgressBar와 SeekBar의 확장버전 입니다.
별표 모양으로 지원되는 위젯뷰인데요. 점수나 등급 등의 평가 관련하여 컨텐츠를 개발할 때 활용하면 유용합니다. RatingBar는 크게 3가지 사이즈를 기본적으로 지원하며, 별도의 스타일 지정을 하지 않는다면 기본 사이즈는 가장 큰 사이즈( @style/Widget.AppCompat.RatingBar) 로 지정됩니다.
■ RatingBar 3가지 사이즈
⊙가장 작은 사이즈 : @style/Widget.AppCompat.RatingBar.Small
⊙ 중간 사이즈 : @style/Widget.AppCompat.RatingBar.Indicator
⊙ 가장 큰 사이즈 : @style/Widget.AppCompat.RatingBar
RatingBar가 변경되었을 때 처리하기 위해 Listener(리스너)를 구현해야합니다. RatingBar 클래스의 OnRatingBarChangeListener()메서드를 오버라이드하여 RatingBar가 변경되었을 때 이벤트 처리를 하게 됩니다.
■RatingBar의 레이아웃 주요속성
rating : 최초 채워진 값 지정
stetpSize : 별모양을 클릭했을 때 채워질 단위 ( 1은 별 1개를 의미, 0.5는 반쪽 별)
numStar : 레이팅바(RatingBar)의 최초 별 개수를 지정
isIndicator= 기본값은 false입니다, true 이면 사용자가 별점 채우기를 할 수 없게 지정
<RatingBar
android:id="@+id/ratingBar3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:rating="1.5"
android:numStars="3"
android:stepSize="1"
style="@style/Widget.AppCompat.RatingBar"/>
RatingBar 레이아웃 구성시 주의할 점은 RatingBar를 감싸고 있는 레이아웃의 layout_width 속성값에 맞춰지게 됩니다. 만약, match_parent 값으로 지정된 경우, numStart 속성값은 적용되지않고 화면 가로 크기 전체에 별모양으로 채우게 됩니다. 반드시 wrap_content 값을 사용하세요.
[예시 1] id가 rating_wrap_layout인 LinearLayout 의 layout_width 값이 match_parent일때
<LinearLayout
android:id="@+id/rating_wrap_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="시설 평가"/>
<RatingBar
android:id="@+id/ratingBar3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:rating="1.5"
android:numStars="3"
android:stepSize="1"
android:isIndicator="false"
style="@style/Widget.AppCompat.RatingBar"/>
</LinearLayout>
[예시 2] id가 rating_wrap_layout인 LinearLayout 의 layout_width 값이 wrap_content 일때
<LinearLayout
android:id="@+id/rating_wrap_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="시설 평가"/>
<RatingBar
android:id="@+id/ratingBar3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:rating="1.5"
android:numStars="3"
android:stepSize="1"
android:isIndicator="false"
style="@style/Widget.AppCompat.RatingBar"/>
</LinearLayout>
리스너 처리시 람다식을 사용하는 경우 미사용 변수는 언더바(_)로 변경처리할 수 있습니다.
ratingBar1.setOnRatingBarChangeListener { ratingBar, rating, fromUser ->
ratingBar1.rating = rating
}
ratingBar2.setOnRatingBarChangeListener { _, rating, _ ->
ratingBar2.rating = rating
}
팔레트에서 Widgets그룹을 클릭 후 RatingBar를 드래그하여 추가할 수 있습니다.
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:text="서비스 만족도 평가"
android:textAppearance="@style/TextAppearance.AppCompat.Display1" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="만족도 평가"/>
<RatingBar
android:id="@+id/ratingBar1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:numStars="7"
android:stepSize="0.5"
android:isIndicator="false"
style="@style/Widget.AppCompat.RatingBar.Small"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="친절도 평가"/>
<RatingBar
android:id="@+id/ratingBar2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:numStars="5"
android:isIndicator="false"
style="@style/Widget.AppCompat.RatingBar.Indicator"/>
</LinearLayout>
<LinearLayout
android:id="@+id/rating_wrap_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="시설 평가"/>
<RatingBar
android:id="@+id/ratingBar3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:rating="1.5"
android:numStars="3"
android:stepSize="1"
android:isIndicator="false"
style="@style/Widget.AppCompat.RatingBar"/>
</LinearLayout>
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="제출"
android:soundEffectsEnabled="true"/>
</LinearLayout>
[MainActivity.kt]
package edu.kotlin.study
import android.app.DatePickerDialog
import android.app.TimePickerDialog
import android.content.DialogInterface
import android.graphics.Color
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.Gravity
import android.widget.*
import androidx.appcompat.app.AlertDialog
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.activity_main.textView1
import kotlinx.android.synthetic.main.custom_simple_list_item_1.*
import java.util.*
import kotlin.collections.ArrayList
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//람다식을 사용하여 처리
ratingBar1.setOnRatingBarChangeListener { ratingBar, rating, fromUser ->
ratingBar1.rating = rating
}
ratingBar2.setOnRatingBarChangeListener { _, rating, _ ->
ratingBar2.rating = rating
}
//inner class를 사용하여 처리
ratingBar3.onRatingBarChangeListener = MyRatingBarChangeListener()
//별점 초기값을 지정
ratingBar1.rating = 3.0F
button.setOnClickListener {
textView1.text = "만족도 평가 : ${ratingBar1.rating}n친절도 평가 : ${ratingBar2.rating}n시설 평가 : ${ratingBar3.rating}"
}
}
inner class MyRatingBarChangeListener : RatingBar.OnRatingBarChangeListener {
override fun onRatingChanged(ratingBar: RatingBar?, rating: Float, fromUser: Boolean) {
// 2미만으로 별점을 줄 수 없게 설정하는 방법
if (ratingBar3.rating < 2.0F) {
ratingBar3.rating = rating
}
}
}
}
[build.gradle(Module:app)]
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 29
defaultConfig {
applicationId "edu.kotlin.study"
minSdkVersion 22
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
[build.gradle(Project)]
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = "1.3.72"
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
[REFERENCE]
▶RatingBar-developer.android.com
[연관 자료]
▶커스텀 레이팅바 구현방법(How to create Custom Ratings bar in Android)