흔히 볼 수 있는 인증번호 입력 화면입니다.
화면이 시작되면서 5분 타이머가 그림과 같이 시작하는데
해당 타이머를 Rxjava interval 을 활용하여 구현해보려고 합니다.
1. Gradle 설정
Rxjava 를 활용하기위해 아래와 같이 gradle 에 추가해 줍니다.
dependencies {
....
// RxJava3
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
}
2. Rxjava Interval
Interval 을 활용하여 1초 간격으로 데이터를 발행합니다.
private fun timeOutStart(startTime: Long): Disposable {
return Observable.interval(0L, 1000L, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
setTimeOut(startTime - (it * 1000))
}
}
subscriber 입장에서 계속해서 전달받는 데이터는 Time 을 갱신하고 View 를 업데이트 해줍니다.
time 이 0 이하라면 타이머를 종료합니다.
private var time = 0L
private fun setTimeOut(value: Long) {
time = value
if (time < 0) {
// Timer 종료
compositeDisposable.clear()
} else {
// 실시간 Timer 표시
val mm = "%02d".format((time / 1000) / 60 % 60)
val ss = "%02d".format((time / 1000) % 60)
val timeStamp = "$mm:$ss"
binding.tvTimeOut.text = timeStamp
}
}
3. CompositeDisposable
타이머를 정상적으로 종료시키기 위해 compositeDisposable 를 사용하였습니다.
class MainActivity : AppCompatActivity() {
lateinit var binding: ActivityMainBinding
private val compositeDisposable = CompositeDisposable()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
compositeDisposable.add(timeOutStart(300 * 1000L)) // 5분
binding.btnRestart.setOnClickListener {
compositeDisposable.clear()
compositeDisposable.add(timeOutStart(300 * 1000L))
}
}
....
}
4. 동작화면
4. 레이아웃
[activity_main.xml]
<?xml version="1.0" encoding="utf-8"?>
<layout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="horizontal">
<EditText
android:id="@+id/etNumber"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/edit_text_custom_box"
android:gravity="center"
android:hint="인증 번호"
android:inputType="number"
android:textSize="17dp" />
<TextView
android:id="@+id/tvTimeOut"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|center_vertical"
android:layout_marginEnd="10dp"
android:text="05:00"
android:textColor="#FF0000"
android:textSize="17dp" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:orientation="vertical">
<Button
android:id="@+id/btnRestart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="타이머 다시시작" />
</LinearLayout>
</LinearLayout>
</layout>
[edit_text_custom_box.xml]
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<shape android:shape="rectangle">
<corners android:radius="5dp"/>
<solid android:color="#000000"/>
</shape>
</item>
</layer-list>
[Reference]
Android Rxjava interval 로 타이머 만들어보기
0 comments: