- エーオーシステム コーポレートサイト
https://www.aosystem.co.jp/ - エーオーシステム プロダクトサイト
https://ao-system.net/ - レンタルサーバー
- バーチャル展示会
- ウェブカタログサービス
- 3Dグラフィック
- Android アプリ
- iOS (iPhone,iPad) アプリ
- Flutter開発
- プログラミング記録QuickAnswer
- 無料画像素材
- スカイボックス 3D SKY BOX
このページのQRコード
下記アプリの主要なソースコードを公開しています。アプリ開発の参考になれば幸いです。
画像等が別途必要ですので下記情報のみでアプリが完成するものではありません。 アプリは少しずつ機能拡張していますのでストア公開されているアプリと内容が異なる場合があります。 コードはコピーして自由にお使いいただけます。ただし著作権は放棄しておりませんので全部の再掲載はご遠慮ください。部分的に再掲載したり、改変して再掲載するのは構いません。 自身のアプリ作成の参考として個人使用・商用問わず自由にお使いいただけます。 コード記述のお手本を示すものではありません。ミニアプリですので変数名などさほど気遣いしていない部分も有りますし間違いも有るかと思いますので参考程度にお考え下さい。 他の賢者の皆様が公開されているコードを参考にした箇所も含まれます。Androidアプリ開発の熟練者が書いたコードではありません。 エンジニア向け技術情報共有サービスではありませんので説明は省いています。ご了承ください。 GitHubなどへの公開は予定しておりません。
// 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
}
plugins {
id 'com.android.application'
id 'kotlin-android'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "jp.aosystem.numberroulette"
minSdkVersion 21
targetSdkVersion 30
multiDexEnabled true
versionCode 10
versionName "1.9"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
}
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'
implementation 'androidx.preference:preference-ktx:1.1.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.aosystem.numberroulette">
<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.NumberRoulette">
<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=".SettingActivity" />
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-0000000000000000~0000000000">
</application>
</manifest>
package jp.aosystem.numberroulette
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.os.LocaleList
import android.util.DisplayMetrics
import android.view.View
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 jp.aosystem.numberroulette.databinding.ActivityMainBinding
import java.util.*
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: ConstraintLayout
private lateinit var customSurfaceView: CustomSurfaceView
private var minNumber: Int = 0
private var maxNumber: Int = 5
private var positionReverse: Int = 0 //0 or 1
private var positionRandom: Int = 0 //0 or 1
private var shortenRotation: Int = 0 //0 or 1
private var speechNumber: Int = 0 //数字を読み上げるか否か 0 or 1
private var themeNumber: Int = 0 //0 or 1
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-3940256099942544/6300978111" //adMob Test
private const val AD_UNIT_ID: String = "ca-app-pub-0000000000000000/0000000000" //adMob
private const val RESULT_SETTING_ACTIVITY: Int = 2
internal const val SETTINGS: String = "settings"
internal const val MIN_NUMBER: String = "minNumber"
internal const val MAX_NUMBER: String = "maxNumber"
internal const val POSITION_REVERSE: String = "positionReverse"
internal const val POSITION_RANDOM: String = "positionRandom"
internal const val SHORTEN_ROTATION: String = "shortenRotation"
internal const val SPEECH_NUMBER: String = "speechNumber"
internal const val THEME_NUMBER: String = "themeNumber"
internal const val LOCALE_LANGUAGE: String = "localeLanguage"
}
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() //タイトルバー非表示
//テーマ読み込みと設定
this.loadThemeNumber()
this.setTheme()
//設定読み込み
this.loadMinNumber()
this.loadMaxNumber()
this.loadPositionReverse()
this.loadPositionRandom()
this.loadShortenRotation()
this.loadSpeechNumber()
//adMob
MobileAds.initialize(this) {}
this.adView = AdView(this)
this.binding.adContainer.addView(this.adView)
this.loadBanner()
}
override fun onResume() {
super.onResume()
this.customSurfaceViewStart()
}
//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 customSurfaceViewStart() {
this.customSurfaceView = CustomSurfaceView(this,
this.binding.surfaceView1,
this.minNumber,
this.maxNumber,
this.positionReverse,
this.positionRandom,
this.shortenRotation,
this.speechNumber,
this.localeLanguage
)
/*
this.customSurfaceView.setOnTouchListener { v, event ->
customSurfaceView.onTouch(event)
}
*/
}
fun onClickStart(v: View) {
if (::customSurfaceView.isInitialized) {
this.customSurfaceView.onClickStart()
}
}
//-------------------------------------------------
fun onClickSetting(v: View?) {
if (::customSurfaceView.isInitialized) {
this.customSurfaceView.setDestroy()
}
val intent = Intent(applicationContext, SettingActivity::class.java)
intent.putExtra(MIN_NUMBER, this.minNumber)
intent.putExtra(MAX_NUMBER, this.maxNumber)
intent.putExtra(POSITION_REVERSE, this.positionReverse)
intent.putExtra(POSITION_RANDOM, this.positionRandom)
intent.putExtra(SHORTEN_ROTATION, this.shortenRotation)
intent.putExtra(SPEECH_NUMBER, this.speechNumber)
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?) {
super.onActivityResult(requestCode, resultCode, intent)
if (resultCode == Activity.RESULT_OK && requestCode == RESULT_SETTING_ACTIVITY && intent != null) {
this.minNumber = intent.getIntExtra(MIN_NUMBER, 0)
this.saveMinNumber() //数値のチェックも兼ねる
//
this.maxNumber = intent.getIntExtra(MAX_NUMBER, 1)
this.saveMaxNumber() //数値のチェックも兼ねる
//
val lastPositionReverse: Int = this.positionReverse
this.positionReverse = intent.getIntExtra(POSITION_REVERSE, 0)
if (lastPositionReverse != this.positionReverse) {
this.savePositionReverse()
}
//
val lastPositionRandom: Int = this.positionRandom
this.positionRandom = intent.getIntExtra(POSITION_RANDOM, 0)
if (lastPositionRandom != this.positionRandom) {
this.savePositionRandom()
}
//
val lastShortenRotation: Int = this.shortenRotation
this.shortenRotation = intent.getIntExtra(SHORTEN_ROTATION, 0)
if (lastShortenRotation != this.shortenRotation) {
this.saveShortenRotation()
}
//
val lastSpeechNumber: Int = this.speechNumber
this.speechNumber = intent.getIntExtra(SPEECH_NUMBER, 1)
if (lastSpeechNumber != this.speechNumber) {
this.saveSpeechNumber()
}
//
val lastThemeNumber: Int = this.themeNumber
this.themeNumber = intent.getIntExtra(THEME_NUMBER, 0)
if (lastThemeNumber != this.themeNumber) {
this.saveThemeNumber()
}
val lastLocaleLanguage = this.localeLanguage
this.localeLanguage = intent.getStringExtra(LOCALE_LANGUAGE) ?: ""
if (this.localeLanguage != lastLocaleLanguage) {
this.saveLocaleLanguage()
}
}
recreate()
}
//-------------------------------------------------
//minNumberを保存
private fun saveMinNumber() {
if (this.minNumber < 0) {
this.minNumber = 0
}
getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
putInt(MIN_NUMBER, this@MainActivity.minNumber)
apply()
}
}
//minNumberを読み出し
private fun loadMinNumber() {
val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
this.minNumber = pref.getInt(MIN_NUMBER, 0)
if (this.minNumber < 0) {
this.saveMinNumber()
}
}
//-------------------------------------------------
//maxNumberを保存
private fun saveMaxNumber() {
if (this.maxNumber <= this.minNumber) {
this.maxNumber = this.minNumber + 1
} else if (this.maxNumber - this.minNumber >= 3600) {
this.maxNumber = this.minNumber + 3599
}
getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
putInt(MAX_NUMBER, this@MainActivity.maxNumber)
apply()
}
}
//maxNumberを読み出し
private fun loadMaxNumber() {
val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
this.maxNumber = pref.getInt(MAX_NUMBER, 5)
if (this.maxNumber <= this.minNumber) {
this.saveMaxNumber()
} else if (this.maxNumber - this.minNumber >= 3600) {
this.saveMaxNumber()
}
}
//-------------------------------------------------
//positionReverseを保存
private fun savePositionReverse() {
getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
putInt(POSITION_REVERSE, this@MainActivity.positionReverse)
apply()
}
}
//positionReverseを読み出し
private fun loadPositionReverse() {
val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
this.positionReverse = pref.getInt(POSITION_REVERSE, 0)
}
//-------------------------------------------------
//positionRandomを保存
private fun savePositionRandom() {
getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
putInt(POSITION_RANDOM, this@MainActivity.positionRandom)
apply()
}
}
//positionRandomを読み出し
private fun loadPositionRandom() {
val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
this.positionRandom = pref.getInt(POSITION_RANDOM, 0)
}
//-------------------------------------------------
//shortenRotationを保存
private fun saveShortenRotation() {
getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
putInt(SHORTEN_ROTATION, this@MainActivity.shortenRotation)
apply()
}
}
//shortenRotationを読み出し
private fun loadShortenRotation() {
val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
this.shortenRotation = pref.getInt(SHORTEN_ROTATION, 0)
}
//-------------------------------------------------
//数字読み上げを保存
private fun saveSpeechNumber() {
getSharedPreferences(SETTINGS, Context.MODE_PRIVATE).edit().apply {
putInt(SPEECH_NUMBER, this@MainActivity.speechNumber)
apply()
}
}
//数字読み上げを読み出し
private fun loadSpeechNumber() {
val pref = getSharedPreferences(SETTINGS, Context.MODE_PRIVATE)
this.speechNumber = pref.getInt(SPEECH_NUMBER, 1)
}
//-------------------------------------------------
//テーマを保存
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)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //minSdkVersion 24
val localeList = LocaleList(loc)
LocaleList.setDefault(localeList)
config.setLocales(localeList)
} else { //minSdkVersion 17 16はダメ
config.setLocale(loc)
}
super.attachBaseContext(base.createConfigurationContext(config))
} else {
super.attachBaseContext(base)
}
}
//----------------------------------------------
}
package jp.aosystem.numberroulette
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.res.Configuration
import android.os.Build
import android.os.Bundle
import android.os.LocaleList
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import jp.aosystem.numberroulette.databinding.ActivitySettingBinding
import java.util.*
class SettingActivity : AppCompatActivity() {
private lateinit var binding: ActivitySettingBinding
private lateinit var viewModel: ConstraintLayout
private var inputMethodManager: InputMethodManager? = null
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 minNumber: Int = intent.getIntExtra(MainActivity.MIN_NUMBER,0)
this.binding.editMinNumber.setText(minNumber.toString())
val maxNumber: Int = intent.getIntExtra(MainActivity.MAX_NUMBER,1)
this.binding.editMaxNumber.setText(maxNumber.toString())
val positionReverse: Int = intent.getIntExtra(MainActivity.POSITION_REVERSE,0)
this.binding.switchPositionReverse.isChecked = positionReverse != 0
val positionRandom: Int = intent.getIntExtra(MainActivity.POSITION_RANDOM,0)
this.binding.switchPositionRandom.isChecked = positionRandom != 0
val shortenRotation: Int = intent.getIntExtra(MainActivity.SHORTEN_ROTATION,0)
this.binding.switchShortenRotation.isChecked = shortenRotation != 0
val speechNumber: Int = intent.getIntExtra(MainActivity.SPEECH_NUMBER,0)
this.binding.switchSpeechNumber.isChecked = speechNumber != 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() //タイトルバー非表示
//
this.setTouchListener()
}
//背景タッチでテキストエリアからフォーカスを外してキーボードを隠す
private fun setTouchListener() {
this.inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
this.binding.editMinNumber.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
this.inputMethodManager!!.hideSoftInputFromWindow( //キーボードを隠す
this.binding.editMinNumber.windowToken,
InputMethodManager.HIDE_NOT_ALWAYS
)
}
}
this.binding.editMaxNumber.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
this.inputMethodManager!!.hideSoftInputFromWindow( //キーボードを隠す
this.binding.editMaxNumber.windowToken,
InputMethodManager.HIDE_NOT_ALWAYS
)
}
}
}
fun onClickApply(v: View) {
val minNumber: Int = ("0" + this.binding.editMinNumber.text.toString()).toInt()
val maxNumber: Int = ("0" + this.binding.editMaxNumber.text.toString()).toInt()
val positionReverse = if (this.binding.switchPositionReverse.isChecked) 1 else 0
val positionRandom = if (this.binding.switchPositionRandom.isChecked) 1 else 0
val shortenRotation = if (this.binding.switchShortenRotation.isChecked) 1 else 0
val speechNumber: Int = if (this.binding.switchSpeechNumber.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.MIN_NUMBER, minNumber)
intent.putExtra(MainActivity.MAX_NUMBER, maxNumber)
intent.putExtra(MainActivity.POSITION_REVERSE, positionReverse)
intent.putExtra(MainActivity.POSITION_RANDOM, positionRandom)
intent.putExtra(MainActivity.SHORTEN_ROTATION, shortenRotation)
intent.putExtra(MainActivity.SPEECH_NUMBER, speechNumber)
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)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { //minSdkVersion 24
val localeList = LocaleList(loc)
LocaleList.setDefault(localeList)
config.setLocales(localeList)
} else { //minSdkVersion 17 16はダメ
config.setLocale(loc)
}
super.attachBaseContext(base.createConfigurationContext(config))
} else {
super.attachBaseContext(base)
}
}
//--------------------------------------------------------------------------------
}
package jp.aosystem.numberroulette
import android.content.Context
import android.graphics.*
import android.graphics.Path.FillType
import android.os.Handler
import android.os.Looper
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.view.SurfaceHolder
import android.view.SurfaceView
import java.util.*
import kotlin.math.*
import kotlin.random.Random
class CustomSurfaceView(
context: Context,
surfaceView: SurfaceView,
paramMinNumber: Int,
paramMaxNumber: Int,
paramPositionReverse: Int,
paramPositionRandom: Int,
paramShortenRotation: Int,
paramSpeechNumber: Int,
paramLocaleLanguage: String
) : SurfaceView(context), SurfaceHolder.Callback, TextToSpeech.OnInitListener {
private val colorLight: List<Int> = listOf(
Color.parseColor("#EF9A9A"),
Color.parseColor("#F48FB1"),
Color.parseColor("#CE93D8"),
Color.parseColor("#B39DDB"),
Color.parseColor("#9FA8DA"),
Color.parseColor("#90CAF9"),
Color.parseColor("#81D4fA"),
Color.parseColor("#80DEEA"),
Color.parseColor("#80CBC4"),
Color.parseColor("#A5D6A7"),
Color.parseColor("#C5E1A5"),
Color.parseColor("#E6EE9C"),
Color.parseColor("#FFF590"),
Color.parseColor("#FFE082"),
Color.parseColor("#FFCC80"),
Color.parseColor("#FFAB91"),
Color.parseColor("#E57373"),
Color.parseColor("#F06292"),
Color.parseColor("#BA68C8"),
Color.parseColor("#9575CD"),
Color.parseColor("#7986CB"),
Color.parseColor("#64B5F6"),
Color.parseColor("#4fC3F7"),
Color.parseColor("#4DD0E1"),
Color.parseColor("#4DB6AC"),
Color.parseColor("#81C784"),
Color.parseColor("#AED581"),
Color.parseColor("#DCE775"),
Color.parseColor("#FFF176"),
Color.parseColor("#FFD54F"),
Color.parseColor("#FFB74D"),
Color.parseColor("#FF8A65"),
)
private val colorDark: List<Int> = listOf(
Color.parseColor("#EF5350"),
Color.parseColor("#EC407A"),
Color.parseColor("#AB47BC"),
Color.parseColor("#7E57C2"),
Color.parseColor("#5C6BC0"),
Color.parseColor("#42A5F5"),
Color.parseColor("#29B6FC"),
Color.parseColor("#26C6DA"),
Color.parseColor("#26A69A"),
Color.parseColor("#66BB6A"),
Color.parseColor("#9CCC65"),
Color.parseColor("#D4E157"),
Color.parseColor("#FFEE58"),
Color.parseColor("#FFCA28"),
Color.parseColor("#FFA726"),
Color.parseColor("#FF7043"),
Color.parseColor("#F44336"),
Color.parseColor("#E91E63"),
Color.parseColor("#9C27B0"),
Color.parseColor("#673AB7"),
Color.parseColor("#3F51B5"),
Color.parseColor("#2196F3"),
Color.parseColor("#03A9F4"),
Color.parseColor("#00BCD4"),
Color.parseColor("#009688"),
Color.parseColor("#4CAF50"),
Color.parseColor("#8BC34A"),
Color.parseColor("#CDDC39"),
Color.parseColor("#FFEB3B"),
Color.parseColor("#FFC107"),
Color.parseColor("#FF9800"),
Color.parseColor("#FF5722"),
)
private var textToSpeech: TextToSpeech
private var surfaceHolder: SurfaceHolder? = null
//private var thread: Thread? = null
//private var prevBitmap: Bitmap? = null
//private var prevCanvas: Canvas? = null
private val adHeight: Int = 185
private val minNumber: Int = paramMinNumber
private val maxNumber: Int = paramMaxNumber
private val positionReverse: Int = paramPositionReverse
private val positionRandom: Int = paramPositionRandom
private val shortenRotation: Int = paramShortenRotation
private val speechNumber: Int = paramSpeechNumber
private val localeLanguage: String = paramLocaleLanguage
//
private var canvas: Canvas? = null
private var items: Array<Int> = arrayOf() //有効なアイテムのみ
private var canvasW: Float = 0F
private var canvasH: Float = 0F
private var boxSize: Float = 0F //描画できる正方形範囲の辺の長さ
private var boxPadding: Float = 0F //描画できる正方形範囲のpadding(上下左右)
private var centerX: Float = 0F //円の中心
private var centerY: Float = 0F //円の中心
private var half: Float = 0F //半径
private var colorCount: Int = this.colorLight.size //色数
private var whitePaint: Paint? = null //白のPaint
private var textPaint: Paint? = null //文字のPaint
private var textLargePaint: Paint? = null //文字のPaint
private var paints: Array<Pair<Paint,Paint>> = arrayOf() //円グラフのpaint
private var actionState: Int = 0 //回転状態
private var actionAngle: Float = Random.nextInt(360).toFloat() + Random.nextFloat() //回転の制御
private var actionCount: Int = 0 //回転の制御
private var destroyFlag: Boolean = false //Activity破棄された場合など
//
init {
this.surfaceHolder = surfaceView.holder
this.surfaceHolder!!.setFormat(PixelFormat.TRANSPARENT)
surfaceView.setZOrderOnTop(true)
this.surfaceHolder!!.addCallback(this)
//読み上げ
this.textToSpeech = TextToSpeech(context, this)
this.textToSpeech.setOnUtteranceProgressListener(object : UtteranceProgressListener() {
override fun onDone(utteranceId: String) {
}
override fun onError(utteranceId: String) {
}
override fun onStart(utteranceId: String) {
}
})
this.setSpeechLocale()
}
override fun onInit(status: Int) {
if (status == TextToSpeech.SUCCESS) {
this.setSpeechLocale()
}
}
override fun surfaceCreated(p0: SurfaceHolder) {
//initializeBitmap()
//this.thread = Thread()
//this.thread!!.start()
this.drawCanvas()
}
override fun surfaceChanged(p0: SurfaceHolder, format: Int, width: Int, height: Int) {
}
override fun surfaceDestroyed(p0: SurfaceHolder) {
this.destroyFlag = true
//this.prevBitmap!!.recycle()
//this.thread = null
}
private fun initializeBitmap() {
//if (this.prevBitmap == null) {
// this.prevBitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888)
//}
//if (this.prevCanvas == null) {
// this.prevCanvas = Canvas(this.prevBitmap!!)
//}
//this.prevCanvas!!.drawColor(0, PorterDuff.Mode.CLEAR)
}
fun setDestroy() {
this.textToSpeech.shutdown()
this.destroyFlag = true
}
//最初の描画と初期データ用意
private fun drawCanvas() {
this.initItemData() //有効なアイテム、レートの合計
this.initWhitePaint() //白Paint
this.initTextPaint() //文字Paint
this.initTextLargePaint() //文字Paint
this.initPaints() //円グラフPaint
this.canvas = Canvas()
this.canvas = this.surfaceHolder!!.lockCanvas() //ロックしてキャンバスを取得
this.canvas!!.drawColor(0, PorterDuff.Mode.CLEAR) //キャンバスのクリア
//this.canvas!!.drawBitmap(this.prevBitmap!!, 0F, 0F, null) //前回のビットマップをキャンバスに描画
//this.canvas!!.drawCircle(centerX, centerY - 300F, 300F, this.paint!!)
this.canvasW = this.canvas?.width!!.toFloat()
this.canvasH = (this.canvas?.height!!.minus(this.adHeight)).toFloat()
this.centerX = this.canvasW.div(2)
this.centerY = this.canvasH.div(2)
this.boxSize = if (canvasW <= canvasH) canvasW else canvasH
val clientSize: Float = this.boxSize.times(0.9).toFloat()
this.boxPadding = (this.boxSize - clientSize).div(2)
this.half = clientSize.div(2)
this.actionStartDraw(this.actionAngle)
this.surfaceHolder!!.unlockCanvasAndPost(this.canvas) //ロックを解除
}
fun onClickStart() {
this.actionState = 0
this.actionCount = 0
actionTimeline()
}
private fun actionTimeline() {
Handler(Looper.getMainLooper()).postDelayed({
if (this.destroyFlag) {
return@postDelayed
}
actionStart(this.actionAngle)
when (this.actionState) {
0 -> { //回転徐々に早く
this.actionAngle += this.actionCount
this.actionCount += 1
if (this.actionCount > 50) {
this.actionAngle %= 360
this.actionCount = 0
if (this.shortenRotation == 1) {
this.actionCount = 51
}
this.actionState = 1
}
}
1 -> { //回転中
this.actionAngle += 89.7F + this.actionCount.div(10)
this.actionCount += 1
if (this.actionCount > 50) {
this.actionAngle += Random.nextInt(360).toFloat() + Random.nextFloat()
this.actionAngle %= 360
this.actionCount = 0
if (this.shortenRotation == 1) {
this.actionCount = 100
}
this.actionState = 2
}
}
2 -> { //回転徐々に停止
this.actionAngle += 100 - this.actionCount.div(2)
this.actionCount += 1
if (this.actionCount > 200) {
this.actionAngle %= 360
this.actionCount = 0
this.actionState = 3
}
}
3 -> { //終了
return@postDelayed
}
}
actionTimeline()
}, 1)
}
private fun actionStart(startAngle: Float) {
this.canvas = Canvas()
this.canvas = this.surfaceHolder!!.lockCanvas() //ロックしてキャンバスを取得
this.canvas!!.drawColor(0, PorterDuff.Mode.CLEAR) //キャンバスのクリア
this.actionStartDraw(startAngle)
this.surfaceHolder!!.unlockCanvasAndPost(this.canvas) //ロックを解除
}
private fun actionStartDraw(paramStartAngle: Float) {
var startAngle: Float = paramStartAngle
val path = Path()
val singleAngle: Float = 360F.div(this.items.size) //書こうとする扇形の確度1個分
//判定結果計算
var nowSelectItem: Int = -1
for (i in this.items) {
val startAngleTmp: Float = startAngle % 360
if (((startAngleTmp <= 270F) && (startAngleTmp + singleAngle > 270F)) || ((startAngleTmp >= 270F) && (startAngleTmp + singleAngle >= 630F))) {
nowSelectItem = i
break
}
startAngle += singleAngle
}
//判定結果表示 back color
if (nowSelectItem != -1) { //念のため
path.fillType = FillType.EVEN_ODD
path.moveTo(0F, 0F)
path.lineTo(this.canvasW, 0F)
path.lineTo(this.canvasW, this.centerY + this.canvasH.div(2))
path.lineTo(0F, this.centerY + this.canvasH.div(2))
path.close()
this.canvas!!.drawPath(path, this.paints[nowSelectItem % this.colorCount].first)
}
//白丸
this.canvas!!.drawArc(this.centerX - this.half - this.boxPadding.div(2), this.centerY - this.half - this.boxPadding.div(2), this.centerX + this.half + this.boxPadding.div(2), this.centerY + this.half + this.boxPadding.div(2),-89.5F, 359F, true, this.whitePaint!!)
//円グラフ
startAngle = paramStartAngle
for (i in this.items) {
//circle
this.canvas!!.drawArc(this.centerX - this.half, this.centerY - this.half, this.centerX + this.half, this.centerY + this.half, startAngle, singleAngle, true, this.paints[i % this.colorCount].first)
//circle dark
this.canvas!!.drawArc(this.centerX - this.half.div(2), this.centerY - this.half.div(2), this.centerX + this.half.div(2), this.centerY + this.half.div(2), startAngle, singleAngle, true, this.paints[i % this.colorCount].second)
startAngle += singleAngle
}
//円グラフの文字
if (this.maxNumber - this.minNumber < 360) {
startAngle = paramStartAngle
for (i in this.items) {
//text
val textAngle: Float = (singleAngle.div(2) + startAngle) + 90
val textX: Float = sin(textAngle.times(PI.div(180))).times(this.half.div(1.1)).toFloat() - this.textPaint!!.textSize.div(2)
val textY: Float = cos(textAngle.times(PI.div(180))).times(this.half.div(1.1)).toFloat().times(-1) + this.textPaint!!.textSize.div(2)
this.canvas!!.drawText(i.toString(), textX + this.centerX, textY + this.centerY, this.textPaint!!)
startAngle += singleAngle
}
}
//判定結果表示 text
if (nowSelectItem != -1) { //念のため
this.canvas!!.drawText(nowSelectItem.toString(), this.textLargePaint!!.textSize, this.textLargePaint!!.textSize.times(1.5F), this.textLargePaint!!)
if (this.speechNumber == 1) {
this.speakText(nowSelectItem.toString())
}
}
}
private fun speakText(text: String) {
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, "utteranceId")
}
//minNumber,MaxNumberを参照して使用するデータの用意
private fun initItemData() {
this.items = arrayOf()
for (i in this.minNumber..this.maxNumber) {
this.items += i
}
if (this.positionRandom == 1) {
this.items.shuffle()
} else if (this.positionReverse == 1) {
this.items.reverse()
}
}
//白Paintの用意
private fun initWhitePaint() {
this.whitePaint = Paint().apply {
isAntiAlias = true
color = Color.rgb(255,255,255)
}
}
//文字Paintの用意
private fun initTextPaint() {
this.textPaint = Paint().apply {
isAntiAlias = true
color = Color.BLACK
textSize = 30F
}
}
//文字大Paintの用意
private fun initTextLargePaint() {
this.textLargePaint = Paint().apply {
isAntiAlias = true
color = Color.BLACK
textSize = 100F
}
}
//円グラフPaintの用意
private fun initPaints() {
this.paints = arrayOf()
for (i in this.colorLight.indices) {
this.paints +=
Pair(Paint().apply {
isAntiAlias = true
Paint.Style.FILL
color = this@CustomSurfaceView.colorLight[i]
},
Paint().apply {
isAntiAlias = true
Paint.Style.FILL
color = this@CustomSurfaceView.colorDark[i]
}
)
}
this.paints.shuffle()
}
//-------------------------------------------------
//音声の言語設定
private fun setSpeechLocale() {
val loc: Locale? = if (this.localeLanguage != "") Locale(this.localeLanguage) else null
if (loc != null) {
this.textToSpeech.let { tts ->
if (tts.isLanguageAvailable(loc) > TextToSpeech.LANG_AVAILABLE) {
tts.language = loc
} else {
// 言語の設定に失敗
}
}
}
}
//-------------------------------------------------
/*
/// 画面をタッチしたときにアクションごとに関数を呼び出す
fun onTouch(e: MotionEvent): Boolean {
when (e.action) {
MotionEvent.ACTION_DOWN -> touchDown(e.x, e.y)
//MotionEvent.ACTION_MOVE -> touchMove(e.x, e.y)
MotionEvent.ACTION_UP -> touchUp(e.x, e.y)
}
return true
}
private fun touchDown(x: Float, y: Float) {
}
private fun touchUp(x: Float, y: Float) {
}
*/
}
<?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:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<LinearLayout
android:id="@+id/layoutHeader"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:orientation="horizontal">
<TextView
android:id="@+id/textStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="5"
android:background="#6276C5"
android:gravity="center"
android:minHeight="96dip"
android:onClick="onClickStart"
android:text="@string/rouletteStart" />
<TextView
android:id="@+id/textSetting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_weight="1"
android:background="#6093C5"
android:gravity="center"
android:minHeight="96dip"
android:onClick="onClickSetting"
android:text="@string/setting" />
</LinearLayout>
<SurfaceView
android:id="@+id/surfaceView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</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" />
</androidx.constraintlayout.widget.ConstraintLayout>
<?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="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#86C663"
android:gravity="center"
android:minHeight="48dip"
android:onClick="onClickCancel"
android:text="@string/cancel" />
<TextView
android:id="@+id/textApply"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="1dp"
android:layout_weight="1"
android:background="#5DC6AF"
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="auto"
android:focusableInTouchMode="true"
android:orientation="vertical"
android:paddingBottom="50dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:orientation="vertical">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/numberRange"
android:textColor="?android:attr/textColorPrimary" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textMinNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/minNumber" />
<EditText
android:id="@+id/editMinNumber"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:ems="6"
android:inputType="number" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="@+id/textMaxNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/maxNumber" />
<EditText
android:id="@+id/editMaxNumber"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_weight="1"
android:ems="6"
android:inputType="number" />
</TableRow>
</TableLayout>
<View
android:id="@+id/divider5"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="20dp"
android:background="?android:attr/listDivider" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switchPositionReverse"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/positionReverse" />
<TextView
android:id="@+id/textPositionReverse1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/positionReverse1" />
<View
android:id="@+id/divider1"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="20dp"
android:background="?android:attr/listDivider" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switchPositionRandom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/positionRandom" />
<TextView
android:id="@+id/textPositionRandom1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/positionRandom1" />
<View
android:id="@+id/divider6"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="20dp"
android:background="?android:attr/listDivider" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switchShortenRotation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:text="@string/shortenRotation" />
<TextView
android:id="@+id/textShortenRotation1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/shortenRotation1" />
<View
android:id="@+id/divider8"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="20dp"
android:background="?android:attr/listDivider" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/switchSpeechNumber"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="@string/speech_number" />
<TextView
android:id="@+id/textView4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/speech_number1" />
<View
android:id="@+id/divider7"
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/textView3"
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/divider2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="20dp"
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/divider3"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_marginTop="10dp"
android:background="?android:attr/listDivider" />
<TextView
android:id="@+id/textUsage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/usage" />
<TextView
android:id="@+id/textUsage1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/usage1" />
<View
android:id="@+id/divider4"
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>
</LinearLayout>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
このページのQRコード
便利ウェブサイト
便利 Android アプリ
便利 iOS(iPhone,iPad) アプリ