안녕하세요. 이번 포스팅에는 안드로이드 개발에서 자주 사용하는 토스트 메시지를 즉시 생성(갱신)하는 방식에 대해 알아보겠습니다.
개요
토스트메시지는 일반적으로 정해진 Duration(지속시간)이 지속될 때 까지 다른 토스트 메시지들의 접근을 Blocking합니다.
왜냐하면 같은 스레드를 동기방식으로 사용하기 때문이죠.
그래서 만약 사용자가 토스트 메시지를 짧은시간에 여러번 호출한다면 아래 GIF와 같이 본인만의 시간의 흐름을 가지기 시작하며, 이는 사용자로 하여금 반응이 느리고 렉이 걸리는 듯한 오해를 가지게하기 쉽습니다.
※ 메시지가 서로 다름을 쉽게 확인하기위해 1씩 증가하는 카운트를 붙였습니다.
그럼 누르는 즉시 토스트 메시지로 띄워 주려면 어떻게 해야할까요?
저는 버튼이 클릭 될 때마다 새로운 스레드를 생성하여 현재 스레드에서 토스트 메시지가 보여지고 있는 중이라면 그 메시지를 취소시키고 현재 요청을 띄워주는 방식으로 구현하였습니다. 그럼 해당 방법으로 구현하였을 때 어떻게 토스트메시지가 보여지는지 확인 해보겠습니다.
누를때마다 count가 1씩 증가해 토스트 메시지가 갱신되는 것 처럼 보여집니다.
이는 즐겨찾기 등록/해제나 아이템 등록/삭제와 같이 즉발성 이벤트에 유용하게 사용됩니다.
그럼 코드를 보시겠습니다.
코드는 같은 코드를 코틀린 버전과 자바 버전으로 나누어서 작성하였으니 본인이 사용하는 언어로 작성하시면 되겠습니다.
코드
<ToastUtilsKotlin.kt>
import android.app.Activity
import android.widget.Toast
class ToastUtilsKotlin(private val mContext: Activity) {
private var toast: Toast? = null
/**
* 토스트메시지를 2초간 비동기로 보여준다
*/
fun showMessage(message: String?) {
val r = Runnable {
cancelToast()
toast = Toast.makeText(mContext, message, Toast.LENGTH_SHORT)
toast!!.show()
}
mContext.runOnUiThread(r)
}
/**
* 토스트메시지가 보여지는 시간을 동적으로 설정한다
*/
fun showMessage(message: String?, duration: Int) {
val r = Runnable {
cancelToast()
toast = Toast.makeText(mContext, message, duration)
toast!!.show()
}
mContext.runOnUiThread(r)
}
/**
* 토스트메시지가 보여지고 있으면 취소시킨다
*/
private fun cancelToast() {
if (toast != null) {
mContext.runOnUiThread { toast!!.cancel() }
}
toast = Toast(mContext)
}
}
<ToastUtils.java>
import android.app.Activity;
import android.widget.Toast;
public class ToastUtils {
private final Activity mContext;
private Toast toast;
/**
* Constructor
**/
public ToastUtils(Activity context) {
this.mContext = context;
}
/**
* 토스트메시지를 2초간 비동기로 보여준다
**/
public void showMessage(final String message) {
Runnable r = () -> {
cancelToast();
toast = Toast.makeText(mContext, message, Toast.LENGTH_SHORT);
toast.show();
};
mContext.runOnUiThread(r);
}
/**
* 토스트메시지가 보여지는 시간을 동적으로 설정한다
**/
public void showMessage(final String message, final int duration) {
Runnable r = () -> {
cancelToast();
toast = Toast.makeText(mContext, message, duration);
toast.show();
};
mContext.runOnUiThread(r);
}
/**
* 토스트메시지가 보여지고 있으면 취소시킨다
**/
private void cancelToast() {
if (toast != null) {
this.mContext.runOnUiThread(() -> toast.cancel());
}
toast = new Toast(mContext);
}
}
<MainActivity.kt>
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import com.example.airsignal_app.view.ToastUtilsKotlin
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val stackBtn: Button = findViewById(R.id.stackToastBtn)
val refreshBtn: Button = findViewById(R.id.refreshToastBtn)
var countStack = 1
var countRefresh = 1
val toast = ToastUtilsKotlin(this)
stackBtn.setOnClickListener {
Toast.makeText(this, "토스트 메시지 스택 $countStack", Toast.LENGTH_SHORT).show()
countStack++
}
refreshBtn.setOnClickListener {
toast.showMessage("토스트 메시지 갱신 $countRefresh",1)
countRefresh++
}
}
}
showMessage의 생성자를 2개로 구분하여 기본 ShortMessage방식과 유지하고 싶은 시간을 입력하는 방식을 선택해서 사용하시면 됩니다.
감사합니다.
전체소스
https://github.com/tekken5953/ToastExam
'Android' 카테고리의 다른 글
[안드로이드] 에러 'Cannot invoke setValue on a background thread' 해결 (0) | 2023.06.08 |
---|---|
[안드로이드] GPS 위치 정보 접근 권한 확인하기! (0) | 2023.05.31 |
[안드로이드] XML뷰에 샘플 데이터 넣기 (0) | 2023.04.19 |
[안드로이드] 배터리 잔량 + 충전상태 불러오기 - BatteryManager (0) | 2023.04.13 |
[안드로이드] 텍스트 폰트 적용하기(Kotlin,Java,XML) (0) | 2023.04.07 |