ソースコード source code

下記アプリの主要なソースコードを公開しています。アプリ開発の参考になれば幸いです。

画像等が別途必要ですので下記情報のみでアプリが完成するものではありません。 アプリは少しずつ機能拡張していますのでストア公開されているアプリと内容が異なる場合があります。 コードはコピーして自由にお使いいただけます。ただし著作権は放棄しておりませんので全部の再掲載はご遠慮ください。部分的に再掲載したり、改変して再掲載するのは構いません。 自身のアプリ作成の参考として個人使用・商用問わず自由にお使いいただけます。 コード記述のお手本を示すものではありません。ミニアプリですので変数名などさほど気遣いしていない部分も有りますし間違いも有るかと思いますので参考程度にお考え下さい。 他の賢者の皆様が公開されているコードを参考にした箇所も含まれます。Androidアプリ開発の熟練者が書いたコードではありません。 エンジニア向け技術情報共有サービスではありませんので説明は省いています。ご了承ください。 GitHubなどへの公開は予定しておりません。

下記コードの最終ビルド日: 2021-05-09

build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    ext.kotlin_version = "1.4.32"
    repositories {
        google()
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:4.2.0'
        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()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

app/build.gradle

plugins {
    id 'com.android.application'
    id 'kotlin-android'
}

android {
    compileSdkVersion 30
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "jp.aosystem.barcodereader"
        minSdkVersion 26
        targetSdkVersion 30
        multiDexEnabled true
        versionCode 14
        versionName "1.13"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    kotlinOptions {
        jvmTarget = '1.8'
    }
    buildFeatures {
        viewBinding true
    }

}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.3.2'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'com.google.android.gms:play-services-ads:20.1.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    implementation 'com.journeyapps:zxing-android-embedded:4.2.0'  //QR code
    implementation 'com.google.zxing:core:3.4.1'  //QR code
}

app/src/main/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="jp.aosystem.barcodereader">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.BarCodeReader"
        android:hardwareAccelerated="true">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="com.journeyapps.barcodescanner.CaptureActivity"
            android:screenOrientation="fullSensor"
            tools:replace="screenOrientation" />
        <activity android:name=".SettingActivity" />
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-0000000000000000~0000000000">
        </meta-data>
    </application>
</manifest>

app/src/main/java/jp/aosystem/barcodereader/MainActivity.kt

package jp.aosystem.barcodereader

