Background
I have an action item that's not quite standard. It has its own layout, because I've failed to create a nice Drawable for it (written about it here).
Basically, it's just a TextView with a background that wraps its short text that it shows.
The problem
Sadly I can't find a way of fully mimic it to look like normal ones:
- The ripple effect (and probably the simple clicking effect on older versions too) doesn't have the same color and size.
- There isn't a toast for when I long click on it
- Maybe other things I haven't noticed?
Here are screenshots to demonstrate the differences:
The new, non standard, action item:
A native action item:
What I've tried
For the color of the ripple effect, I think I can use "colorControlHighlight", but I can't find out which color is the one used by default, correctly. I've looked inside the "values.xml" file of the support library, and noticed that it's "ripple_material_dark" color (or "ripple_material_light", in case the toolbar is supposed to be white) , but this seems a bit like a hack.
Not sure about the size, but looking at the layout inspector, I think the view has padding:
I've also noticed that the view class name of the toolbar is ActionMenuItemView
. I tried to look at its code (probably avaialble online too, here) , but didn't notice anything mentioned there about background. For padding I think it just tries to put the icon in the middle:
Anyway, this is the current code of the POC:
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var goToTodayView: View
lateinit var goToTodayTextView: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
goToTodayView = LayoutInflater.from(this).inflate(R.layout.go_to_today_action_item, toolbar, false)
goToTodayTextView = goToTodayView.goToTodayTextView
goToTodayTextView.setBackgroundDrawable(AppCompatResources.getDrawable(this, R.drawable.ic_backtodate))
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menu.add("goToToday").setActionView(goToTodayView).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS)
menu.add("asd").setIcon(R.drawable.abc_ic_menu_copy_mtrl_am_alpha).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS) //for comparison
return super.onCreateOptionsMenu(menu)
}
}
go_to_today_action_item.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="?attr/actionBarSize" android:layout_height="?attr/actionBarSize"
android:background="?attr/selectableItemBackgroundBorderless" android:backgroundTint="#fff" android:clickable="true"
android:focusable="true">
<TextView
android:id="@+id/goToTodayTextView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:gravity="center" android:text="1"
android:textColor="#fff" android:textSize="12dp" tools:background="@drawable/ic_backtodate" tools:layout_gravity="center"/>
</FrameLayout>
The questions
- How do I set the same background as a normal action item?
- How do I put the toast like a normal action item?
- Are there other things that are different between normal action item and one that I set with a layout?
- In other words, is it possible to fully mimic native action items? Maybe using the
ActionMenuItemView
class somehow? Maybe a very different solution from what I tried?
EDIT: for the background of the action items, I made it a bit like the original ones, but it's still not the same. Clicking effect seems a tiny bit different, and I haven't found how to show the toast of the action item upon long clicking on it. Here's the result:
Anyway, here's what I did:
go_to_today_action_item.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
android:layout_width="?attr/actionBarSize" android:layout_height="?attr/actionBarSize" android:clickable="true"
android:focusable="true">
<ImageView
android:layout_width="@dimen/action_item_background_size"
android:layout_height="@dimen/action_item_background_size" android:layout_gravity="center"
android:background="@drawable/action_item_selector" android:duplicateParentState="true"/>
<TextView
android:id="@+id/goToTodayTextView" android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:gravity="center" android:text="31" android:textColor="#fff"
android:textSize="12dp" tools:background="@drawable/ic_backtodate" tools:layout_gravity="center"/>
</FrameLayout>
drawable/action_item_selector.xml
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true">
<shape android:shape="rectangle">
<solid android:color="@color/clicking_semi_white_ripple_color"/>
</shape>
</item>
<item android:drawable="@android:color/transparent"/>
</selector>
drawable-v21/action_item_selector.xml
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/clicking_semi_white_ripple_color">
<item android:id="@android:id/mask">
<shape android:shape="oval">
<solid android:color="@android:color/white"/>
</shape>
</item>
</ripple>
colors.xml
<color name="clicking_semi_white_ripple_color">#33ffffff</color>
values/dimens.xml
<dimen name="action_item_background_size">48dp</dimen>
values-v21/dimens.xml
<dimen name="action_item_background_size">40dp</dimen>