Food Details
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:
id
String
Unique identifier for the food item.
refCode
String
Reference code for the item.
name
String
Name of the food item.
details
String
Description/details of the food.
iconId
String
ID for loading the food icon.
amount
PassioFoodAmount
Serving size and unit info.
ingredients
List<PassioIngredient>
List of ingredients in the food.
Example:
The food item name, icon, and details are rendered using PassioFoodItem
's properties.
kotlinCopy codebinding.tvFoodName.text = foodItem.name
binding.foodIcon.loadPassioIcon(foodItem.iconId)
PassioFoodAmount
PassioFoodAmount
This model defines possible serving sizes and units. PassioFoodAmount
includes:
servingSizes
List<PassioServingSize>
Available serving sizes for the food
servingUnits
List<PassioServingUnit>
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
PassioServingSize
and PassioServingUnit
These classes are components of PassioFoodAmount
that define the quantity and units for serving sizes:
PassioServingSize
quantity
Double
Quantity of the unit
unitName
String
Name of the serving unit
PassioServingUnit
unitName
String
Linked to the PassioServingSize
weight
UnitMass
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.
foodItem.setQuantityAndUnit(quantity, foodItem.amount.selectedUnit)
FoodDetailsFragment.kt
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