Custom Menu Item Using Action Layout

Anik Dey
2 min readNov 15, 2019

Few days back while working with a project i came across a requirement where i needed to show a menu item with custom design. Here is how i did that using actionLayout.

To have the floating action button add this line in your app.gradle and perform a sync

implementation 'com.google.android.material:material:1.1.0-alpha10'

Create your menu.xml file

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">


<item
android:id="@+id/refresh
android:orderInCategory="100"
android:title=""
app:actionLayout="@layout/refresh_menu_item_action_layout"
app:showAsAction="always" />

</menu>

Now inside your layout folder create refresh_menu_item_action_layout.xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/appCompatTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFFFFF"
android:lineHeight="16dp"
android:textSize="16sp"
android:text="Refresh"
android:layout_marginRight="8dp"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabRefresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:elevation="4dp"
android:scaleType="center"
android:backgroundTint="#C1E5E5"
app:backgroundTint="#C1E5E5"
app:fabSize="mini"
app:rippleColor="#3cffffff"
android:layout_marginRight="8dp"
app:srcCompat="@drawable/baseline_autorenew_24"
app:tint="#FFFFFF"
/>
</LinearLayout>

Now we can inflate the menu from activity and set click listener like this

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}


override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu, menu)

val item: MenuItem = menu.findItem(R.id.refresh)

item.actionView.findViewById<FloatingActionButton>(R.id.fabRefresh).setOnClickListener {
Toast.makeText(this, "Your clicked on the floating button", Toast.LENGTH_SHORT).show()
}

item.actionView.findViewById<AppCompatTextView>(R.id.appCompatTextView).setOnClickListener {
Toast.makeText(this, "Your clicked on the textview", Toast.LENGTH_SHORT).show()
}
return true
}

}

If your activity is hosting a fragment or you are using a navigation graph you can inflate the menu from fragment and set click listeners like this.

First set has options menu as true in the fragment

setHasOptionsMenu(true)

and then

override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_clear_goal, menu)

val item: MenuItem = menu.findItem(R.id.refresh)
item.actionView.findViewById<FloatingActionButton>(R.id.fabRefresh).setOnClickListener {
// Todo.. code your stuff here..

}
}

--

--