Touchless Chef
50.001 1D Project
A POC Recipe Android Application using Google Mediapipe Hands Tracking model for smart touchless scrolling.
Deliverables:
A. Acknowledgement:
Tran Nguyen Bao Long
@TNBL
: Project Lead
- define software architecture
- documentation
Li Xueqing
@cnmnrll
: Project Design
- set basic
Recipe
,Ingredients
andInstructions
modelsmodel
- documentation
- set basic
Melodie Chew En Qi
@melmelchew
: Marketing + Frontend
RecyclerView
andNavigationView
adapter
forRecyclerView
Melvin Lim Boon Han
@melvinlimbh
: Marketing + Frontend
- Fragments for different cuisines
home
- Fragments for creating recipes RecipeCreate
- all resources and layouts
res
- Fragments for different cuisines
Han Jin
@dlmszhhh
: Backend Acitivity
- basic recipe activities
acitivity
- basic recipe activities
Wang Zhouran
@wzrwzr23
: Backend Database
Liang Junyi
@LiangJunyi-010
Backend HandTracking
- implement HandTracking using Google Mediapipe Hands model for touchless scrolling in
ViewRecipeActivity
- implement HandTracking using Google Mediapipe Hands model for touchless scrolling in
B. Description
Overview of Design Pattern used:
- Adapter Design Pattern (for SQLite database and RecyclerView)
- Singleton Design Pattern (for SQLite database)
- Observer Design Pattern (for
CreateRecipeActivity
)- Factory Design Pattern (for Cuisine Fragment)
- Template Method Design Pattern (for Create Recipe Fragment)
0. Model
- Utilize
Parcelable
interface:- speed up data transfer using Java Serializable
- easily pass data as
Bundle
object through Activity
- Recipe :
id
: primary key for SQLitename
: name of recipedescription
: short description of recipecategory
: category/cuisine (Vietnamese/Chinese)mealType
: type of meals (Breakfast, Dinner,…)time
: estimated to prepare the dishimagePath
: local URI path to Recipe imageingredients
: list of ingredientsinstructions
: list of instructions
- Instruction :
id
: primary key for SQLiterecipeID
: foreign keycontent
: instruction body
- Ingredient :
1. Database
- We use local database SQLite and utilize abstract class
SQLiteOpenHelper
to create and manage our database inSQLiteDbCRUD
- Adapter in
DatabaseAdapter
- using Adapter Design Pattern as main API for Recipe CRUD operations
- using Singleton Design Pattern to create a single instance of our database to be shared within all activities
- Data Access Objects (DAO):
2. Activity
- Both
MainActivity
andViewRecipeActivity
inherits aToolbar
(explain in section B5a) from abstract classMenuActivity
MainActivity
- implements interface
BaseFragment.FragmentListener
that define blueprint for methods to:- display recipe:
onShowRecipe
which navigates toViewRecipeActivity
(an Explicit Intent) - delete recipe:
onDeleteRecipe
- display recipe:
- consists of 3 main views:
- implements interface
ViewRecipeActivity
:- display chosen recipe from the data passed as parcel from
MainActivity
- where HandsTracking feature (explain in section B3) is located
- display chosen recipe from the data passed as parcel from
CreateRecipeActivity
3. Hand Tracking
- This feature is implemented in
ViewRecipeActivity
- 2 main Buttons
Start Tracking
andStop Tracking
to enable/disable the feature, which open up aglSurfaceView
in theRelativeLayout at the bottom of the page
glSurfaceView
is an instance ofSolutionGlSurfaceView<HandsResult>
provided by Mediapipe Library, similar to OpenGL that allows writing words and drawing on webcam output.- we detect whether the index finger is pointing up or down and from there, post a
Runnable
to ourScrollView
(that is displaying the Ingredients and Instructions) to perform a smooth scroll correspoding to the gesture.
- 2 main Buttons
4. Fragment
a. Cuisine Fragment under fragment/home
- Both
ChineseFragment
andVietnameseFragment
extends from abstract classBaseFragment
- using Factory Design Pattern (
BaseFragment
is the factory,ChineseFragment
andVietnameseFragment
are the products) allow us to easily scale to multiple cuisines in the future - the only abstract method is
getFragmentLayout
that each product should define to generate its own correct fragment - both using
RecyclerView
to display its recipes (explain in section B5c)
- using Factory Design Pattern (
b. Recipe Create Fragment under fragment/recipe
- 3 fragments correspond to 3 steps in creating a new Recipe:
RecipeCreateImageFragment
: (1st step) to add image, description, choose meal type and timeRecipeCreateIngredientFragment
: (2nd step) to add ingredientsRecipeCreateInstructionFragment
: (3rd step) to add instructions
- All 3 Create Recipe Fragments extends the abstract class
NavigableFragment
:- blueprint for method
onNext
that define which fragment to navigate to after completing each creating new recipe step - using Template Method Design Pattern with
NavigableFragment
as the template
- blueprint for method
RecipeCreateImageFragment
can access the local storage to upload new image for recipe (an Implicit Intent)
5. View and Layout
a. Toolbar
- Both
MainActivity
andViewRecipeActivity
needs to define its own Toolbar according to the blueprint defined in the abstract classMenuActivity
MainActivity
Toolbar:- includes
NavigationView
(explain in section B5b below) - includes menu to add a “New recipe”
- includes
ViewRecipeActivity
Toolbar:- support Edit and Delete recipe functionalities
b. Navigation View and DrawerLayout
- make use of a
switch
case to switch to a different cuisine insideMainActivity
- once a new cuisine is selected, the corresponding Fragment (
ChineseFragment
orVietnameseFragment
) will be added intoNestedScrollView
to show recipeCardView
c. RecyclerView
- We user
RecyclerView
at 2 places:- to display recipes in the Cuisine Fragment (
BaseFragment
) - to display the added ingredients and instructions when creating new recipe in Recipe Create Fragment
- to display recipes in the Cuisine Fragment (
- To implement
RecyclerView
we need to implement the corresponding adapter as shown inadapter/recipe
(Adapter Design Pattern)- the 3 main functions in each adapter to override are:
onCreateViewHolder
that inflate a new view in the parent layout to allow for display of listed itemsonBindViewHolder
that binds the data to be displayed in as listed itemsgetItemCount
that return the size of all the items to be displayed
- in the corresponding Fragment, before we set the above adapter, we also need to set a
LinearLayoutManager
for theRecyclerView
to reside in - code examples:
- the 3 main functions in each adapter to override are:
1 | private RecyclerView instructionRecyclerView; |
C. Appendix
0. Reference:
- We made use of a some very useful Youtube tutorials + Github repos to build a normal Cooking Recipe app before adding modifications and our hand tracking feature: