Kotlin

[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)

 

Leave a Reply

error: Content is protected !!