diff --git a/app/build.gradle b/app/build.gradle index b7e4b541..32a9e407 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-parcelize' repositories { mavenCentral() @@ -44,10 +44,11 @@ android { vectorDrawables.useSupportLibrary = true } - lintOptions { - abortOnError false + buildFeatures { + viewBinding true } + flavorDimensions "default" productFlavors { @@ -63,7 +64,7 @@ android { } en { - resConfig "en" + resConfigs 'en' buildConfigField "Boolean", "DISCRETE", "false" manifestPlaceholders = [ @@ -114,6 +115,9 @@ android { kotlinOptions { jvmTarget = '1.8' } + lint { + abortOnError false + } } dependencies { @@ -134,7 +138,7 @@ dependencies { implementation 'com.google.android.material:material:1.7.0-alpha01' implementation 'com.google.android.flexbox:flexbox:3.0.0' implementation 'com.esotericsoftware:kryo:3.0.3' - implementation 'com.squareup.moshi:moshi-kotlin:1.9.2' + implementation 'com.squareup.moshi:moshi-kotlin:1.13.0' implementation 'com.squareup:otto:1.3.8' // api 'com.github.PhilJay:MPAndroidChart:v2.1.6' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' @@ -143,12 +147,8 @@ dependencies { implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' - api "org.jetbrains.kotlin:kotlin-reflect:1.5.20" - api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.5.30" - - kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.12.0' -} + api "org.jetbrains.kotlin:kotlin-reflect:1.6.21" + api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21" -androidExtensions { - experimental = true + kapt 'com.squareup.moshi:moshi-kotlin-codegen:1.13.0' } diff --git a/app/discrete/release/app-discrete-release.apk b/app/discrete/release/app-discrete-release.apk new file mode 100644 index 00000000..a3d83009 Binary files /dev/null and b/app/discrete/release/app-discrete-release.apk differ diff --git a/app/discrete/release/output-metadata.json b/app/discrete/release/output-metadata.json new file mode 100644 index 00000000..c3a26b4a --- /dev/null +++ b/app/discrete/release/output-metadata.json @@ -0,0 +1,20 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "me.anon.grow", + "variantName": "discreteRelease", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 2631, + "versionName": "2.6.4", + "outputFile": "app-discrete-release.apk" + } + ], + "elementType": "File" +} \ No newline at end of file diff --git a/app/en/release/app-en-release.apk b/app/en/release/app-en-release.apk new file mode 100644 index 00000000..da35b11a Binary files /dev/null and b/app/en/release/app-en-release.apk differ diff --git a/app/en/release/output-metadata.json b/app/en/release/output-metadata.json new file mode 100644 index 00000000..a65ae63f --- /dev/null +++ b/app/en/release/output-metadata.json @@ -0,0 +1,20 @@ +{ + "version": 3, + "artifactType": { + "type": "APK", + "kind": "Directory" + }, + "applicationId": "me.anon.grow", + "variantName": "enRelease", + "elements": [ + { + "type": "SINGLE", + "filters": [], + "attributes": [], + "versionCode": 2631, + "versionName": "2.6.4", + "outputFile": "app-en-release.apk" + } + ], + "elementType": "File" +} \ No newline at end of file diff --git a/app/src/main/java/me/anon/controller/adapter/ActionAdapter.java b/app/src/main/java/me/anon/controller/adapter/ActionAdapter.java index 2a0ca289..74593e10 100644 --- a/app/src/main/java/me/anon/controller/adapter/ActionAdapter.java +++ b/app/src/main/java/me/anon/controller/adapter/ActionAdapter.java @@ -41,7 +41,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.PopupMenu; import androidx.recyclerview.widget.RecyclerView; -import kotlinx.android.parcel.Parcelize; +import kotlinx.parcelize.Parcelize; import me.anon.grow.R; import me.anon.lib.DateRenderer; import me.anon.lib.TempUnit; diff --git a/app/src/main/java/me/anon/grow/ActionsActivity.kt b/app/src/main/java/me/anon/grow/ActionsActivity.kt index f6ebbb06..d77bec88 100644 --- a/app/src/main/java/me/anon/grow/ActionsActivity.kt +++ b/app/src/main/java/me/anon/grow/ActionsActivity.kt @@ -1,7 +1,7 @@ package me.anon.grow import android.os.Bundle -import kotlinx.android.synthetic.main.fragment_holder.* +import me.anon.grow.databinding.FragmentHolderBinding import me.anon.grow.fragment.ActionsListFragment class ActionsActivity : BaseActivity() @@ -11,7 +11,8 @@ class ActionsActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.fragment_holder) - setSupportActionBar(toolbar) + val binding = FragmentHolderBinding.inflate(layoutInflater) + setSupportActionBar(binding.toolbar) if (intent.extras == null || !intent.hasExtra("plant")) { diff --git a/app/src/main/java/me/anon/grow/AddWateringActivity.kt b/app/src/main/java/me/anon/grow/AddWateringActivity.kt index c0401a87..31f21698 100644 --- a/app/src/main/java/me/anon/grow/AddWateringActivity.kt +++ b/app/src/main/java/me/anon/grow/AddWateringActivity.kt @@ -2,7 +2,6 @@ package me.anon.grow import android.os.Bundle import androidx.appcompat.app.AlertDialog -import kotlinx.android.synthetic.main.fragment_holder.* import me.anon.grow.fragment.WateringFragment class AddWateringActivity : BaseActivity() @@ -12,7 +11,7 @@ class AddWateringActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.fragment_holder) - setSupportActionBar(toolbar) + setSupportActionBar(findViewById(R.id.toolbar)) var plantIndex: IntArray? = intent.extras?.getIntArray("plant_index") ?: intArrayOf(-1) var gardenIndex: Int = intent.extras?.getInt("garden_index", -1) ?: -1 diff --git a/app/src/main/java/me/anon/grow/FeedingScheduleActivity.kt b/app/src/main/java/me/anon/grow/FeedingScheduleActivity.kt index db581dda..36032fd4 100644 --- a/app/src/main/java/me/anon/grow/FeedingScheduleActivity.kt +++ b/app/src/main/java/me/anon/grow/FeedingScheduleActivity.kt @@ -1,7 +1,8 @@ package me.anon.grow import android.os.Bundle -import kotlinx.android.synthetic.main.fragment_holder.* +import android.view.View +import androidx.appcompat.widget.Toolbar import me.anon.grow.fragment.FeedingScheduleListFragment /** @@ -19,7 +20,7 @@ class FeedingScheduleActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.fragment_holder) - setSupportActionBar(toolbar) + setSupportActionBar(findViewById(R.id.toolbar) as Toolbar) setTitle(R.string.feeding_schedules_title) if (supportFragmentManager.findFragmentByTag(TAG_FRAGMENT) == null) diff --git a/app/src/main/java/me/anon/grow/FeedingScheduleDetailsActivity.kt b/app/src/main/java/me/anon/grow/FeedingScheduleDetailsActivity.kt index 213a3fcf..cd0d35e8 100644 --- a/app/src/main/java/me/anon/grow/FeedingScheduleDetailsActivity.kt +++ b/app/src/main/java/me/anon/grow/FeedingScheduleDetailsActivity.kt @@ -1,7 +1,8 @@ package me.anon.grow import android.os.Bundle -import kotlinx.android.synthetic.main.fragment_holder.* +import android.view.View +import androidx.appcompat.widget.Toolbar import me.anon.grow.fragment.FeedingScheduleDetailsFragment /** @@ -19,7 +20,7 @@ class FeedingScheduleDetailsActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.fragment_holder) - setSupportActionBar(toolbar) + setSupportActionBar(findViewById(R.id.toolbar) as Toolbar) setTitle(R.string.schedule_details_title) if (supportFragmentManager.findFragmentByTag(TAG_FRAGMENT) == null) diff --git a/app/src/main/java/me/anon/grow/PlantDetailsActivity.kt b/app/src/main/java/me/anon/grow/PlantDetailsActivity.kt index f5773599..19d02bae 100644 --- a/app/src/main/java/me/anon/grow/PlantDetailsActivity.kt +++ b/app/src/main/java/me/anon/grow/PlantDetailsActivity.kt @@ -4,11 +4,10 @@ import android.content.Intent import android.os.Bundle import android.view.MenuItem import android.view.View +import androidx.appcompat.widget.Toolbar import androidx.fragment.app.Fragment import com.google.android.material.appbar.AppBarLayout -import kotlinx.android.synthetic.main.fragment_holder.toolbar -import kotlinx.android.synthetic.main.fragment_holder.toolbar_layout -import kotlinx.android.synthetic.main.tabbed_fragment_holder.* +import com.google.android.material.bottomnavigation.BottomNavigationView import me.anon.grow.fragment.ActionsListFragment import me.anon.grow.fragment.PlantDetailsFragment import me.anon.grow.fragment.StatisticsFragment2 @@ -18,7 +17,7 @@ import me.anon.model.Plant class PlantDetailsActivity : BaseActivity() { - public val toolbarLayout: AppBarLayout by lazy { toolbar_layout } + public val toolbarLayout: AppBarLayout by lazy { findViewById(R.id.toolbar_layout) } private lateinit var plant: Plant override fun onCreate(savedInstanceState: Bundle?) @@ -28,9 +27,10 @@ class PlantDetailsActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.tabbed_fragment_holder) - setSupportActionBar(toolbar) + setSupportActionBar(findViewById(R.id.toolbar) as Toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_done_white_24dp) + val tabs = findViewById(R.id.tabs) supportFragmentManager.findFragmentByTag(TAG_FRAGMENT) ?: let { val fragment = when (intent.extras?.get("forward")) diff --git a/app/src/main/java/me/anon/grow/ScheduleDateDetailsActivity.kt b/app/src/main/java/me/anon/grow/ScheduleDateDetailsActivity.kt index 527d0801..386fa3a9 100644 --- a/app/src/main/java/me/anon/grow/ScheduleDateDetailsActivity.kt +++ b/app/src/main/java/me/anon/grow/ScheduleDateDetailsActivity.kt @@ -1,7 +1,8 @@ package me.anon.grow import android.os.Bundle -import kotlinx.android.synthetic.main.fragment_holder.* +import android.view.View +import androidx.appcompat.widget.Toolbar import me.anon.grow.fragment.ScheduleDateDetailsFragment /** @@ -19,7 +20,8 @@ class ScheduleDateDetailsActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.fragment_holder) - setSupportActionBar(toolbar) + + setSupportActionBar(findViewById(R.id.toolbar) as Toolbar) setTitle(R.string.schedule_date_title) if (supportFragmentManager.findFragmentByTag(TAG_FRAGMENT) == null) diff --git a/app/src/main/java/me/anon/grow/StatisticsActivity.kt b/app/src/main/java/me/anon/grow/StatisticsActivity.kt index 7b15550c..fc25c090 100644 --- a/app/src/main/java/me/anon/grow/StatisticsActivity.kt +++ b/app/src/main/java/me/anon/grow/StatisticsActivity.kt @@ -1,8 +1,8 @@ package me.anon.grow import android.os.Bundle -import kotlinx.android.synthetic.main.fragment_holder.* -import me.anon.grow.fragment.StatisticsFragment +import android.view.View +import androidx.appcompat.widget.Toolbar import me.anon.grow.fragment.StatisticsFragment2 import me.anon.lib.manager.PlantManager @@ -13,7 +13,7 @@ class StatisticsActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.fragment_holder) - setSupportActionBar(toolbar) + setSupportActionBar(findViewById(R.id.toolbar) as Toolbar) // if (intent.extras == null || !intent.hasExtra("plant")) // { diff --git a/app/src/main/java/me/anon/grow/ViewPhotosActivity.kt b/app/src/main/java/me/anon/grow/ViewPhotosActivity.kt index 351430eb..9a9d95ad 100644 --- a/app/src/main/java/me/anon/grow/ViewPhotosActivity.kt +++ b/app/src/main/java/me/anon/grow/ViewPhotosActivity.kt @@ -1,7 +1,8 @@ package me.anon.grow import android.os.Bundle -import kotlinx.android.synthetic.main.fragment_holder.* +import android.view.View +import androidx.appcompat.widget.Toolbar import me.anon.grow.fragment.ViewPhotosFragment class ViewPhotosActivity : BaseActivity() @@ -11,7 +12,8 @@ class ViewPhotosActivity : BaseActivity() super.onCreate(savedInstanceState) setContentView(R.layout.fragment_holder) - setSupportActionBar(toolbar) + + setSupportActionBar(findViewById(R.id.toolbar) as Toolbar) if (intent.extras == null || !intent.hasExtra("plant_index") && !intent.hasExtra("plant")) { diff --git a/app/src/main/java/me/anon/grow/fragment/ExportDialogFragment.kt b/app/src/main/java/me/anon/grow/fragment/ExportDialogFragment.kt index 0a3d272f..68063054 100644 --- a/app/src/main/java/me/anon/grow/fragment/ExportDialogFragment.kt +++ b/app/src/main/java/me/anon/grow/fragment/ExportDialogFragment.kt @@ -2,12 +2,11 @@ package me.anon.grow.fragment import android.app.Dialog import android.os.Bundle -import android.view.LayoutInflater import android.widget.ArrayAdapter import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment -import kotlinx.android.synthetic.main.export_dialog.view.* import me.anon.grow.R +import me.anon.grow.databinding.ExportDialogBinding import me.anon.lib.export.ExportProcessor import me.anon.lib.export.MarkdownProcessor @@ -15,16 +14,16 @@ class ExportDialogFragment(val callback: (processor: Class, { override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - val view = LayoutInflater.from(activity).inflate(R.layout.export_dialog, null) - val dialog = AlertDialog.Builder(context!!) + val binding = ExportDialogBinding.inflate(layoutInflater) + val dialog = AlertDialog.Builder(requireContext()) val options = arrayOf("Markdown")//, "HTML") val optionCls = arrayOf(MarkdownProcessor::class.java)//, HtmlProcessor::class.java) - view.formatters.adapter = ArrayAdapter(activity!!, android.R.layout.simple_list_item_1, options) + binding.formatters.adapter = ArrayAdapter(requireActivity(), android.R.layout.simple_list_item_1, options) dialog.setTitle(R.string.menu_export) dialog.setPositiveButton(R.string.menu_export) { dialog, which -> - callback(optionCls[view.formatters.selectedItemPosition], view.include_images.isChecked) + callback(optionCls[binding.formatters.selectedItemPosition], binding.includeImages.isChecked) } dialog.setView(view) diff --git a/app/src/main/java/me/anon/grow/fragment/FeedingScheduleDetailsFragment.kt b/app/src/main/java/me/anon/grow/fragment/FeedingScheduleDetailsFragment.kt index 4b7663ca..5dfa2727 100644 --- a/app/src/main/java/me/anon/grow/fragment/FeedingScheduleDetailsFragment.kt +++ b/app/src/main/java/me/anon/grow/fragment/FeedingScheduleDetailsFragment.kt @@ -11,13 +11,12 @@ import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import com.esotericsoftware.kryo.Kryo -import kotlinx.android.synthetic.main.feeding_date_stub.view.* -import kotlinx.android.synthetic.main.schedule_details_view.* import me.anon.grow.R import me.anon.grow.ScheduleDateDetailsActivity +import me.anon.grow.databinding.FeedingDateStubBinding +import me.anon.grow.databinding.ScheduleDetailsViewBinding import me.anon.lib.SnackBar import me.anon.lib.Unit -import me.anon.lib.ext.T import me.anon.lib.manager.ScheduleManager import me.anon.model.FeedingSchedule import me.anon.model.FeedingScheduleDate @@ -41,9 +40,13 @@ class FeedingScheduleDetailsFragment : Fragment() private var scheduleDates = arrayListOf() private val measureUnit: Unit by lazy { Unit.getSelectedMeasurementUnit(activity); } private val deliveryUnit: Unit by lazy { Unit.getSelectedDeliveryUnit(activity); } + private lateinit var binding: ScheduleDetailsViewBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? - = inflater.inflate(R.layout.schedule_details_view, container, false) ?: View(activity) + = ScheduleDetailsViewBinding.inflate(inflater, container, false).let { + binding = it + it.root + } override fun onActivityCreated(savedInstanceState: Bundle?) { @@ -55,17 +58,17 @@ class FeedingScheduleDetailsFragment : Fragment() scheduleDates = savedInstanceState.getParcelableArrayList("schedule_dates") as ArrayList } - title.setText(schedule?.name) - description.setText(schedule?.description) + binding.title.setText(schedule?.name) + binding.description.setText(schedule?.description) populateScheduleDates() - fab_complete.setOnClickListener { - title.error = null + binding.fabComplete.setOnClickListener { + binding.title.error = null - if (title.text.isEmpty()) + if (binding.title.text.isEmpty()) { - title.error = getString(R.string.field_required) + binding.title.error = getString(R.string.field_required) } else { @@ -73,15 +76,15 @@ class FeedingScheduleDetailsFragment : Fragment() { null -> { FeedingSchedule( - name = title.text.toString(), - description = description.text.toString(), + name = binding.title.text.toString(), + description = binding.description.text.toString(), _schedules = scheduleDates ) } else -> { schedule!!.apply { - name = this@FeedingScheduleDetailsFragment.title.text.toString() - description = this@FeedingScheduleDetailsFragment.description.text.toString() + name = binding.title.text.toString() + description = binding.description.text.toString() _schedules = this@FeedingScheduleDetailsFragment.scheduleDates } } @@ -121,10 +124,10 @@ class FeedingScheduleDetailsFragment : Fragment() */ private fun populateScheduleDates() { - schedule_dates_container.removeViews(0, schedule_dates_container.indexOfChild(new_schedule)) + binding.scheduleDatesContainer.removeViews(0, binding.scheduleDatesContainer.indexOfChild(binding.newSchedule)) scheduleDates.sortWith(compareBy { it.stageRange[0].ordinal }.thenBy { it.dateRange[0] }) scheduleDates.forEachIndexed { index, date -> - val feedingView = LayoutInflater.from(activity).inflate(R.layout.feeding_date_stub, schedule_dates_container, false) + val feedingView = FeedingDateStubBinding.inflate(LayoutInflater.from(activity), binding.scheduleDatesContainer, false) feedingView.title.text = "${date.dateRange[0]}${getString(date.stageRange[0].printString)[0]}" if (date.dateRange[0] != date.dateRange[1] || date.stageRange[0] != date.stageRange[1]) { @@ -168,27 +171,27 @@ class FeedingScheduleDetailsFragment : Fragment() scheduleDates.add(newSchedule) populateScheduleDates() - SnackBar().show(activity!!, R.string.schedule_copied, R.string.undo, action = { + SnackBar().show(requireActivity(), R.string.schedule_copied, R.string.undo, action = { scheduleDates.remove(newSchedule) populateScheduleDates() }) } - feedingView.setOnClickListener { + feedingView.root.setOnClickListener { startActivityForResult(Intent(it.context, ScheduleDateDetailsActivity::class.java).also { it.putExtra("schedule_date", date) }, 0) } - schedule_dates_container.addView(feedingView, schedule_dates_container.childCount - 1) + binding.scheduleDatesContainer.addView(feedingView.root, binding.scheduleDatesContainer.childCount - 1) } - new_schedule.setOnClickListener { + binding.newSchedule.setOnClickListener { if (schedule == null) { scheduleDates = arrayListOf() schedule = FeedingSchedule( - name = title.text.toString(), - description = description.text.toString(), + name = binding.title.text.toString(), + description = binding.description.text.toString(), _schedules = scheduleDates ) ScheduleManager.instance.insert(schedule!!) diff --git a/app/src/main/java/me/anon/grow/fragment/FeedingScheduleListFragment.kt b/app/src/main/java/me/anon/grow/fragment/FeedingScheduleListFragment.kt index 767f2f95..2602d35d 100644 --- a/app/src/main/java/me/anon/grow/fragment/FeedingScheduleListFragment.kt +++ b/app/src/main/java/me/anon/grow/fragment/FeedingScheduleListFragment.kt @@ -11,10 +11,10 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import com.esotericsoftware.kryo.Kryo -import kotlinx.android.synthetic.main.schedule_list_view.* import me.anon.controller.adapter.FeedingScheduleAdapter import me.anon.grow.FeedingScheduleDetailsActivity import me.anon.grow.R +import me.anon.grow.databinding.ScheduleListViewBinding import me.anon.lib.SnackBar import me.anon.lib.manager.ScheduleManager import java.util.* @@ -26,17 +26,22 @@ class FeedingScheduleListFragment : Fragment() { private val adapter = FeedingScheduleAdapter() + private lateinit var binding: ScheduleListViewBinding + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? - = inflater.inflate(R.layout.schedule_list_view, container, false) ?: View(activity) + = ScheduleListViewBinding.inflate(inflater, container, false).let { + binding = it + it.root + } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) adapter.items = ScheduleManager.instance.schedules - recycler_view.adapter = adapter - recycler_view.layoutManager = LinearLayoutManager(activity) - recycler_view.addItemDecoration(DividerItemDecoration(activity, VERTICAL)) + binding.recyclerView.adapter = adapter + binding.recyclerView.layoutManager = LinearLayoutManager(activity) + binding.recyclerView.addItemDecoration(DividerItemDecoration(activity, VERTICAL)) adapter.onDeleteCallback = { schedule -> val index = ScheduleManager.instance.schedules.indexOf(schedule) @@ -73,7 +78,7 @@ class FeedingScheduleListFragment : Fragment() }) } - fab_add.setOnClickListener { + binding.fabAdd.setOnClickListener { startActivity(Intent(activity, FeedingScheduleDetailsActivity::class.java)) } } @@ -91,13 +96,13 @@ class FeedingScheduleListFragment : Fragment() { if (adapter.itemCount == 0) { - empty.visibility = View.VISIBLE - recycler_view.visibility = View.GONE + binding.empty.visibility = View.VISIBLE + binding.recyclerView.visibility = View.GONE } else { - empty.visibility = View.GONE - recycler_view.visibility = View.VISIBLE + binding.empty.visibility = View.GONE + binding.recyclerView.visibility = View.VISIBLE } } } diff --git a/app/src/main/java/me/anon/grow/fragment/GardenHostFragment.kt b/app/src/main/java/me/anon/grow/fragment/GardenHostFragment.kt index e18d81df..c686e438 100644 --- a/app/src/main/java/me/anon/grow/fragment/GardenHostFragment.kt +++ b/app/src/main/java/me/anon/grow/fragment/GardenHostFragment.kt @@ -6,17 +6,20 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.tabbed_fragment_holder.* import me.anon.grow.R +import me.anon.grow.databinding.GardenFragmentHolderBinding import me.anon.model.Garden class GardenHostFragment : Fragment() { public lateinit var garden: Garden + private lateinit var binding: GardenFragmentHolderBinding + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? - { - return inflater.inflate(R.layout.garden_fragment_holder, container, false) + = GardenFragmentHolderBinding.inflate(inflater).let { + binding = it + it.root } override fun onActivityCreated(savedInstanceState: Bundle?) @@ -31,7 +34,7 @@ class GardenHostFragment : Fragment() childFragmentManager.beginTransaction().replace(R.id.fragment_holder, GardenFragment.newInstance(garden), "child_fragment").commit() } - tabs.setOnNavigationItemSelectedListener { + binding.tabs.setOnNavigationItemSelectedListener { childFragmentManager.beginTransaction() .setCustomAnimations(R.anim.fade_in, R.anim.fade_out) .replace(R.id.fragment_holder, when (it.itemId) diff --git a/app/src/main/java/me/anon/grow/fragment/GardenTrackerFragment.kt b/app/src/main/java/me/anon/grow/fragment/GardenTrackerFragment.kt index 8d7a6dfc..f5003cf3 100644 --- a/app/src/main/java/me/anon/grow/fragment/GardenTrackerFragment.kt +++ b/app/src/main/java/me/anon/grow/fragment/GardenTrackerFragment.kt @@ -18,11 +18,10 @@ import com.github.mikephil.charting.data.Entry import com.github.mikephil.charting.highlight.Highlight import com.github.mikephil.charting.listener.OnChartValueSelectedListener import com.github.mikephil.charting.utils.MPPointF -import kotlinx.android.synthetic.main.data_label_stub.view.* -import kotlinx.android.synthetic.main.garden_tracker_view.* import me.anon.controller.adapter.GardenActionAdapter import me.anon.grow.MainActivity import me.anon.grow.R +import me.anon.grow.databinding.GardenTrackerViewBinding import me.anon.lib.TempUnit import me.anon.lib.ext.formatWhole import me.anon.lib.ext.inflate @@ -66,9 +65,13 @@ class GardenTrackerFragment : Fragment() save() } + + private lateinit var binding: GardenTrackerViewBinding + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? - { - return inflater.inflate(R.layout.garden_tracker_view, container, false) + = GardenTrackerViewBinding.inflate(inflater).let { + binding = it + it.root } override fun onActivityCreated(savedInstanceState: Bundle?) @@ -126,36 +129,36 @@ class GardenTrackerFragment : Fragment() { var currentLighting = (transactions.lastOrNull { it is LightingChange } ?: garden.actions.lastOrNull { it is LightingChange }) as LightingChange? currentLighting?.let { - lighton_input.text = it.on - lightoff_input.text = it.off + binding.lightonInput.text = it.on + binding.lightoffInput.text = it.off if (it.off.isEmpty()) return@let val lightOnTime = LocalTime.parse(it.on, DateTimeFormatter.ofPattern("HH:mm")) val lightOffTime = LocalTime.parse(it.off, DateTimeFormatter.ofPattern("HH:mm")) var diff = (abs(Duration.between(lightOnTime, lightOffTime).toMinutes()) / 15.0) if (diff == 0.0) diff = 96.0 - light_ratio.progress = diff.toInt() + binding.lightRatio.progress = diff.toInt() - val on = ((light_ratio.progress.toDouble() * 15.0) / 60.0).round(2).formatWhole() - val off = ((1440.0 - (light_ratio.progress.toDouble() * 15.0)) / 60.0).round(2).formatWhole() - progresson_label.text = "$on" + getString(R.string.hour_abbr) - progressoff_label.text = "$off" + getString(R.string.hour_abbr) + val on = ((binding.lightRatio.progress.toDouble() * 15.0) / 60.0).round(2).formatWhole() + val off = ((1440.0 - (binding.lightRatio.progress.toDouble() * 15.0)) / 60.0).round(2).formatWhole() + binding.progressonLabel.text = "$on" + getString(R.string.hour_abbr) + binding.progressoffLabel.text = "$off" + getString(R.string.hour_abbr) } - lightson_container.setOnClickListener { + binding.lightsonContainer.setOnClickListener { val currentLighting = (transactions.lastOrNull { it is LightingChange } ?: Kryo().copy(garden.actions.lastOrNull { it is LightingChange })) as LightingChange? ?: LightingChange() val lightOnTime = LocalTime.parse(currentLighting.on, DateTimeFormatter.ofPattern("HH:mm")) val dialog = TimePickerDialog(activity, TimePickerDialog.OnTimeSetListener { view, hourOfDay, minute -> - light_ratio.isEnabled = true - val currentProgress = light_ratio.progress + binding.lightRatio.isEnabled = true + val currentProgress = binding.lightRatio.progress val timeOff = LocalTime.of(hourOfDay, minute).plusMinutes(currentProgress.toLong() * 15) - lighton_input.text = LocalTime.of(hourOfDay, minute).format(DateTimeFormatter.ofPattern("HH:mm")) - lightoff_input.text = timeOff.format(DateTimeFormatter.ofPattern("HH:mm")) + binding.lightonInput.text = LocalTime.of(hourOfDay, minute).format(DateTimeFormatter.ofPattern("HH:mm")) + binding.lightoffInput.text = timeOff.format(DateTimeFormatter.ofPattern("HH:mm")) - currentLighting.on = lighton_input.text.toString() - currentLighting.off = lightoff_input.text.toString() + currentLighting.on = binding.lightonInput.text.toString() + currentLighting.off = binding.lightoffInput.text.toString() currentLighting.date = System.currentTimeMillis() addTransaction(currentLighting) @@ -163,20 +166,20 @@ class GardenTrackerFragment : Fragment() dialog.show() } - lightsoff_container.setOnClickListener { + binding.lightsoffContainer.setOnClickListener { val currentLighting = (transactions.lastOrNull { it is LightingChange } ?: Kryo().copy(garden.actions.lastOrNull { it is LightingChange })) as LightingChange? ?: LightingChange() val lightOffTime = LocalTime.parse(currentLighting.off, DateTimeFormatter.ofPattern("HH:mm")) val dialog = TimePickerDialog(activity, TimePickerDialog.OnTimeSetListener { view, hourOfDay, minute -> - light_ratio.isEnabled = true - val currentProgress = light_ratio.progress + binding.lightRatio.isEnabled = true + val currentProgress = binding.lightRatio.progress val timeOn = LocalTime.of(hourOfDay, minute).minusMinutes(currentProgress.toLong() * 15) - lightoff_input.text = LocalTime.of(hourOfDay, minute).format(DateTimeFormatter.ofPattern("HH:mm")) - lighton_input.text = timeOn.format(DateTimeFormatter.ofPattern("HH:mm")) + binding.lightoffInput.text = LocalTime.of(hourOfDay, minute).format(DateTimeFormatter.ofPattern("HH:mm")) + binding.lightonInput.text = timeOn.format(DateTimeFormatter.ofPattern("HH:mm")) - currentLighting.on = lighton_input.text.toString() - currentLighting.off = lightoff_input.text.toString() + currentLighting.on = binding.lightonInput.text.toString() + currentLighting.off = binding.lightoffInput.text.toString() currentLighting.date = System.currentTimeMillis() addTransaction(currentLighting) @@ -184,20 +187,20 @@ class GardenTrackerFragment : Fragment() dialog.show() } - light_ratio.isEnabled = currentLighting != null - light_ratio.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener + binding.lightRatio.isEnabled = currentLighting != null + binding.lightRatio.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { override fun onProgressChanged(p0: SeekBar?, progress: Int, p2: Boolean) { val on = ((progress.toDouble() * 15.0) / 60.0).round(2).formatWhole() val off = ((1440.0 - (progress.toDouble() * 15.0)) / 60.0).round(2).formatWhole() - progresson_label.text = "$on" + getString(R.string.hour_abbr) - progressoff_label.text = "$off" + getString(R.string.hour_abbr) + binding.progressonLabel.text = "$on" + getString(R.string.hour_abbr) + binding.progressoffLabel.text = "$off" + getString(R.string.hour_abbr) - if (lighton_input.text.isNotEmpty()) + if (binding.lightonInput.text.isNotEmpty()) { - val timeOff = LocalTime.parse(lighton_input.text, DateTimeFormatter.ofPattern("HH:mm")).plusMinutes(progress.toLong() * 15) - lightoff_input.text = timeOff.format(DateTimeFormatter.ofPattern("HH:mm")) + val timeOff = LocalTime.parse(binding.lightonInput.text, DateTimeFormatter.ofPattern("HH:mm")).plusMinutes(progress.toLong() * 15) + binding.lightoffInput.text = timeOff.format(DateTimeFormatter.ofPattern("HH:mm")) } } @@ -206,30 +209,30 @@ class GardenTrackerFragment : Fragment() { val currentLighting = (transactions.lastOrNull { it is LightingChange } ?: garden.actions.lastOrNull { it is LightingChange }) as LightingChange? currentLighting?.let { - currentLighting.on = lighton_input.text.toString() - currentLighting.off = lightoff_input.text.toString() + currentLighting.on = binding.lightonInput.text.toString() + currentLighting.off = binding.lightoffInput.text.toString() } } }) - fake_toggle_actions.setOnClickListener { - actions_container.visibility = View.VISIBLE - details_container.visibility = View.GONE + binding.fakeToggleActions.setOnClickListener { + binding.actionsContainer.visibility = View.VISIBLE + binding.detailsContainer.visibility = View.GONE } - toggle_actions.setOnClickListener { - actions_container.visibility = View.GONE - details_container.visibility = View.VISIBLE + binding.toggleActions.setOnClickListener { + binding.actionsContainer.visibility = View.GONE + binding.detailsContainer.visibility = View.VISIBLE } - actions_recycler.adapter ?: let { - actions_recycler.adapter = GardenActionAdapter() - actions_recycler.layoutManager = LinearLayoutManager(activity!!) + binding.actionsRecycler.adapter ?: let { + binding.actionsRecycler.adapter = GardenActionAdapter() + binding.actionsRecycler.layoutManager = LinearLayoutManager(requireActivity()) } updateDataReferences() - (actions_recycler.adapter as GardenActionAdapter?)?.let { + (binding.actionsRecycler.adapter as GardenActionAdapter?)?.let { it.editListener = ::editAction it.deleteListener = ::deleteAction } @@ -285,7 +288,7 @@ class GardenTrackerFragment : Fragment() else -> -1 } - AlertDialog.Builder(activity!!) + AlertDialog.Builder(requireActivity()) .setTitle(R.string.delete_item_dialog_title) .setMessage(Html.fromHtml(getString(R.string.confirm_delete_item_message_holder, getString(title)))) .setPositiveButton(R.string.delete, DialogInterface.OnClickListener { dialogInterface, i -> @@ -298,19 +301,19 @@ class GardenTrackerFragment : Fragment() private fun setStatistics() { - val tempUnit = TempUnit.getSelectedTemperatureUnit(activity!!) + val tempUnit = TempUnit.getSelectedTemperatureUnit(requireActivity()) val tempAdditional = arrayOfNulls(3) (garden.actions.lastOrNull { it is TemperatureChange } as TemperatureChange?)?.let { - val view = data_container.findViewById(R.id.stats_temp) ?: data_container.inflate(R.layout.data_label_stub) - view.label.setText(R.string.current_temp) - view.data.text = "${TempUnit.CELCIUS.to(tempUnit, it.temp).formatWhole()}°${tempUnit.label}" + val view = binding.dataContainer.findViewById(R.id.stats_temp) ?: binding.dataContainer.inflate(R.layout.data_label_stub) + view.findViewById(R.id.label).setText(R.string.current_temp) + view.findViewById(R.id.data).text = "${TempUnit.CELCIUS.to(tempUnit, it.temp).formatWhole()}°${tempUnit.label}" view.id = R.id.stats_temp - if (data_container.findViewById(R.id.stats_temp) == null) data_container.addView(view) + if (binding.dataContainer.findViewById(R.id.stats_temp) == null) binding.dataContainer.addView(view) } - StatsHelper.setTempData(garden, activity!!, temp, tempAdditional) + StatsHelper.setTempData(garden, requireActivity(), binding.temp, tempAdditional) - temp.marker = object : MarkerView(context, R.layout.chart_marker) + binding.temp.marker = object : MarkerView(context, R.layout.chart_marker) { override fun refreshContent(e: Entry, highlight: Highlight) { @@ -326,23 +329,23 @@ class GardenTrackerFragment : Fragment() override fun getOffset(): MPPointF = MPPointF.getInstance(-(width / 2f), -(height * 1.2f)) } - temp.notifyDataSetChanged() - temp.postInvalidate() - min_temp.text = if (tempAdditional[0] == "100") "-" else "${tempAdditional[0]}°${tempUnit.label}" - max_temp.text = if (tempAdditional[1] == "-100") "-" else "${tempAdditional[1]}°${tempUnit.label}" - ave_temp.text = "${tempAdditional[2]}°${tempUnit.label}" + binding.temp.notifyDataSetChanged() + binding.temp.postInvalidate() + binding.minTemp.text = if (tempAdditional[0] == "100") "-" else "${tempAdditional[0]}°${tempUnit.label}" + binding.maxTemp.text = if (tempAdditional[1] == "-100") "-" else "${tempAdditional[1]}°${tempUnit.label}" + binding.aveTemp.text = "${tempAdditional[2]}°${tempUnit.label}" val humidityAdditional = arrayOfNulls(3) (garden.actions.lastOrNull { it is HumidityChange } as HumidityChange?)?.let { - val view = data_container.findViewById(R.id.stats_humidity) ?: data_container.inflate(R.layout.data_label_stub) - view.label.setText(R.string.current_humidity) - view.data.text = "${it.humidity?.formatWhole() ?: 0}%" + val view = binding.dataContainer.findViewById(R.id.stats_humidity) ?: binding.dataContainer.inflate(R.layout.data_label_stub) + view.findViewById(R.id.label).setText(R.string.current_humidity) + view.findViewById(R.id.data).text = "${it.humidity?.formatWhole() ?: 0}%" view.id = R.id.stats_humidity - if (data_container.findViewById(R.id.stats_humidity) == null) data_container.addView(view) + if (binding.dataContainer.findViewById(R.id.stats_humidity) == null) binding.dataContainer.addView(view) } - StatsHelper.setHumidityData(garden, activity!!, humidity, humidityAdditional) - humidity.marker = object : MarkerView(context, R.layout.chart_marker) + StatsHelper.setHumidityData(garden, requireActivity(), binding.humidity, humidityAdditional) + binding.humidity.marker = object : MarkerView(context, R.layout.chart_marker) { override fun refreshContent(e: Entry, highlight: Highlight) { @@ -357,32 +360,32 @@ class GardenTrackerFragment : Fragment() override fun getOffset(): MPPointF = MPPointF.getInstance(-(width / 2f), -(height * 1.2f)) } - humidity.notifyDataSetChanged() - humidity.postInvalidate() - min_humidity.text = if (humidityAdditional[0] == "100") "-" else "${humidityAdditional[0]}%" - max_humidity.text = if (humidityAdditional[1] == "-100") "-" else "${humidityAdditional[1]}%" - ave_humidity.text = "${humidityAdditional[2]}%" + binding.humidity.notifyDataSetChanged() + binding.humidity.postInvalidate() + binding.minHumidity.text = if (humidityAdditional[0] == "100") "-" else "${humidityAdditional[0]}%" + binding.maxHumidity.text = if (humidityAdditional[1] == "-100") "-" else "${humidityAdditional[1]}%" + binding.aveHumidity.text = "${humidityAdditional[2]}%" - humidity.setOnChartValueSelectedListener(object : OnChartValueSelectedListener + binding.humidity.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { override fun onNothingSelected() { - edit_humidity.visibility = View.GONE - delete_humidity.visibility = View.GONE + binding.editHumidity.visibility = View.GONE + binding.deleteHumidity.visibility = View.GONE } override fun onValueSelected(e: Entry?, h: Highlight?) { - edit_humidity.visibility = View.VISIBLE - delete_humidity.visibility = View.VISIBLE + binding.editHumidity.visibility = View.VISIBLE + binding.deleteHumidity.visibility = View.VISIBLE - edit_humidity.setOnClickListener { + binding.editHumidity.setOnClickListener { (e?.data as HumidityChange?)?.let { current -> editAction(current) } } - delete_humidity.setOnClickListener { + binding.deleteHumidity.setOnClickListener { (e?.data as Action?)?.let { deleteAction(it) } @@ -390,26 +393,26 @@ class GardenTrackerFragment : Fragment() } }) - temp.setOnChartValueSelectedListener(object : OnChartValueSelectedListener + binding.temp.setOnChartValueSelectedListener(object : OnChartValueSelectedListener { override fun onNothingSelected() { - edit_temp.visibility = View.GONE - delete_temp.visibility = View.GONE + binding.editTemp.visibility = View.GONE + binding.deleteTemp.visibility = View.GONE } override fun onValueSelected(e: Entry?, h: Highlight?) { - edit_temp.visibility = View.VISIBLE - delete_temp.visibility = View.VISIBLE + binding.editTemp.visibility = View.VISIBLE + binding.deleteTemp.visibility = View.VISIBLE - edit_temp.setOnClickListener { + binding.editTemp.setOnClickListener { (e?.data as TemperatureChange?)?.let { current -> editAction(current) } } - delete_temp.setOnClickListener { + binding.deleteTemp.setOnClickListener { (e?.data as Action?)?.let { current -> deleteAction(current) } @@ -417,24 +420,24 @@ class GardenTrackerFragment : Fragment() } }) - general_title.visibility = if (data_container.childCount > 0) View.VISIBLE else View.GONE - data_container.visibility = if (data_container.childCount > 0) View.VISIBLE else View.GONE + binding.generalTitle.visibility = if (binding.dataContainer.childCount > 0) View.VISIBLE else View.GONE + binding.dataContainer.visibility = if (binding.dataContainer.childCount > 0) View.VISIBLE else View.GONE } private fun updateDataReferences() { - (actions_recycler.adapter as GardenActionAdapter?)?.let { + (binding.actionsRecycler.adapter as GardenActionAdapter?)?.let { it.items = garden.actions if (it.items.size > 0) { - actions_recycler.visibility = View.VISIBLE - empty.visibility = View.GONE + binding.actionsRecycler.visibility = View.VISIBLE + binding.empty.visibility = View.GONE } else { - actions_recycler.visibility = View.GONE - empty.visibility = View.VISIBLE + binding.actionsRecycler.visibility = View.GONE + binding.empty.visibility = View.VISIBLE } } diff --git a/app/src/main/java/me/anon/grow/fragment/HumidityDialogFragment.kt b/app/src/main/java/me/anon/grow/fragment/HumidityDialogFragment.kt index eb8bf6c8..fa925e22 100644 --- a/app/src/main/java/me/anon/grow/fragment/HumidityDialogFragment.kt +++ b/app/src/main/java/me/anon/grow/fragment/HumidityDialogFragment.kt @@ -19,7 +19,7 @@ class HumidityDialogFragment(var action: HumidityChange? = null, val callback: ( override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { val view = LayoutInflater.from(activity).inflate(R.layout.humidity_dialog, null) - val dialog = AlertDialog.Builder(context!!) + val dialog = AlertDialog.Builder(requireContext()) dialog.setTitle(R.string.humidity) dialog.setPositiveButton(if (newAction) R.string.add else R.string.edit) { dialog, which -> if (view.findViewById(R.id.humidity_input).text.toString().isNotBlank()) diff --git a/app/src/main/java/me/anon/grow/fragment/ScheduleDateDetailsFragment.kt b/app/src/main/java/me/anon/grow/fragment/ScheduleDateDetailsFragment.kt index 13064949..ba7c2e71 100644 --- a/app/src/main/java/me/anon/grow/fragment/ScheduleDateDetailsFragment.kt +++ b/app/src/main/java/me/anon/grow/fragment/ScheduleDateDetailsFragment.kt @@ -13,8 +13,8 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.TextView import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.schedule_date_details_view.* import me.anon.grow.R +import me.anon.grow.databinding.ScheduleDateDetailsViewBinding import me.anon.lib.Unit import me.anon.lib.ext.toSafeInt import me.anon.model.Additive @@ -38,9 +38,13 @@ class ScheduleDateDetailsFragment : Fragment() private var additives: ArrayList = arrayListOf() private val selectedMeasurementUnit: Unit by lazy { Unit.getSelectedMeasurementUnit(activity); } private val selectedDeliveryUnit: Unit by lazy { Unit.getSelectedDeliveryUnit(activity); } + private lateinit var binding: ScheduleDateDetailsViewBinding override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? - = inflater.inflate(R.layout.schedule_date_details_view, container, false) ?: View(activity) + = ScheduleDateDetailsViewBinding.inflate(inflater, container, false).let { + binding = it + it.root + } override fun onActivityCreated(savedInstanceState: Bundle?) { @@ -51,76 +55,76 @@ class ScheduleDateDetailsFragment : Fragment() additives = (it?.get("additives") as ArrayList?) ?: date?.additives ?: arrayListOf() } - to_stage.adapter = ArrayAdapter(activity!!, android.R.layout.simple_list_item_1, PlantStage.values().map { getString(it.printString) }.toTypedArray()) - from_stage.adapter = ArrayAdapter(activity!!, android.R.layout.simple_list_item_1, PlantStage.values().map { getString(it.printString) }.toTypedArray()) + binding.toStage.adapter = ArrayAdapter(requireActivity(), android.R.layout.simple_list_item_1, PlantStage.values().map { getString(it.printString) }.toTypedArray()) + binding.fromStage.adapter = ArrayAdapter(requireActivity(), android.R.layout.simple_list_item_1, PlantStage.values().map { getString(it.printString) }.toTypedArray()) - from_stage.onItemSelectedListener = object: AdapterView.OnItemSelectedListener + binding.fromStage.onItemSelectedListener = object: AdapterView.OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?){} override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - from_stage.tag = PlantStage.values()[position] - if (to_stage.selectedItemPosition < position) + binding.fromStage.tag = PlantStage.values()[position] + if (binding.toStage.selectedItemPosition < position) { - to_stage.setSelection(position) + binding.toStage.setSelection(position) } } } - to_stage.onItemSelectedListener = object: AdapterView.OnItemSelectedListener + binding.toStage.onItemSelectedListener = object: AdapterView.OnItemSelectedListener { override fun onNothingSelected(parent: AdapterView<*>?){} override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { - to_stage.tag = PlantStage.values()[position] - if (from_stage.selectedItemPosition > position) + binding.toStage.tag = PlantStage.values()[position] + if (binding.fromStage.selectedItemPosition > position) { - from_stage.setSelection(position) + binding.fromStage.setSelection(position) } } } - from_date.addTextChangedListener(object: TextWatcher + binding.fromDate.addTextChangedListener(object: TextWatcher { override fun afterTextChanged(s: Editable?){} override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int){} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { - if (to_date.text.isEmpty()) to_date.setText(s) + if (binding.toDate.text.isEmpty()) binding.toDate.setText(s) } }) date?.let { - from_stage.setSelection(it.stageRange[0].ordinal) - from_stage.tag = it.stageRange[0] - to_stage.setSelection(it.stageRange[1].ordinal) - to_stage.tag = it.stageRange[1] - from_date.setText(it.dateRange[0].toString()) - to_date.setText(it.dateRange[1].toString()) + binding.fromStage.setSelection(it.stageRange[0].ordinal) + binding.fromStage.tag = it.stageRange[0] + binding.toStage.setSelection(it.stageRange[1].ordinal) + binding.toStage.tag = it.stageRange[1] + binding.fromDate.setText(it.dateRange[0].toString()) + binding.toDate.setText(it.dateRange[1].toString()) this@ScheduleDateDetailsFragment.additives = additives } populateAdditives() - fab_complete.setOnClickListener { - if (from_date.text.isEmpty()) + binding.fabComplete.setOnClickListener { + if (binding.fromDate.text.isEmpty()) { - from_date.error = "From date is required" + binding.fromDate.error = "From date is required" return@setOnClickListener } - val fromDate = from_date.text.toString().toSafeInt() - val toDate = if (to_date.text.isEmpty()) fromDate else to_date.text.toString().toSafeInt() - val fromStage = from_stage.tag as PlantStage? - val toStage = to_stage.tag as PlantStage? + val fromDate = binding.fromDate.text.toString().toSafeInt() + val toDate = if (binding.toDate.text.isEmpty()) fromDate else binding.toDate.text.toString().toSafeInt() + val fromStage = binding.fromStage.tag as PlantStage? + val toStage = binding.toStage.tag as PlantStage? if (toDate < fromDate && fromStage?.ordinal ?: -1 == toStage?.ordinal ?: -1) { - to_date.error = "Date can not be before from date" + binding.toDate.error = "Date can not be before from date" return@setOnClickListener } @@ -128,14 +132,14 @@ class ScheduleDateDetailsFragment : Fragment() { null -> { FeedingScheduleDate( - dateRange = arrayOf(fromDate, if (to_date.text.isEmpty()) fromDate else toDate), + dateRange = arrayOf(fromDate, if (binding.toDate.text.isEmpty()) fromDate else toDate), stageRange = arrayOf(fromStage!!, toStage!!), additives = additives ) } else -> { date!!.apply { - dateRange = arrayOf(fromDate, if (to_date.text.isEmpty()) fromDate else toDate) + dateRange = arrayOf(fromDate, if (binding.toDate.text.isEmpty()) fromDate else toDate) stageRange = arrayOf(fromStage!!, toStage!!) additives = this@ScheduleDateDetailsFragment.additives } @@ -165,15 +169,15 @@ class ScheduleDateDetailsFragment : Fragment() val converted = Unit.ML.to(selectedMeasurementUnit, additive.amount!!) val amountStr = if (converted == floor(converted)) converted.toInt().toString() else converted.toString() - val additiveStub = LayoutInflater.from(activity).inflate(R.layout.additive_stub, additive_container, false) + val additiveStub = LayoutInflater.from(activity).inflate(R.layout.additive_stub, binding.additiveContainer, false) (additiveStub as TextView).text = "${additive.description} - $amountStr${selectedMeasurementUnit.label}/${selectedDeliveryUnit.label}" additiveStub.setTag(additive) additiveStub.setOnClickListener { view -> onNewAdditiveClick(view) } - additive_container.addView(additiveStub, additive_container.childCount - 1) + binding.additiveContainer.addView(additiveStub, binding.additiveContainer.childCount - 1) } - new_additive.setOnClickListener { onNewAdditiveClick(it) } + binding.newAdditive.setOnClickListener { onNewAdditiveClick(it) } } private fun onNewAdditiveClick(view: View) @@ -194,7 +198,7 @@ class ScheduleDateDetailsFragment : Fragment() var converted = Unit.ML.to(selectedMeasurementUnit, additive.amount!!) var amountStr = if (converted == floor(converted)) converted.toInt().toString() else converted.toString() - val additiveStub = LayoutInflater.from(activity).inflate(R.layout.additive_stub, additive_container, false) + val additiveStub = LayoutInflater.from(activity).inflate(R.layout.additive_stub, binding.additiveContainer, false) (additiveStub as TextView).text = "${additive.description} - $amountStr${selectedMeasurementUnit.label}/${selectedDeliveryUnit.label}" if (currentTag == null) @@ -205,14 +209,14 @@ class ScheduleDateDetailsFragment : Fragment() additiveStub.setTag(additive) additiveStub.setOnClickListener { view -> onNewAdditiveClick(view) } - additive_container.addView(additiveStub, additive_container.childCount - 1) + binding.additiveContainer.addView(additiveStub, binding.additiveContainer.childCount - 1) } } else { - for (childIndex in 0 until additive_container.childCount) + for (childIndex in 0 until binding.additiveContainer.childCount) { - val tag = additive_container.getChildAt(childIndex).tag + val tag = binding.additiveContainer.getChildAt(childIndex).tag if (tag === currentTag) { @@ -221,8 +225,8 @@ class ScheduleDateDetailsFragment : Fragment() additives[childIndex] = additive - (additive_container.getChildAt(childIndex) as TextView).text = "${additive.description} - $amountStr${selectedMeasurementUnit.label}/${selectedDeliveryUnit.label}" - additive_container.getChildAt(childIndex).tag = additive + (binding.additiveContainer.getChildAt(childIndex) as TextView).text = "${additive.description} - $amountStr${selectedMeasurementUnit.label}/${selectedDeliveryUnit.label}" + binding.additiveContainer.getChildAt(childIndex).tag = additive break } @@ -242,13 +246,13 @@ class ScheduleDateDetailsFragment : Fragment() additives.remove(additive) } - for (childIndex in 0 until additive_container.childCount) + for (childIndex in 0 until binding.additiveContainer.childCount) { - val tag = additive_container.getChildAt(childIndex).tag + val tag = binding.additiveContainer.getChildAt(childIndex).tag if (tag === additive) { - additive_container.removeViewAt(childIndex) + binding.additiveContainer.removeViewAt(childIndex) break } } diff --git a/app/src/main/java/me/anon/grow/fragment/StatisticsFragment2.kt b/app/src/main/java/me/anon/grow/fragment/StatisticsFragment2.kt index bfe98e19..77b3c34f 100644 --- a/app/src/main/java/me/anon/grow/fragment/StatisticsFragment2.kt +++ b/app/src/main/java/me/anon/grow/fragment/StatisticsFragment2.kt @@ -20,9 +20,8 @@ import com.github.mikephil.charting.interfaces.datasets.IBarDataSet import com.github.mikephil.charting.interfaces.datasets.ILineDataSet import com.github.mikephil.charting.utils.MPPointF import com.google.android.material.chip.Chip -import kotlinx.android.synthetic.main.data_label_stub.view.* -import kotlinx.android.synthetic.main.statistics2_view.* import me.anon.grow.R +import me.anon.grow.databinding.Statistics2ViewBinding import me.anon.grow.fragment.StatisticsFragment2.template.data import me.anon.grow.fragment.StatisticsFragment2.template.header import me.anon.lib.TdsUnit @@ -318,8 +317,13 @@ class StatisticsFragment2 : Fragment() } } + private lateinit var binding: Statistics2ViewBinding + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? - = inflater.inflate(R.layout.statistics2_view, container, false) + = Statistics2ViewBinding.inflate(inflater, container, false).let { + binding = it + it.root + } override fun onActivityCreated(savedInstanceState: Bundle?) { @@ -356,7 +360,7 @@ class StatisticsFragment2 : Fragment() { val statTemplates = arrayListOf