Create navigation and bottom menu bar
Create fragments of several pages and add navigation
For the creation of fragments, please refer tohttps://www.jianshu.com/p/5974e52a024d
Add marked fragments temporarily, and refer to others later

Change the constraints of XML files corresponding to all fragments to constraintlayout
And all fragments are changed into binding to access the control

Create a navigation in res and add the newly created fragment to the navigation

Remove actionbar
Actionbar, that is, the navigation information of the header, is not used in this project
res -> themes -> themes. XML (change both)

In activity_ main. Add two controls to XML
Constraint layout at the same time

Add menu
Create a menu the same way you create a navigation

ID is the ID corresponding to the fragment. Each menu button is bound with a corresponding fragment so that page switching can be completed when clicked
Icon is a button icon, which can be added to drawable by yourself. If you are too lazy to design pictures, you can right-click to add vector asset in drawable to add picture resources provided by the system
Showasaction shows when the bottom menu bar will be displayed: the editor originally chose always, but the system recommends using ifroom
Here, let’s explain the three different statuses of shoasaction:
Always: indicates that it is always displayed in the container (the container here refers to the bottomnavigationbar)
Ifroom: indicates that it is displayed in the container if the screen is large enough, and in the menu if it is not large enough
Never: indicates that it is always displayed in the menu
As for the specific effect of each, you will know after trying
Icontint set default color

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:tools="http://schemas.android.com/tools"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/recipeFragment"
android:icon="@drawable/ic_book"
android:title="Recipes"
app:showAsAction="ifRoom"
android:iconTint="#7C7B7E"
tools:targetApi="o" />
<item
android:id="@+id/favoriteFragment"
android:icon="@drawable/ic_star"
android:title="Favorite"
app:showAsAction="ifRoom"
android:iconTint="#7C7B7E"
tools:targetApi="o"/>
<item
android:id="@+id/otherFragment"
android:icon="@drawable/ic_other"
android:title="Other"
app:showAsAction="ifRoom"
android:iconTint="#7C7B7E"
tools:targetApi="o"/>
</menu>
Setting button click status color change
Set the menu property of bottomnavigaitonview, and set the bottom_ Menu set to menu.

Create a color file and an item in Res_ color. xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#F5FC" android:state_checked="true"/>
<item android:color="#7C7b7E" android:state_checked="false"/>
</selector>
fragment_ recipe. XML interface setup

Shapeableimageview: set the circular pattern through shapeappearanceoverlay
image.png
<?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:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fragment.recipe.RecipeFragment">
<ImageView
android:id="@+id/imageView"
android:layout_width="0dp"
android:layout_height="0dp"
android:scaleType="centerCrop"
android:src="@drawable/main_bg"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:text="Welcome to Food App"
android:textColor="@color/white"
android:textSize="26sp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Ready to cook launch?"
app:layout_constraintStart_toStartOf="@+id/textView2"
app:layout_constraintTop_toBottomOf="@+id/textView2"
android:textStyle="bold"
android:textColor="#817F7C"
android:textSize="20sp"/>
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/shapeableImageView"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginEnd="16dp"
android:scaleType="centerCrop"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/textView2"
app:shapeAppearanceOverlay="@style/roundedCornerImageStyle"
app:srcCompat="@drawable/myhead" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:src="@drawable/top"
app:layout_constraintEnd_toEndOf="@+id/shapeableImageView"
app:layout_constraintStart_toStartOf="@+id/textView3"
app:layout_constraintTop_toBottomOf="@+id/textView3"
android:scaleType="centerCrop"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/typeRecyclerView"
android:layout_width="383dp"
android:layout_height="50dp"
android:layout_marginTop="30dp"
app:layout_constraintEnd_toEndOf="@+id/imageView2"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="@+id/imageView2"
app:layout_constraintTop_toBottomOf="@+id/imageView2" />
<com.todkars.shimmer.ShimmerRecyclerView
android:id="@+id/foodRecyclerView"
android:layout_width="0dp"
android:layout_height="272dp"
android:layout_marginTop="15dp"
app:shimmer_recycler_layout="@layout/food_item_shimmer_layout"
app:shimmer_recycler_item_count="4"
app:layout_constraintBottom_toBottomOf="@+id/imageView"
app:layout_constraintEnd_toEndOf="@+id/typeRecyclerView"
app:layout_constraintStart_toStartOf="@+id/typeRecyclerView"
app:layout_constraintTop_toBottomOf="@+id/typeRecyclerView"
app:layout_constraintVertical_bias="0.355" />
</androidx.constraintlayout.widget.ConstraintLayout>
Background color setting at the top of mobile screen
In order to make the background color of the image we set consistent with the system default top color, we need to Change color in XML

Search bar design

In recipefrragment
Note: this cannot be used in the context of the fragment, but requirecontext is required
private fun initRecyclerView(){
//Recyclerview for configuration type selection
binding.typeRecyclerView.layoutManager = LinearLayoutManager(requireContext(),RecyclerView.HORIZONTAL,false)
binding.typeRecyclerView.adapter = typeAdapter
//Handling callback events
typeAdapter.callBack= {current, last ->
val currentHolder = binding.typeRecyclerView.findViewHolderForAdapterPosition(current) as TypeAdapter.MyViewHolder
val lastHolder = binding.typeRecyclerView.findViewHolderForAdapterPosition(last)
//Select current
currentHolder.changeSelectedStatus(true)
//Cancel the previously selected
if (lastHolder != null){
val lastTypeHolder = lastHolder as TypeAdapter.MyViewHolder
lastTypeHolder.changeSelectedStatus(false)
}else{
//Refresh the last selected item
typeAdapter.notifyItemChanged(last)
}
//Get data
fetchData(typeAdapter.typeList[current])
}
}
Layout corresponding to adapter

In typeadapter
package com.example.foodresp.fragment.recipe.adapter
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.foodresp.databinding.ItemTypeBinding
/**
*@Description
*@Author PC
*@QQ 1578684787
*/
class TypeAdapter:RecyclerView.Adapter<TypeAdapter.MyViewHolder>() {
//Lambda for event callback
var callBack:((current:Int,last:Int)->Unit)?=null
val typeList = listOf("main course","side dish","dessert","appetizer","salad","bread",
"breakfast","beverage","sauce","marinade","finger food","snack","drink")
private var lastSelectedPosition = 0
class MyViewHolder(private val binding:ItemTypeBinding):RecyclerView.ViewHolder(binding.root) {
//Data callback
var callBack:((Int)->Unit)?=null
companion object{
fun from(parent: ViewGroup): MyViewHolder {
//Create viewholder
val inflater = LayoutInflater.from(parent.context)
return MyViewHolder(ItemTypeBinding.inflate(inflater))
}
}
//Binding data
fun bind(type:String,position: Int){
binding.titleTextView.text = type
binding.titleTextView.setOnClickListener {
callBack?.let {it(position) }
changeSelectedStatus(true)
}
}
fun changeSelectedStatus(status:Boolean){
binding.titleTextView.isSelected = status
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
val holder = MyViewHolder.from(parent)
//Handle callback events after clicking
holder.callBack = {
//Is the point the same
if (it!=lastSelectedPosition){
callBack?.let { call ->
call(it,lastSelectedPosition)
//Record the currently selected index
lastSelectedPosition = it
}
}
}
return holder
}
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
holder.bind(typeList[position],position)
if (position == lastSelectedPosition){
holder.changeSelectedStatus(true)
}else{
holder.changeSelectedStatus(false)
}
}
override fun getItemCount(): Int {
return typeList.size
}
}
See the following chapter for the detailed implementation analysis of the search bar