import android.app.Activity
import android.app.AlertDialog
import android.content.*
import android.content.res.Configuration
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.LocaleList
import android.util.DisplayMetrics
import android.view.Gravity
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.constraintlayout.widget.ConstraintLayout
import com.google.android.gms.ads.AdRequest
import com.google.android.gms.ads.AdSize
import com.google.android.gms.ads.AdView
import com.google.android.gms.ads.MobileAds
import com.google.zxing.integration.android.IntentIntegrator
import jp.aosystem.barcodereader.databinding.ActivityMainBinding
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.util.*
import kotlin.collections.ArrayList

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private lateinit var viewModel: ConstraintLayout
    private var continuousScan: Int = 0
    private var beepSoundWhenScan: Int = 0
    private var fixedOrientation: Int = 0
    private var themeNumber: Int = 0
    private var localeLanguage: String = ""

    //adMob
    private lateinit var adView: AdView     //adMob
    private val adSize: AdSize
        get() {
            val display = windowManager.defaultDisplay
            val outMetrics = DisplayMetrics()
            display.getMetrics(outMetrics)
            val density = outMetrics.density
            var adWidthPixels = this.binding.adContainer.width.toFloat()
            if (adWidthPixels == 0f) {
                adWidthPixels = outMetrics.widthPixels.toFloat()
            }
            val adWidth = (adWidthPixels / density).toInt()
            return AdSize.getCurrentOrientationAnchoredAdaptiveBannerAdSize(this, adWidth)
        }

    companion object {
        private const val AD_UNIT_ID: String = "ca-app-pub-0000000000000000/0000000000"     //adMob
        private const val RESULT_SETTING_ACTIVITY: Int = 1
        private const val READ_TEXT: String = "readText"
        internal const val SETTINGS: String = "settings"
        internal const val CONTINUOUS_SCAN: String = "continuousScan"
        internal const val BEEP_SOUND_WHEN_SCAN: String = "beepSoundWhenScan"
        internal const val FIXED_ORIENTATION: String = "fixedOrientation"
        internal const val THEME_NUMBER: String = "themeNumber"
        internal const val LOCALE_LANGUAGE: String = "localeLanguage"
    }
    private var scanIntegrator: IntentIntegrator? = null
    private var lastToast: Toast? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //setContentView(R.layout.activity_main)
        this.binding = ActivityMainBinding.inflate(layoutInflater)
        this.viewModel = this.binding.root
        setContentView(this.viewModel)
        //タイトルバー非表示
        supportActionBar?.hide()
        //adMob
        MobileAds.initialize(this) { }
        this.adView = AdView(this)
        this.binding.adContainer.addView(this.adView)
        this.loadBanner()
        //config load
        this.loadContinuousScan()
        this.loadBeepSoundWhenScan()
        this.loadFixedOrientation()
        this.loadThemeNumber()
        this.setTheme()
        this.resultTextColor()
        this.binding.editText1.setText(this.loadReadText(), TextView.BufferType.NORMAL)
    }

    //adMob
    private fun loadBanner() {
        this.adView.adUnitId = AD_UNIT_ID
        this.adView.adSize = adSize
        val adRequest = AdRequest
            .Builder()
            //.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
            .build()
        this.adView.loadAd(adRequest)
    }

    private fun resultTextColor() {
        val clr1: Int = if (this.themeNumber == 0) Color.rgb(238,238,238) else Color.rgb(34,34,34)
        this.binding.layoutBase.setBackgroundColor(clr1)
        val clr2: Int = if (this.themeNumber == 0) Color.rgb(255,255,255) else Color.rgb(0,0,0)
        this.binding.editText1.setBackgroundColor(clr2)
    }

    fun onClickSetting(v: View) {
        val intent = Intent(applicationContext, SettingActivity::class.java)
        intent.putExtra(CONTINUOUS_SCAN, this.continuousScan)
        intent.putExtra(BEEP_SOUND_WHEN_SCAN, this.beepSoundWhenScan)
        intent.putExtra(FIXED_ORIENTATION, this.fixedOrientation)
        intent.putExtra(THEME_NUMBER, this.themeNumber)
        intent.putExtra(LOCALE_LANGUAGE, this.localeLanguage)
        startActivityForResult(intent, RESULT_SETTING_ACTIVITY)
    }

    // 読み取り後に呼ばれるメソッド
    override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
        if (requestCode == RESULT_SETTING_ACTIVITY) {
            //設定の戻り
            super.onActivityResult(requestCode, resultCode, intent)
            if (resultCode == Activity.RESULT_OK && intent != null) {
                var reCreateFlag: Boolean = false
                val lastContinuousScan: Int = this.continuousScan
                this.continuousScan = intent.getIntExtra(CONTINUOUS_SCAN, 0)
                if (lastContinuousScan != this.continuousScan) {
                    this.saveContinuousScan()
                }
                //
                val lastBeepSoundWhenScan: Int = this.beepSoundWhenScan
                this.beepSoundWhenScan = intent.getIntExtra(BEEP_SOUND_WHEN_SCAN, 0)
                if (lastBeepSoundWhenScan != this.beepSoundWhenScan) {
                    this.saveBeepSoundWhenScan()
                }
                //
                val lastFixedOrientation: Int = this.fixedOrientation
                this.fixedOrientation = intent.getIntExtra(FIXED_ORIENTATION, 0)
                if (lastFixedOrientation != this.fixedOrientation) {
                    this.saveFixedOrientation()
                }
                //
                val lastThemeNumber: Int = this.themeNumber
                this.themeNumber = intent.getIntExtra(THEME_NUMBER, 0)
                if (lastThemeNumber != this.themeNumber) {
                    this.saveThemeNumber()
                    reCreateFlag = true
                }
                //
                val lastLocaleLanguage = this.localeLanguage
                this.localeLanguage = intent.getStringExtra(LOCALE_LANGUAGE) ?: ""
                if (this.localeLanguage != lastLocaleLanguage) {
                    this.saveLocaleLanguage()
                    reCreateFlag = true
                }
                if (reCreateFlag) {
                    recreate()
                }
            }
        } else {
            // 結果の取得
            val result = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent)
            if (result != null) {
                if (result.contents == null) {  //取得した値
                    Toast(this).showCustomToast("Cancelled", this)
                } else {
                    val dateTime: LocalDateTime = LocalDateTime.now()
                    val formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")
                    val dt: String = dateTime.format(formatter)
                    val encodeResult = this.strEncode(result.contents)
                    val str: String = dt + "," + result.formatName + "," + encodeResult
                    Toast(this).showCustomToast(encodeResult, this)
                    var results: String = this.loadReadText()
                    results += str + "\n"
                    this.saveReadText(results)
                    this.binding.editText1.setText(results, TextView.BufferType.NORMAL)
                    if (this.continuousScan == 1) {
                        this.scanIntegrator?.initiateScan()   //スキャン開始(アクティビティ生成)
                    }
                }
            } else {
                super.onActivityResult(requestCode, resultCode, intent)
            }
        }
    }

    fun onClickButtonScan(v: View) {
        this.scanIntegrator = IntentIntegrator(this)
        this.scanIntegrator?.setPrompt("Scan a barcode")
        this.scanIntegrator?.setBeepEnabled(this.beepSoundWhenScan == 1)    //読み取り後にビープ音
        this.scanIntegrator?.setOrientationLocked(this.fixedOrientation == 1)  //画面の回転 false:回転 true:固定 無指定:固定
        this.scanIntegrator?.setBarcodeImageEnabled(false)
        this.scanIntegrator?.initiateScan()   //スキャン開始(アクティビティ生成)
    }

    //テキストを保存
    private fun saveReadText(str: String) {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putString(READ_TEXT, str)
            apply()
        }
    }

    //テキストを読み出し
    private fun loadReadText(): String {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        val org = pref.getString(READ_TEXT, "").toString()
        if (org == "") {
            return ""
        }
        var result: String = ""
        val ary: ArrayList<String> = (org + "\n").split("\n") as ArrayList<String>
        ary.forEach{ s1 ->
            if (s1.length > 5) {
                result += s1 + "\n"
            }
        }
        return result
    }

    fun onClickButtonCopy(v: View) {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringCopied: String = getString(R.string.copied)
        val rStringButtonCopy: String = getString(R.string.buttonCopy)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonCopy)
            setMessage("")
            setPositiveButton(rStringOk, DialogInterface.OnClickListener { _, _ ->
                val results: String = this@MainActivity.loadReadText()
                val mManager: ClipboardManager = applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip: ClipData = ClipData.newPlainText("label", this@MainActivity.toCsv(results))
                mManager.setPrimaryClip(clip)
                Toast(this@MainActivity).showCustomToast(rStringCopied,this@MainActivity)
            })
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    fun onClickButtonSend(v: View) {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringButtonSend: String = getString(R.string.buttonSend)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonSend)
            setMessage("")
            setPositiveButton(rStringOk, DialogInterface.OnClickListener { _, _ ->
                val results: String = this@MainActivity.loadReadText()
                val csv: String = this@MainActivity.toCsv(results)
                val sendIntent: Intent = Intent().apply {
                    action = Intent.ACTION_SEND
                    putExtra(Intent.EXTRA_TEXT, csv)
                    type = "text/plain"
                }
                val shareIntent = Intent.createChooser(sendIntent, null)
                startActivity(shareIntent)
            })
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    fun onClickButtonDelete(v: View) {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringDeleted: String = getString(R.string.deleted)
        val rStringButtonDelete: String = getString(R.string.buttonDelete)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonDelete)
            setMessage("")
            setPositiveButton(rStringOk, DialogInterface.OnClickListener { _, _ ->
                this@MainActivity.binding.editText1.text = null
                this@MainActivity.saveReadText("")
                Toast(this@MainActivity).showCustomToast(rStringDeleted,this@MainActivity)
            })
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    fun onClickButtonCopyLast(v: View) {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringCopied: String = getString(R.string.copied)
        val rStringButtonCopyLast: String = getString(R.string.buttonCopyLast)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonCopyLast)
            setMessage("")
            setPositiveButton(rStringOk, DialogInterface.OnClickListener { _, _ ->
                val results: String = this@MainActivity.readLast()
                val mManager: ClipboardManager = applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                val clip: ClipData = ClipData.newPlainText("label", results)
                mManager.setPrimaryClip(clip)
                Toast(this@MainActivity).showCustomToast(rStringCopied,this@MainActivity)
            })
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    fun onClickButtonSendLast(v: View) {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringButtonSendLast: String = getString(R.string.buttonSendLast)
        //
        val results: String = this.readLast()
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonSendLast)
            setMessage(results)
            setPositiveButton(rStringOk, DialogInterface.OnClickListener { _, _ ->
                val sendIntent: Intent = Intent().apply {
                    action = Intent.ACTION_SEND
                    putExtra(Intent.EXTRA_TEXT, results)
                    type = "text/plain"
                }
                val shareIntent = Intent.createChooser(sendIntent, null)
                startActivity(shareIntent)
            })
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    fun onClickButtonBrowserLast(v: View) {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringButtonBrowserLast: String = getString(R.string.buttonBrowserLast)
        //
        val results: String = this.readLast()
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonBrowserLast)
            setMessage(results)
            setPositiveButton(rStringOk, DialogInterface.OnClickListener { _, _ ->
                if (results.startsWith("http://") || results.startsWith("https://")) {
                    val uri: Uri? = Uri.parse(results)
                    if (uri != null) {
                        val intent = Intent(Intent.ACTION_VIEW, uri)
                        startActivity(intent)
                    }
                } else {
                    val sendIntent: Intent = Intent().apply {
                        action = Intent.ACTION_SEND
                        putExtra(Intent.EXTRA_TEXT, results)
                        type = "text/plain"
                    }
                    val shareIntent = Intent.createChooser(sendIntent, null)
                    startActivity(shareIntent)
                }
            })
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    fun onClickButtonDeleteLast(v: View) {
        val rStringOk: String = getString(R.string.ok)
        val rStringCancel: String = getString(R.string.cancel)
        val rStringDeleted: String = getString(R.string.deleted)
        val rStringButtonDeleteLast: String = getString(R.string.buttonDeleteLast)
        //
        AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
            setTitle(rStringButtonDeleteLast)
            setMessage("")
            setPositiveButton(rStringOk, DialogInterface.OnClickListener { _, _ ->
                this@MainActivity.deleteLast()
                Toast(this@MainActivity).showCustomToast(rStringDeleted,this@MainActivity)
            })
            setNegativeButton(rStringCancel, null)
            show()
        }
    }

    private fun readLast(): String {
        val org: String = this@MainActivity.loadReadText()
        if (org == "") {
            return ""
        }
        var last: String = ""
        val ary: ArrayList<String> = (org + "\n").split("\n") as ArrayList<String>
        ary.forEach{ s1 ->
            if (s1.length > 10) {
                last = s1
            }
        }
        val ary2: ArrayList<String> = (last + ",,").split(",") as ArrayList<String>
        return this.strDecode(ary2[2])
    }

    private fun deleteLast() {
        val org: String = this@MainActivity.loadReadText()
        if (org == "") {
            return
        }
        var result: String = ""
        val ary: ArrayList<String> = (org + "\n").split("\n") as ArrayList<String>
        var last: String = "012345"
        ary.forEach{ s1 ->
            if (last != "012345" && s1.length > 5) {
                result += last + "\n"
            }
            last = s1
        }
        this@MainActivity.binding.editText1.setText(result, TextView.BufferType.NORMAL)
        this@MainActivity.saveReadText(result)
    }

    private fun toCsv(str: String): String {
        if (str == "") {
            return ""
        }
        var result: String = ""
        val ary: ArrayList<String> = (str + "\n").split("\n") as ArrayList<String>
        ary.forEach{ s1 ->
            val ary2: ArrayList<String> = (s1 + ",,").split(",") as ArrayList<String>
            if (ary2[0].length > 10) {  //空行じゃない場合
                result += "\"" + ary2[0] + "\",\"" + ary2[1] + "\",\"" + ary2[2] + "\"\n"
            }
        }
        return result
    }

    private fun strEncode(str: String): String {
        return str.replace("\"","%22").replace(",","%2C").replace("\n","\\n")
    }

    private fun strDecode(str: String): String {
        return str.replace("%22","\"").replace("%2C",",").replace("\\n","\n")
    }

    //custom Toast
    private fun Toast.showCustomToast(message: String, activity: Activity) {
        if (this@MainActivity.lastToast != null) {  //前回のToastが残っていたら削除
            this@MainActivity.lastToast!!.cancel()
            this@MainActivity.lastToast = null
        }
        val layout = activity.layoutInflater.inflate (
            R.layout.custom_toast_layout,
            activity.findViewById(R.id.toast_container)
        )
        // set the text of the TextView of the message
        val textView = layout.findViewById<TextView>(R.id.toast_text)
        textView.text = message
        // use the application extension function
        this.apply {
            setGravity(Gravity.BOTTOM, 0, 40)
            duration = Toast.LENGTH_SHORT
            view = layout
            show()
        }
        this@MainActivity.lastToast = this
    }

    //--------------------------------------------------------------------------------

    //連続読取を保存
    private fun saveContinuousScan() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(CONTINUOUS_SCAN, this@MainActivity.continuousScan)
            apply()
        }
    }

    //連続読取を読み出し
    private fun loadContinuousScan() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.continuousScan = pref.getInt(CONTINUOUS_SCAN, 0)
    }

    //読取時ビープ音を保存
    private fun saveBeepSoundWhenScan() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(BEEP_SOUND_WHEN_SCAN, this@MainActivity.beepSoundWhenScan)
            apply()
        }
    }

    //読取時ビープ音を読み出し
    private fun loadBeepSoundWhenScan() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.beepSoundWhenScan = pref.getInt(BEEP_SOUND_WHEN_SCAN, 0)
    }

    //縦横固定を保存
    private fun saveFixedOrientation() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(FIXED_ORIENTATION, this@MainActivity.fixedOrientation)
            apply()
        }
    }

    //縦横固定を読み出し
    private fun loadFixedOrientation() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.fixedOrientation = pref.getInt(FIXED_ORIENTATION, 0)
    }

    //テーマを保存
    private fun saveThemeNumber() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putInt(THEME_NUMBER, this@MainActivity.themeNumber)
            apply()
        }
    }

    //テーマを読み出し
    private fun loadThemeNumber() {
        val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.themeNumber = pref.getInt(THEME_NUMBER, 0)
    }

    //テーマを設定
    private fun setTheme() {
        when (this.themeNumber) {
            0 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
            1 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
        }
    }

    //--------------------------------------------------------------------------------

    //localeLanguageを保存
    private fun saveLocaleLanguage() {
        getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
            putString(LOCALE_LANGUAGE, this@MainActivity.localeLanguage)
            apply()
        }
    }

    //言語設定
    override fun attachBaseContext(base: Context) {
        val pref = base.getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
        this.localeLanguage = pref.getString(LOCALE_LANGUAGE, "") ?: ""
        val loc: Locale? = if (this.localeLanguage != "") Locale(this.localeLanguage) else null
        if (loc != null) {
            val res = base.resources
            val config = Configuration(res.configuration)
            val localeList = LocaleList(loc)
            LocaleList.setDefault(localeList)
            config.setLocales(localeList)
            super.attachBaseContext(base.createConfigurationContext(config))
        } else {
            super.attachBaseContext(base)
        }
    }

    //--------------------------------------------------------------------------------

}

