Refactoring to delete some layout-xml.

This commit is contained in:
sockenklaus
2022-07-20 15:07:25 +02:00
parent 50d952effc
commit 2e72b63f05
8 changed files with 174 additions and 226 deletions

View File

@@ -13,13 +13,14 @@ import androidx.compose.material.icons.filled.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.sockenklaus.batterytracker.R import com.sockenklaus.batterytracker.R
import com.sockenklaus.batterytracker.databinding.FragmentAddBatteryBinding
import com.sockenklaus.batterytracker.room.entities.Battery import com.sockenklaus.batterytracker.room.entities.Battery
import com.sockenklaus.batterytracker.ui.composables.MyOutlinedTextFieldWithSuffix import com.sockenklaus.batterytracker.ui.composables.MyOutlinedTextFieldWithSuffix
import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme
@@ -31,17 +32,13 @@ import com.sockenklaus.batterytracker.util.validateDecimal
* create an instance of this fragment. * create an instance of this fragment.
*/ */
class AddBatteryFragment : Fragment() { class AddBatteryFragment : Fragment() {
private var _binding: FragmentAddBatteryBinding? = null
private val binding get() = _binding!!
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentAddBatteryBinding.inflate(inflater, container, false)
val model = ViewModelProvider(this)[AddBatteryViewModel::class.java] val model = ViewModelProvider(this)[AddBatteryViewModel::class.java]
val view = binding.root
var batteries = emptyList<Battery>() var batteries = emptyList<Battery>()
@@ -49,66 +46,66 @@ class AddBatteryFragment : Fragment() {
batteries = it batteries = it
} }
binding.root.setContent { return ComposeView(requireContext()).apply {
BatteryTrackerTheme { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
val outerPadding = 24.dp setContent {
val innerPadding = 16.dp BatteryTrackerTheme() {
val outerPadding = 24.dp
val innerPadding = 16.dp
Column( Column(
Modifier.padding(outerPadding) Modifier.padding(outerPadding)
) { ) {
MyOutlinedTextFieldWithSuffix( MyOutlinedTextFieldWithSuffix(
value = model.batteryName, value = model.batteryName,
onValueChange = { value -> onValueChange = { value ->
model.batteryName = value model.batteryName = value
model.batteryHasError = false model.batteryHasError = false
model.batteryHelperId = R.string.helper_required model.batteryHelperId = R.string.helper_required
if(batteries.any{ it.name.equals(value, ignoreCase = true) }){ if(batteries.any{ it.name.equals(value, ignoreCase = true) }){
model.batteryHasError = true model.batteryHasError = true
model.batteryHelperId = R.string.helper_battery_not_unique model.batteryHelperId = R.string.helper_battery_not_unique
} }
}, },
labelId = R.string.hint_enter_battery_name, labelId = R.string.hint_enter_battery_name,
leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") }, leadingIcon = { Icon(Icons.Default.Tag, "Icon Tag") },
isError = model.batteryHasError, isError = model.batteryHasError,
helperTextId = model.batteryHelperId helperTextId = model.batteryHelperId
) )
Spacer(Modifier.size(innerPadding)) Spacer(Modifier.size(innerPadding))
MyOutlinedTextFieldWithSuffix( MyOutlinedTextFieldWithSuffix(
value = model.declaredCapacity, value = model.declaredCapacity,
onValueChange = { onValueChange = {
model.declaredCapacity = validateDecimal(it, model.declaredCapacity) model.declaredCapacity = validateDecimal(it, model.declaredCapacity)
}, },
labelId = R.string.hint_enter_declared_capacity, labelId = R.string.hint_enter_declared_capacity,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
leadingIcon = { Icon(Icons.Default.BatteryFull, "Icon Battery Full") }, leadingIcon = { Icon(Icons.Default.BatteryFull, "Icon Battery Full") },
suffix = "Ah" suffix = "Ah"
) )
Spacer(Modifier.size(outerPadding)) Spacer(Modifier.size(outerPadding))
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
onClick = { onClick = {
if(model.batteryName.isBlank()) model.batteryHasError = true if(model.batteryName.isBlank()) model.batteryHasError = true
if(!model.batteryHasError && model.saveBattery(model.batteryName, model.declaredCapacity)){ if(!model.batteryHasError && model.saveBattery(model.batteryName, model.declaredCapacity)){
findNavController().navigate(R.id.action_nav_add_battery_to_nav_home) findNavController().navigate(R.id.action_nav_add_battery_to_nav_home)
} }
}, },
icon = { Icon(Icons.Default.Save, "Icon Save") }, icon = { Icon(Icons.Default.Save, "Icon Save") },
text = { Text(stringResource(R.string.button_save_battery)) }, text = { Text(stringResource(R.string.button_save_battery)) },
modifier = Modifier.align(Alignment.End) modifier = Modifier.align(Alignment.End)
) )
}
} }
} }
} }
// Inflate the layout for this fragment
return view
} }
/*companion object { /*companion object {

View File

@@ -17,6 +17,8 @@ import androidx.compose.material.icons.filled.Tag
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.TextRange
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
@@ -25,7 +27,6 @@ import androidx.compose.ui.unit.dp
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.datepicker.MaterialDatePicker
import com.sockenklaus.batterytracker.R import com.sockenklaus.batterytracker.R
import com.sockenklaus.batterytracker.databinding.FragmentAddChargeBinding
import com.sockenklaus.batterytracker.room.entities.Battery import com.sockenklaus.batterytracker.room.entities.Battery
import com.sockenklaus.batterytracker.ui.composables.MyOutlinedTextFieldWithSuffix import com.sockenklaus.batterytracker.ui.composables.MyOutlinedTextFieldWithSuffix
import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme
@@ -38,9 +39,7 @@ import java.util.*
class AddChargeFragment : Fragment() { class AddChargeFragment : Fragment() {
private var _binding: FragmentAddChargeBinding? = null
private lateinit var model: AddChargeViewModel private lateinit var model: AddChargeViewModel
private val binding get() = _binding!!
@OptIn(ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterialApi::class)
override fun onCreateView( override fun onCreateView(
@@ -49,7 +48,6 @@ class AddChargeFragment : Fragment() {
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = FragmentAddChargeBinding.inflate(inflater, container, false)
model = ViewModelProvider(this)[AddChargeViewModel::class.java] model = ViewModelProvider(this)[AddChargeViewModel::class.java]
var batteries = emptyList<Battery>() var batteries = emptyList<Battery>()
@@ -57,121 +55,123 @@ class AddChargeFragment : Fragment() {
batteries = it batteries = it
} }
binding.root.setContent{ return ComposeView(requireContext()).apply{
BatteryTrackerTheme { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
val outerPadding = 24.dp
val innerPadding = 16.dp
var bIdExpanded by remember { mutableStateOf(false)} setContent {
BatteryTrackerTheme() {
val outerPadding = 24.dp
val innerPadding = 16.dp
Column( var bIdExpanded by remember { mutableStateOf(false)}
Modifier.padding(outerPadding)
) { Column(
ExposedDropdownMenuBox( Modifier.padding(outerPadding)
expanded = bIdExpanded,
onExpandedChange = { bIdExpanded = !bIdExpanded}
) { ) {
ExposedDropdownMenuBox(
expanded = bIdExpanded,
onExpandedChange = { bIdExpanded = !bIdExpanded}
) {
val filteringOptions = batteries.filter { it.name.contains(model.batteryId.text, ignoreCase = true)} val filteringOptions = batteries.filter { it.name.contains(model.batteryId.text, ignoreCase = true)}
OutlinedTextField( OutlinedTextField(
value = model.batteryId, value = model.batteryId,
onValueChange = { onValueChange = {
model.batteryId = it model.batteryId = it
model.batteryHasError = false model.batteryHasError = false
model.batteryHelper = R.string.helper_required model.batteryHelper = R.string.helper_required
bIdExpanded = filteringOptions.size > 1 bIdExpanded = filteringOptions.size > 1
}, },
label = { Text(stringResource(R.string.select_battery_id)) }, label = { Text(stringResource(R.string.select_battery_id)) },
leadingIcon = { Icon(Icons.Default.Tag, null) }, leadingIcon = { Icon(Icons.Default.Tag, null) },
trailingIcon = { trailingIcon = {
ExposedDropdownMenuDefaults.TrailingIcon(expanded = bIdExpanded) ExposedDropdownMenuDefaults.TrailingIcon(expanded = bIdExpanded)
}, },
colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(), colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
isError = model.batteryHasError isError = model.batteryHasError
) )
if(filteringOptions.isNotEmpty()) { if(filteringOptions.isNotEmpty()) {
ExposedDropdownMenu( ExposedDropdownMenu(
expanded = bIdExpanded, expanded = bIdExpanded,
onDismissRequest = { bIdExpanded = false } onDismissRequest = { bIdExpanded = false }
) { ) {
for (filteringOption in filteringOptions) { for (filteringOption in filteringOptions) {
DropdownMenuItem( DropdownMenuItem(
onClick = { onClick = {
model.batteryId = TextFieldValue( model.batteryId = TextFieldValue(
text = filteringOption.name, text = filteringOption.name,
selection = TextRange(filteringOption.name.length) selection = TextRange(filteringOption.name.length)
) )
bIdExpanded = false bIdExpanded = false
}
) {
Text(filteringOption.name)
} }
) {
Text(filteringOption.name)
} }
} }
} }
} }
Text(
text = stringResource(model.batteryHelper),
style = MaterialTheme.typography.caption,
color = if(model.batteryHasError) MaterialTheme.colors.error else Gray500,
modifier = Modifier.padding(start = 16.dp)
)
Spacer(Modifier.size(innerPadding))
MyOutlinedTextFieldWithSuffix(
value = model.charge,
onValueChange = {
model.charge = validateDecimal(it, model.charge)
model.chargeHasError = false
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
labelId = R.string.hint_charge,
leadingIcon = { Icon(Icons.Default.BatteryChargingFull, "Icon Battery Charging Full") },
isError = model.chargeHasError,
helperTextId = R.string.helper_required,
suffix = "Ah"
)
Spacer(Modifier.size(innerPadding))
ChargeDatePicker(
date = model.date,
onSelect = { model.date = it}
)
Spacer(Modifier.size(outerPadding))
ExtendedFloatingActionButton(
text = { Text(stringResource(R.string.button_save_charge)) },
onClick = {
if(!batteries.any{ it.name == model.batteryId.text }){
model.batteryHasError = true
model.batteryHelper = R.string.helper_battery_not_found
}
if(model.batteryId.text.isBlank()){
model.batteryHasError = true
model.batteryHelper = R.string.helper_required
}
if(model.charge.isBlank()){
model.chargeHasError = true
}
if(!model.batteryHasError && !model.chargeHasError && model.saveCharge(batteries, model.batteryId.text, model.charge, model.date)){
findNavController().navigate(R.id.action_nav_add_charge_to_nav_home)
}
},
icon = { Icon(Icons.Default.Save, "Icon Save") },
modifier = Modifier.align(Alignment.End)
)
} }
Text(
text = stringResource(model.batteryHelper),
style = MaterialTheme.typography.caption,
color = if(model.batteryHasError) MaterialTheme.colors.error else Gray500,
modifier = Modifier.padding(start = 16.dp)
)
Spacer(Modifier.size(innerPadding))
MyOutlinedTextFieldWithSuffix(
value = model.charge,
onValueChange = {
model.charge = validateDecimal(it, model.charge)
model.chargeHasError = false
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
labelId = R.string.hint_charge,
leadingIcon = { Icon(Icons.Default.BatteryChargingFull, "Icon Battery Charging Full") },
isError = model.chargeHasError,
helperTextId = R.string.helper_required,
suffix = "Ah"
)
Spacer(Modifier.size(innerPadding))
ChargeDatePicker(
date = model.date,
onSelect = { model.date = it}
)
Spacer(Modifier.size(outerPadding))
ExtendedFloatingActionButton(
text = { Text(stringResource(R.string.button_save_charge)) },
onClick = {
if(!batteries.any{ it.name == model.batteryId.text }){
model.batteryHasError = true
model.batteryHelper = R.string.helper_battery_not_found
}
if(model.batteryId.text.isBlank()){
model.batteryHasError = true
model.batteryHelper = R.string.helper_required
}
if(model.charge.isBlank()){
model.chargeHasError = true
}
if(!model.batteryHasError && !model.chargeHasError && model.saveCharge(batteries, model.batteryId.text, model.charge, model.date)){
findNavController().navigate(R.id.action_nav_add_charge_to_nav_home)
}
},
icon = { Icon(Icons.Default.Save, "Icon Save") },
modifier = Modifier.align(Alignment.End)
)
} }
} }
} }
return binding.root
} }
@Composable @Composable
@@ -208,6 +208,5 @@ class AddChargeFragment : Fragment() {
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null
} }
} }

View File

@@ -5,38 +5,34 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.TextView import android.widget.TextView
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import com.sockenklaus.batterytracker.databinding.FragmentHomeBinding import com.sockenklaus.batterytracker.ui.theme.BatteryTrackerTheme
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
private var _binding: FragmentHomeBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
val homeViewModel =
ViewModelProvider(this).get(HomeViewModel::class.java)
_binding = FragmentHomeBinding.inflate(inflater, container, false) val model = ViewModelProvider(this)[HomeViewModel::class.java]
val root: View = binding.root
val textView: TextView = binding.textHome return ComposeView(requireContext()).apply {
homeViewModel.text.observe(viewLifecycleOwner) { setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
textView.text = it
setContent {
BatteryTrackerTheme() {
}
}
} }
return root
} }
override fun onDestroyView() { override fun onDestroyView() {
super.onDestroyView() super.onDestroyView()
_binding = null
} }
} }

View File

@@ -1,10 +1,12 @@
package com.sockenklaus.batterytracker.ui.fragments.home package com.sockenklaus.batterytracker.ui.fragments.home
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
class HomeViewModel : ViewModel() { class HomeViewModel(application: Application) : AndroidViewModel(application) {
private val _text = MutableLiveData<String>().apply { private val _text = MutableLiveData<String>().apply {
value = "This is home Fragment" value = "This is home Fragment"

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.compose.ui.platform.ComposeView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.fragments.add_battery.AddBatteryFragment"
/>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.compose.ui.platform.ComposeView
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=".ui.fragments.add_charge.AddChargeFragment"
android:id="@+id/compose_view"
app:layout_constraintTop_toTopOf="parent"
/>

View File

@@ -1,22 +0,0 @@
<?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=".ui.fragments.home.HomeFragment">
<TextView
android:id="@+id/text_home"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -8,14 +8,12 @@
<fragment <fragment
android:id="@+id/nav_home" android:id="@+id/nav_home"
android:name="com.sockenklaus.batterytracker.ui.fragments.home.HomeFragment" android:name="com.sockenklaus.batterytracker.ui.fragments.home.HomeFragment"
android:label="@string/menu_home" android:label="@string/menu_home" />
tools:layout="@layout/fragment_home" />
<fragment <fragment
android:id="@+id/nav_add_charge" android:id="@+id/nav_add_charge"
android:name="com.sockenklaus.batterytracker.ui.fragments.add_charge.AddChargeFragment" android:name="com.sockenklaus.batterytracker.ui.fragments.add_charge.AddChargeFragment"
android:label="@string/menu_add_charge" android:label="@string/menu_add_charge">
tools:layout="@layout/fragment_add_charge" >
<action <action
android:id="@+id/action_nav_add_charge_to_nav_home" android:id="@+id/action_nav_add_charge_to_nav_home"
app:destination="@id/nav_home" /> app:destination="@id/nav_home" />
@@ -24,8 +22,7 @@
<fragment <fragment
android:id="@+id/nav_add_battery" android:id="@+id/nav_add_battery"
android:name="com.sockenklaus.batterytracker.ui.fragments.add_battery.AddBatteryFragment" android:name="com.sockenklaus.batterytracker.ui.fragments.add_battery.AddBatteryFragment"
android:label="@string/menu_add_battery" android:label="@string/menu_add_battery" >
tools:layout="@layout/fragment_add_battery" >
<action <action
android:id="@+id/action_nav_add_battery_to_nav_home" android:id="@+id/action_nav_add_battery_to_nav_home"
app:destination="@id/nav_home" /> app:destination="@id/nav_home" />