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:

  1. Food Item Information: Displays the name, icon, and serving size details.

  2. Serving Size Selector: Allows users to select a preferred serving size or unit.

  3. Nutritional Information: Shows calorie count and macronutrient breakdown (Carbs, Protein, Fat).

  4. 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:

Property
Type
Description

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

This model defines possible serving sizes and units. PassioFoodAmount includes:

Property
Type
Description

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

These classes are components of PassioFoodAmount that define the quantity and units for serving sizes:

PassioServingSize

Property
Type
Description

quantity

Double

Quantity of the unit

unitName

String

Name of the serving unit

PassioServingUnit

Property
Type
Description

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