app/src/main/java/jp/aosystem/barcodereader/SettingActivity.kt

package jp.aosystem.barcodereader

import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Bundle
import android.os.LocaleList
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import jp.aosystem.barcodereader.databinding.ActivitySettingBinding
import java.util.*

class SettingActivity : AppCompatActivity() {
    private lateinit var binding: ActivitySettingBinding
    private lateinit var viewModel: ConstraintLayout

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        //setContentView(R.layout.activity_main)
        this.binding = ActivitySettingBinding.inflate(layoutInflater)
        this.viewModel = this.binding.root
        setContentView(this.viewModel)
        //データ受け取り
        val intent = this.intent
        val continuousScan: Int = intent.getIntExtra(MainActivity.CONTINUOUS_SCAN,0)
        this.binding.switchContinuousScan.isChecked = continuousScan != 0
        val beepSoundWhenScan: Int = intent.getIntExtra(MainActivity.BEEP_SOUND_WHEN_SCAN,0)
        this.binding.switchBeepSoundWhenScan.isChecked = beepSoundWhenScan != 0
        val fixedOrientation: Int = intent.getIntExtra(MainActivity.FIXED_ORIENTATION,0)
        this.binding.switchFixedOrientation.isChecked = fixedOrientation != 0
        val themeNumber: Int = intent.getIntExtra(MainActivity.THEME_NUMBER,0)
        this.binding.switchTheme.isChecked = themeNumber != 0
        val localeLanguage: String = intent.getStringExtra(MainActivity.LOCALE_LANGUAGE) ?: ""
        when (localeLanguage) {
            "en" -> this.binding.radioLanguageEn.isChecked = true
            "bg" -> this.binding.radioLanguageBg.isChecked = true
            "cs" -> this.binding.radioLanguageCs.isChecked = true
            "da" -> this.binding.radioLanguageDa.isChecked = true
            "de" -> this.binding.radioLanguageDe.isChecked = true
            "el" -> this.binding.radioLanguageEl.isChecked = true
            "es" -> this.binding.radioLanguageEs.isChecked = true
            "et" -> this.binding.radioLanguageEt.isChecked = true
            "fi" -> this.binding.radioLanguageFi.isChecked = true
            "fr" -> this.binding.radioLanguageFr.isChecked = true
            "hu" -> this.binding.radioLanguageHu.isChecked = true
            "it" -> this.binding.radioLanguageIt.isChecked = true
            "ja" -> this.binding.radioLanguageJa.isChecked = true
            "lt" -> this.binding.radioLanguageLt.isChecked = true
            "lv" -> this.binding.radioLanguageLv.isChecked = true
            "nl" -> this.binding.radioLanguageNl.isChecked = true
            "pl" -> this.binding.radioLanguagePl.isChecked = true
            "pt" -> this.binding.radioLanguagePt.isChecked = true
            "ro" -> this.binding.radioLanguageRo.isChecked = true
            "ru" -> this.binding.radioLanguageRu.isChecked = true
            "sk" -> this.binding.radioLanguageSk.isChecked = true
            "sv" -> this.binding.radioLanguageSv.isChecked = true
            "zh" -> this.binding.radioLanguageZh.isChecked = true
            else -> this.binding.radioLanguageSystem.isChecked = true
        }
        //
        supportActionBar?.hide()    //タイトルバー非表示
    }

    fun onClickApply(v: View) {
        val continuousScan = if (this.binding.switchContinuousScan.isChecked) 1 else 0
        val beepSoundWhenScan = if (this.binding.switchBeepSoundWhenScan.isChecked) 1 else 0
        val fixedOrientation = if (this.binding.switchFixedOrientation.isChecked) 1 else 0
        val themeNumber = if (this.binding.switchTheme.isChecked) 1 else 0
        var localeLanguage: String = ""
        if (this.binding.radioLanguageEn.isChecked) {
            localeLanguage = "en"
        } else if (this.binding.radioLanguageBg.isChecked) {
            localeLanguage = "bg"
        } else if (this.binding.radioLanguageCs.isChecked) {
            localeLanguage = "cs"
        } else if (this.binding.radioLanguageDa.isChecked) {
            localeLanguage = "da"
        } else if (this.binding.radioLanguageDe.isChecked) {
            localeLanguage = "de"
        } else if (this.binding.radioLanguageEl.isChecked) {
            localeLanguage = "el"
        } else if (this.binding.radioLanguageEs.isChecked) {
            localeLanguage = "es"
        } else if (this.binding.radioLanguageEt.isChecked) {
            localeLanguage = "et"
        } else if (this.binding.radioLanguageFi.isChecked) {
            localeLanguage = "fi"
        } else if (this.binding.radioLanguageFr.isChecked) {
            localeLanguage = "fr"
        } else if (this.binding.radioLanguageHu.isChecked) {
            localeLanguage = "hu"
        } else if (this.binding.radioLanguageIt.isChecked) {
            localeLanguage = "it"
        } else if (this.binding.radioLanguageJa.isChecked) {
            localeLanguage = "ja"
        } else if (this.binding.radioLanguageLt.isChecked) {
            localeLanguage = "lt"
        } else if (this.binding.radioLanguageLv.isChecked) {
            localeLanguage = "lv"
        } else if (this.binding.radioLanguageNl.isChecked) {
            localeLanguage = "nl"
        } else if (this.binding.radioLanguagePl.isChecked) {
            localeLanguage = "pl"
        } else if (this.binding.radioLanguagePt.isChecked) {
            localeLanguage = "pt"
        } else if (this.binding.radioLanguageRo.isChecked) {
            localeLanguage = "ro"
        } else if (this.binding.radioLanguageRu.isChecked) {
            localeLanguage = "ru"
        } else if (this.binding.radioLanguageSk.isChecked) {
            localeLanguage = "sk"
        } else if (this.binding.radioLanguageSv.isChecked) {
            localeLanguage = "sv"
        } else if (this.binding.radioLanguageZh.isChecked) {
            localeLanguage = "zh"
        }
        val intent = Intent()
        intent.putExtra(MainActivity.CONTINUOUS_SCAN, continuousScan)
        intent.putExtra(MainActivity.BEEP_SOUND_WHEN_SCAN, beepSoundWhenScan)
        intent.putExtra(MainActivity.FIXED_ORIENTATION, fixedOrientation)
        intent.putExtra(MainActivity.THEME_NUMBER, themeNumber)
        intent.putExtra(MainActivity.LOCALE_LANGUAGE, localeLanguage)
        setResult(Activity.RESULT_OK, intent)
        finish()
    }

    fun onClickCancel(v: View) {
        val intent = Intent()
        setResult(Activity.RESULT_CANCELED, intent)
        finish()
    }

    //--------------------------------------------------------------------------------

    //言語設定
    override fun attachBaseContext(base: Context) {
        val pref = base.getSharedPreferences(MainActivity.SETTINGS, Context.MODE_PRIVATE)
        val localeLanguage: String = pref.getString(MainActivity.LOCALE_LANGUAGE, "") ?: ""
        val loc: Locale? = if (localeLanguage != "") Locale(localeLanguage) else null
        if (loc != null) {
            val res = base.resources
            val config = Configuration(res.configuration)
            val localeList = LocaleList(loc)
            LocaleList.setDefault(localeList)
            config.setLocales(localeList)
            super.attachBaseContext(base.createConfigurationContext(config))
        } else {
            super.attachBaseContext(base)
        }
    }

    //--------------------------------------------------------------------------------

}

