SubwayTooter-Android-App/app/src/main/java/jp/juggler/util/ToastUtils.kt

89 lines
3.1 KiB
Kotlin
Raw Normal View History

2018-12-01 00:02:18 +01:00
package jp.juggler.util
import android.content.Context
import android.widget.Toast
2022-05-29 15:38:21 +02:00
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import jp.juggler.subwaytooter.R
import kotlinx.coroutines.CancellationException
2018-12-01 00:02:18 +01:00
import me.drakeet.support.toast.ToastCompat
import java.lang.ref.WeakReference
2018-12-01 00:02:18 +01:00
2022-05-29 15:38:21 +02:00
private val log = LogCategory("ToastUtils")
private var refToast: WeakReference<Toast>? = null
internal fun showToastImpl(context: Context, bLong: Boolean, message: String): Boolean {
runOnMainLooper {
// 前回のトーストの表示を終了する
try {
refToast?.get()?.cancel()
} catch (ex: Throwable) {
log.trace(ex)
} finally {
refToast = null
}
2022-05-29 15:38:21 +02:00
// 新しいトーストを作る
try {
val duration = if (bLong) Toast.LENGTH_LONG else Toast.LENGTH_SHORT
val t = ToastCompat.makeText(context, message, duration)
t.setBadTokenListener { }
t.show()
refToast = WeakReference(t)
} catch (ex: Throwable) {
log.trace(ex)
}
// コールスタックの外側でエラーになる…
// android.view.WindowManager$BadTokenException:
// at android.view.ViewRootImpl.setView (ViewRootImpl.java:679)
// at android.view.WindowManagerGlobal.addView (WindowManagerGlobal.java:342)
// at android.view.WindowManagerImpl.addView (WindowManagerImpl.java:94)
// at android.widget.Toast$TN.handleShow (Toast.java:435)
// at android.widget.Toast$TN$2.handleMessage (Toast.java:345)
}
2022-05-29 15:38:21 +02:00
return false
2018-12-01 00:02:18 +01:00
}
2021-06-27 12:05:04 +02:00
fun Context.showToast(bLong: Boolean, caption: String?): Boolean =
2022-05-29 15:38:21 +02:00
showToastImpl(this, bLong, caption ?: "(null)")
2018-12-01 00:02:18 +01:00
fun Context.showToast(ex: Throwable, caption: String = "error."): Boolean =
2022-05-29 15:38:21 +02:00
showToastImpl(this, true, ex.withCaption(caption))
2018-12-01 00:02:18 +01:00
2021-06-27 12:05:04 +02:00
fun Context.showToast(bLong: Boolean, stringId: Int, vararg args: Any): Boolean =
2022-05-29 15:38:21 +02:00
showToastImpl(this, bLong, getString(stringId, *args))
2018-12-01 00:02:18 +01:00
2021-06-27 12:05:04 +02:00
fun Context.showToast(ex: Throwable, stringId: Int, vararg args: Any): Boolean =
2022-05-29 15:38:21 +02:00
showToastImpl(this, true, ex.withCaption(resources, stringId, *args))
fun AppCompatActivity.showError(ex: Throwable, caption: String = "error.") {
log.e(ex)
// キャンセル例外はUIに表示しない
if (ex is CancellationException) return
try {
AlertDialog.Builder(this)
.setTitle(R.string.error)
.setMessage(
listOf(
caption,
when (ex) {
is IllegalStateException ->
null
else ->
ex.javaClass.simpleName
},
ex.message,
)
.filter { !it.isNullOrBlank() }
.joinToString("\n")
)
.setPositiveButton(R.string.ok, null)
} catch (ex: Throwable) {
log.e(ex)
showToast(ex, caption)
}
}