app/src/main/java/jp/aosystem/basalmetabolism/MainActivity.kt
package jp.aosystem.basalmetabolism
import android.content.Context
import android.content.DialogInterface
import android.graphics.Shader
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.DisplayMetrics
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
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.basalmetabolism.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var viewModel: ConstraintLayout
private var inputMethodManager: InputMethodManager? = null
private var configTheme: Int = 0 //0 or 1
//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
}
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.loadTheme() //テーマ読み込みと設定
//adMob
MobileAds.initialize(this) {}
this.adView = AdView(this)
this.binding.adContainer.addView(this.adView)
loadBanner()
//
this.setTouchListener()
this.binding.radioMan.isChecked = true
this.loadSetting()
if (this.binding.editHeight.text.toString() != "" && this.binding.editWeight.text.toString() != "" && this.binding.editAge.text.toString() != "") {
this.calc()
}
this.setTextChangeListener()
val d = ContextCompat.getDrawable(this, R.drawable.ic_pattern2)
this.binding.imageBack.setImageDrawable(d?.let { TileDrawable(it, Shader.TileMode.REPEAT) })
this.binding.imageView4.setImageResource(R.drawable.ic_leaf1)
}
//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 setTouchListener() {
this.inputMethodManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager?
this.binding.editHeight.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
this.inputMethodManager!!.hideSoftInputFromWindow( //キーボードを隠す
this.binding.editHeight.windowToken,
InputMethodManager.HIDE_NOT_ALWAYS
)
// 背景にフォーカスを移す
//this.binding.textTitle.requestFocus()
}
}
this.binding.editWeight.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
this.inputMethodManager!!.hideSoftInputFromWindow( //キーボードを隠す
this.binding.editWeight.windowToken,
InputMethodManager.HIDE_NOT_ALWAYS
)
// 背景にフォーカスを移す
//this.binding.textTitle.requestFocus()
}
}
this.binding.editAge.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) {
this.inputMethodManager!!.hideSoftInputFromWindow( //キーボードを隠す
this.binding.editAge.windowToken,
InputMethodManager.HIDE_NOT_ALWAYS
)
// 背景にフォーカスを移す
//this.binding.textTitle.requestFocus()
}
}
}
private fun setTextChangeListener() {
this.binding.editHeight.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
this@MainActivity.calc()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
//
this.binding.editWeight.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
this@MainActivity.calc()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
//
this.binding.editAge.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
this@MainActivity.calc()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
//
this.binding.radioGroup1.setOnCheckedChangeListener { radioGroup, optionId ->
run {
this@MainActivity.calc()
}
}
}
private fun calc() {
val valHeight: Int = this.binding.editHeight.text.toString().toIntOrNull() ?: 0
val valWeight: Int = this.binding.editWeight.text.toString().toIntOrNull() ?: 0
val valAge: Int = this.binding.editAge.text.toString().toIntOrNull() ?: 0
val valGender: Int = if (this.binding.radioMan.isChecked) 1 else 2
//
var ansA1: Int = 0
when (valGender) {
1 -> ansA1 = (66.4730 + (13.7516 * valWeight) + (5.0033 * valHeight) - (6.7550 * valAge)).toInt()
2 -> ansA1 = (655.0955 + (9.5634 * valWeight) + (1.8496 * valHeight) - (4.6756 * valAge)).toInt()
}
this.binding.textResultA1a.text = ansA1.toString() + " kcal"
this.binding.textResultA2a.text = (ansA1 * 1.5).toInt().toString() + " kcal"
this.binding.textResultA3a.text = (ansA1 * 1.75).toInt().toString() + " kcal"
this.binding.textResultA4a.text = (ansA1 * 2).toString() + " kcal"
//
var ansB1: Int = 0
when (valGender) {
1 -> ansB1 = (((0.1238 + (0.0481 * valWeight) + (0.0234 * valHeight) - (0.0138 * valAge) - 0.5473)) * 1000 / 4.186).toInt()
2 -> ansB1 = (((0.1238 + (0.0481 * valWeight) + (0.0234 * valHeight) - (0.0138 * valAge) - 0.5473 * 2)) * 1000 / 4.186).toInt()
}
this.binding.textResultB1a.text = ansB1.toString() + " kcal"
this.binding.textResultB2a.text = (ansB1 * 1.5).toInt().toString() + " kcal"
this.binding.textResultB3a.text = (ansB1 * 1.75).toInt().toString() + " kcal"
this.binding.textResultB4a.text = (ansB1 * 2).toString() + " kcal"
//
this.saveSetting()
}
//--------------------------------------------------------------------------------
//身長・体重・年齢・性別を保存
private fun saveSetting() {
getSharedPreferences("settings", Context.MODE_PRIVATE).edit().apply {
putString("valueHeight", this@MainActivity.binding.editHeight.text.toString())
putString("valueWeight", this@MainActivity.binding.editWeight.text.toString())
putString("valueAge", this@MainActivity.binding.editAge.text.toString())
putString("valueGender", if (this@MainActivity.binding.radioMan.isChecked) "1" else "2")
apply()
}
}
//身長・体重・年齢・性別を読み出し
private fun loadSetting() {
val pref = getSharedPreferences("settings", Context.MODE_PRIVATE)
this.binding.editHeight.setText(pref.getString("valueHeight", "").toString())
this.binding.editWeight.setText(pref.getString("valueWeight", "").toString())
this.binding.editAge.setText(pref.getString("valueAge", "").toString())
when (pref.getString("valueGender", "1").toString().toInt()) {
1 -> this.binding.radioMan.isChecked = true
2 -> this.binding.radioWoman.isChecked = true
}
}
//--------------------------------------------------------------------------------
//テーマを保存
private fun saveTheme() {
getSharedPreferences("settings", Context.MODE_PRIVATE).edit().apply {
putString("valueTheme", this@MainActivity.configTheme.toString())
apply()
recreate()
}
}
//テーマを読み出し
private fun loadTheme() {
val pref = getSharedPreferences("settings", Context.MODE_PRIVATE)
this.configTheme = pref.getString("valueTheme", "0")?.toInt() ?: 0
when (this.configTheme) {
0 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
1 -> AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
}
}
fun onClickButtonTheme(v: View) {
val dialogMenu = arrayOf<String>("Light","Dark")
val theme: Int = this.configTheme
var selectedId: Int = theme
AlertDialog.Builder(this).apply { // FragmentではActivityを取得して生成
setTitle("テーマ変更")
setSingleChoiceItems(dialogMenu, theme) { _, which ->
selectedId = which
}
setPositiveButton("適用", DialogInterface.OnClickListener { _, _ ->
when (selectedId) {
0 -> this@MainActivity.configTheme = 0
1 -> this@MainActivity.configTheme = 1
}
this@MainActivity.saveTheme()
})
setNegativeButton("キャンセル", null)
show()
}
}
//--------------------------------------------------------------------------------
}
app/src/main/java/jp/aosystem/basalmetabolism/TileDrawable.kt
package jp.aosystem.basalmetabolism
import android.graphics.Bitmap
import android.graphics.BitmapShader
import android.graphics.Canvas
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.Shader
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
class TileDrawable(drawable: Drawable, tileMode: Shader.TileMode) : Drawable() {
private val paint: Paint
init {
paint = Paint().apply {
shader = BitmapShader(getBitmap(drawable), tileMode, tileMode)
}
}
override fun draw(canvas: Canvas) {
canvas.drawPaint(paint)
}
override fun setAlpha(alpha: Int) {
paint.alpha = alpha
}
override fun getOpacity() = PixelFormat.TRANSLUCENT
override fun setColorFilter(colorFilter: ColorFilter?) {
paint.colorFilter = colorFilter
}
private fun getBitmap(drawable: Drawable): Bitmap {
if (drawable is BitmapDrawable) {
return drawable.bitmap
}
val bmp = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight,
Bitmap.Config.ARGB_8888)
val c = Canvas(bmp)
drawable.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
drawable.draw(c)
return bmp
}
}