app/src/main/res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layoutBase"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:paddingBottom="20dp">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="48dip"
                    android:layout_marginTop="1dp"
                    android:orientation="horizontal">

                    <TextView
                        android:id="@+id/textView"
                        android:layout_width="wrap_content"
                        android:layout_height="48dip"
                        android:layout_weight="1"
                        android:background="#7462C5"
                        android:gravity="center"
                        android:paddingLeft="10dp"
                        android:paddingRight="10dp"
                        android:text="@string/title" />

                    <TextView
                        android:id="@+id/textSettings"
                        android:layout_width="wrap_content"
                        android:layout_height="48dip"
                        android:layout_marginStart="1dp"
                        android:layout_weight="1"
                        android:background="#6276C5"
                        android:gravity="center"
                        android:minHeight="48dip"
                        android:onClick="onClickSetting"
                        android:text="@string/settings" />
                </LinearLayout>

                <TextView
                    android:id="@+id/textScan"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#6093C5"
                    android:gravity="center"
                    android:minHeight="96dip"
                    android:onClick="onClickButtonScan"
                    android:text="@string/buttonScan" />

                <TextView
                    android:id="@+id/textCopy"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#5FB1C6"
                    android:gravity="center"
                    android:minHeight="60dip"
                    android:onClick="onClickButtonCopy"
                    android:text="@string/buttonCopy" />

                <TextView
                    android:id="@+id/textSend"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#5DC6AF"
                    android:gravity="center"
                    android:minHeight="60dip"
                    android:onClick="onClickButtonSend"
                    android:text="@string/buttonSend" />

                <TextView
                    android:id="@+id/textDelete"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#5DC674"
                    android:gravity="center"
                    android:minHeight="48dip"
                    android:onClick="onClickButtonDelete"
                    android:text="@string/buttonDelete" />

                <TextView
                    android:id="@+id/textCopyLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#86C663"
                    android:gravity="center"
                    android:minHeight="60dip"
                    android:onClick="onClickButtonCopyLast"
                    android:text="@string/buttonCopyLast" />

                <TextView
                    android:id="@+id/textSendLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#BFC663"
                    android:gravity="center"
                    android:minHeight="60dip"
                    android:onClick="onClickButtonSendLast"
                    android:text="@string/buttonSendLast" />

                <TextView
                    android:id="@+id/textBrowserLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#C69D65"
                    android:gravity="center"
                    android:minHeight="60dip"
                    android:onClick="onClickButtonBrowserLast"
                    android:text="@string/buttonBrowserLast" />

                <TextView
                    android:id="@+id/textDeleteLast"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="1dp"
                    android:layout_weight="1"
                    android:background="#C77C64"
                    android:gravity="center"
                    android:minHeight="48dip"
                    android:onClick="onClickButtonDeleteLast"
                    android:text="@string/buttonDeleteLast" />

                <EditText
                    android:id="@+id/editText1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="5dp"
                    android:layout_marginTop="15dp"
                    android:layout_marginRight="5dp"
                    android:autofillHints=""
                    android:background="@drawable/border"
                    android:ems="10"
                    android:focusable="false"
                    android:focusableInTouchMode="false"
                    android:gravity="start|top"
                    android:inputType="textMultiLine"
                    android:paddingLeft="5dp"
                    android:paddingTop="2dp"
                    android:paddingRight="5dp"
                    android:paddingBottom="2dp"
                    android:textSize="13sp" />

                <Space
                    android:layout_width="match_parent"
                    android:layout_height="120dp" />

            </LinearLayout>
        </ScrollView>
    </LinearLayout>

    <LinearLayout
        android:id="@+id/ad_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent">

    </LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

