The FoodDetailsFragment
is a core component designed to display detailed information about a selected food item, including its name, icon, calories, macronutrients, and a list of micronutrients. Users can adjust serving sizes and quantities to view nutrient values accordingly.
The primary components in FoodDetailsFragment
include:
Food Item Information : Displays the name, icon, and serving size details.
Serving Size Selector : Allows users to select a preferred serving size or unit.
Nutritional Information : Shows calorie count and macronutrient breakdown (Carbs, Protein, Fat).
Micronutrient List : Provides detailed nutrient information for vitamins, minerals, and other nutrients.
PassioFoodItem
The PassioFoodItem
model is the foundation of food details and includes the following properties:
Unique identifier for the food item.
Reference code for the item.
Description/details of the food.
ID for loading the food icon.
Serving size and unit info.
List of ingredients in the food.
Example:
The food item name, icon, and details are rendered using PassioFoodItem
's properties.
Copy kotlinCopy codebinding.tvFoodName.text = foodItem.name
binding.foodIcon.loadPassioIcon(foodItem.iconId)
PassioFoodAmount
This model defines possible serving sizes and units. PassioFoodAmount
includes:
Available serving sizes for the food
Units available for the food item
Example:
The servingSizes
property is used to populate the RecyclerView adapter ServingSizeAdapter
, allowing users to select different serving sizes.
PassioServingSize
and PassioServingUnit
These classes are components of PassioFoodAmount
that define the quantity and units for serving sizes:
PassioServingSize
PassioServingUnit
Linked to the PassioServingSize
Weight in grams or other units
Setting Serving Size Quantity
The setQuantityAndUnit
function allows users to specify a desired serving quantity and unit, updating the displayed nutrient values dynamically.
Copy foodItem.setQuantityAndUnit(quantity, foodItem.amount.selectedUnit)
FoodDetailsFragment.kt
Copy package com.passioai.quickstart.ui.details
import ai.passio.passiosdk.passiofood.data.model.PassioFoodItem
import ai.passio.passiosdk.passiofood.data.model.PassioServingSize
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.KeyEvent
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import com.passioai.quickstart.databinding.FragmentFoodDetailsBinding
import com.passioai.quickstart.ui.details.MicroNutrient.Companion.getMicroNutrients
import com.passioai.quickstart.util.loadPassioIcon
import com.passioai.quickstart.util.twoDecimal
class FoodDetailsFragment : Fragment() {
private lateinit var _binding: FragmentFoodDetailsBinding
private val binding get() = _binding
private val foodItem = passioFoodItem?.copy()
companion object {
private var passioFoodItem: PassioFoodItem? = null
fun setPassioFoodItem(passioFoodItem: PassioFoodItem) {
this.passioFoodItem = passioFoodItem
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentFoodDetailsBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (foodItem == null)
return
with(binding)
{
servingQty.setOnEditorActionListener { _, actionId, event ->
// Check if the action is "done" or if the action is triggered by the keyboard
if (actionId == EditorInfo.IME_ACTION_DONE ||
(event != null && event.keyCode == KeyEvent.KEYCODE_ENTER && event.action == KeyEvent.ACTION_DOWN)
) {
// Handle the done action here
try {
val quantity = servingQty.text.toString().toDouble()
foodItem.setQuantityAndUnit(
quantity,
foodItem.amount.selectedUnit
)
showFoodDetails()
} catch (e: Exception) {
e.printStackTrace()
}
// You can do something with inputText, like showing a Toast
// Optionally clear the text
true // Return true to indicate the action was handled
} else {
false // Return false to indicate the action was not handled
}
}
rvServingSizes.adapter =
ServingSizeAdapter(
foodItem.amount.servingSizes,
foodItem.amount.selectedUnit,
::onServingSizeSelected
)
}
showFoodDetails()
}
private fun onServingSizeSelected(passioServingSize: PassioServingSize) {
foodItem?.setQuantityAndUnit(passioServingSize.quantity, passioServingSize.unitName)
showFoodDetails()
}
@SuppressLint("SetTextI18n")
private fun showFoodDetails() {
if (foodItem == null) return
val passioNutrients = foodItem.nutrientsSelectedSize()
with(binding)
{
tvFoodName.text = foodItem.name
servingSizeValue.text = "(${foodItem.amount.weightGrams()} g)"
servingQty.setText(foodItem.amount.selectedQuantity.toString())
foodIcon.loadPassioIcon(foodItem.iconId)
tvCaloriesVal.text =
"${passioNutrients.calories()?.value?.twoDecimal()} ${passioNutrients.calories()?.unit?.symbol}"
tvCarbsVal.text = "${passioNutrients.carbs()?.gramsValue()?.twoDecimal()} g"
tvProteinVal.text = "${passioNutrients.protein()?.gramsValue()?.twoDecimal()} g"
tvFatVal.text = "${passioNutrients.fat()?.gramsValue()?.twoDecimal()} g"
rvNutrients.adapter = NutrientsAdapter(passioNutrients.getMicroNutrients())
}
}
}
Check out the full code here. FULL CODE
Last updated 3 months ago