app/src/main/res/layout/activity_setting.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SettingActivity">

    <LinearLayout
        android:id="@+id/layoutButtons"
        android:layout_width="match_parent"
        android:layout_height="48dip"
        android:layout_marginTop="1dp"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textCancel"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="6"
            android:background="#86C663"
            android:gravity="center"
            android:minHeight="48dip"
            android:onClick="onClickCancel"
            android:text="@string/cancel" />

        <TextView
            android:id="@+id/textVerification"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="1dp"
            android:layout_weight="6"
            android:background="#5DC674"
            android:gravity="center"
            android:minHeight="48dip"
            android:onClick="onClickApply"
            android:text="@string/apply" />

    </LinearLayout>
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/layoutButtons">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:orientation="vertical"
            android:paddingLeft="20dp"
            android:paddingTop="20dp"
            android:paddingRight="20dp"
            android:paddingBottom="50dp">

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchContinuousScan"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/continuousScan" />

            <View
                android:id="@+id/divider1"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchBeepSoundWhenScan"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/BeepSoundWhenScan" />

            <View
                android:id="@+id/divider2"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchFixedOrientation"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/fixedOrientation" />

            <View
                android:id="@+id/divider3"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <androidx.appcompat.widget.SwitchCompat
                android:id="@+id/switchTheme"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="10dp"
                android:text="@string/darkTheme" />

            <View
                android:id="@+id/divider4"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="10dp"
                android:background="?android:attr/listDivider" />

            <TextView
                android:id="@+id/textLanguage"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:text="@string/language"
                android:textColor="?android:attr/textColorPrimary" />

            <TextView
                android:id="@+id/textView2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                android:text="@string/languageNote" />

            <RadioGroup
                android:layout_width="match_parent"
                android:layout_height="match_parent" >
                <RadioButton
                    android:id="@+id/radioLanguageSystem"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageSystem" />
                <RadioButton
                    android:id="@+id/radioLanguageEn"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEn" />
                <RadioButton
                    android:id="@+id/radioLanguageBg"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageBg" />
                <RadioButton
                    android:id="@+id/radioLanguageCs"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageCs" />
                <RadioButton
                    android:id="@+id/radioLanguageDa"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageDa" />
                <RadioButton
                    android:id="@+id/radioLanguageDe"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageDe" />
                <RadioButton
                    android:id="@+id/radioLanguageEl"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEl" />
                <RadioButton
                    android:id="@+id/radioLanguageEs"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEs" />
                <RadioButton
                    android:id="@+id/radioLanguageEt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageEt" />
                <RadioButton
                    android:id="@+id/radioLanguageFi"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageFi" />
                <RadioButton
                    android:id="@+id/radioLanguageFr"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageFr" />
                <RadioButton
                    android:id="@+id/radioLanguageHu"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageHu" />
                <RadioButton
                    android:id="@+id/radioLanguageIt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageIt" />
                <RadioButton
                    android:id="@+id/radioLanguageJa"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageJa" />
                <RadioButton
                    android:id="@+id/radioLanguageLt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageLt" />
                <RadioButton
                    android:id="@+id/radioLanguageLv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageLv" />
                <RadioButton
                    android:id="@+id/radioLanguageNl"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageNl" />
                <RadioButton
                    android:id="@+id/radioLanguagePl"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languagePl" />
                <RadioButton
                    android:id="@+id/radioLanguagePt"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languagePt" />
                <RadioButton
                    android:id="@+id/radioLanguageRo"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageRo" />
                <RadioButton
                    android:id="@+id/radioLanguageRu"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageRu" />
                <RadioButton
                    android:id="@+id/radioLanguageSk"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageSk" />
                <RadioButton
                    android:id="@+id/radioLanguageSv"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageSv" />
                <RadioButton
                    android:id="@+id/radioLanguageZh"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/languageZh" />

            </RadioGroup>


            <View
                android:id="@+id/divider5"
                android:layout_width="match_parent"
                android:layout_height="1dp"
                android:layout_marginTop="20dp"
                android:background="?android:attr/listDivider" />

            <Space
                android:layout_width="match_parent"
                android:layout_height="120dp" />


        </LinearLayout>
    </ScrollView>

</androidx.constraintlayout.widget.ConstraintLayout>

app/src/main/res/layout/custom_toast_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	xmlns:app="http://schemas.android.com/apk/res-auto"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:id="@+id/toast_container">

	<RelativeLayout
		android:id="@+id/button_parent"
		android:layout_width="match_parent"
		android:layout_height="60dp"
		android:layout_centerHorizontal="true"
		android:layout_centerVertical="true">

		<androidx.cardview.widget.CardView
			android:id="@+id/button_card_parent"
			android:layout_width="match_parent"
			android:layout_height="56dp"
			android:layout_centerHorizontal="true"
			android:layout_centerVertical="true"
			android:layout_marginLeft="25dp"
			app:cardElevation="20dp"
			android:layout_marginRight="25dp"
			app:cardCornerRadius="3dp">

			<RelativeLayout
				android:id="@+id/button_click_parent"
				android:layout_width="match_parent"
				android:layout_height="match_parent"
				android:background="?attr/selectableItemBackground"
				android:clickable="true"
				android:focusable="true">

				<FrameLayout
					android:id="@+id/button_accent_border"
					android:layout_width="5dp"
					android:layout_height="match_parent"
					android:background="#9071c6" />

				<TextView
					android:id="@+id/toast_text"
					android:layout_width="wrap_content"
					android:layout_height="wrap_content"
					android:layout_centerVertical="true"
					android:layout_marginStart="17dp"
					android:ellipsize="end"
					android:lines="1"
					android:textSize="18sp" />

			</RelativeLayout>

		</androidx.cardview.widget.CardView>

	</RelativeLayout>

</RelativeLayout>