I am using the code from this question: Animated Icon for ActionItem to animate my refresh ActionBarButton. It works fine, except that the style doesn't seem to be right. When I click the item, it starts rotating, but only after it "jumps" a few pixels. It seems like the style of the ImageView is different from the style of the menu item.
The item is defined like this:
<item
android:id="#+id/action_refresh"
android:orderInCategory="100"
android:icon="#drawable/ic_menu_refresh"
android:showAsAction="ifRoom"
<!-- added this myself, didn't have any effect -->
style="#android:style/Widget.ActionButton"
android:title="#string/action_refresh"/>
and the ImageView like this:
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/action_refresh"
android:src="#drawable/ic_menu_refresh"
style="#android:style/Widget.ActionButton" />
How can I style my menuitem to match the ImageView in the rotation, or the other way round?
I found the solution by setting the View also for the non-animated item to be the same. In the menu.xml:
<item
android:id="#+id/action_refresh"
android:orderInCategory="100"
android:icon="#drawable/ic_menu_refresh"
android:actionLayout="#layout/refresh_action_view"
android:showAsAction="ifRoom"
style="#android:style/Widget.ActionButton"
android:title="#string/action_refresh"/>
Then, in onCreateOptionsMenu, I fetch the view in a member variable, and attach an onclick handler:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.orders, menu);
final Menu m = menu;
refreshItem = menu.findItem(R.id.action_refresh);
refreshItem.getActionView().setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
m.performIdentifierAction(refreshItem.getItemId(), 0);
}
});
return true;
}
In onCreate, we load the animation:
rotation = AnimationUtils.loadAnimation(this, R.anim.clockwise_refresh);
rotation.setRepeatCount(Animation.INFINITE);
Finally, call this to start the animation:
refreshItem.getActionView().startAnimation(rotation);
and this to stop it:
refreshItem.getActionView().clearAnimation();
It's better to change the ImageView to an ImageButton, and not to change the layout on the menu item in menu.xml, then the image will not jump, and you also don't need to add the click handler. It will also be the correct size, which will not be the case if you use an ImageView instead of an ImageButton.
This is all you need:
<ImageButton xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/action_refresh"
android:src="#drawable/ic_menu_refresh"
android:id="#+id/refresh_view"
style="#android:style/Widget.ActionButton" />
Put some padding in ImageView. In my case, 8dp on each side.
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="8dp"
android:paddingLeft="8dp"
android:src="#drawable/ic_action_important" />
Related
I need to get the View representing the three dots on the action bar.
(The reason I want the view reference is to pass it to a showcase library to show the showcaseView.)
No luck finding a solution. Any idea how to do that?
You can add the 3 dots using the below code. Add the below lines in your layout file.
<TextView
android:id="#+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:textColor="#color/colorPrimaryDark"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:paddingLeft="25dp"
android:paddingRight="15dp"
android:text="⋮"
android:textAppearance="?android:textAppearanceLarge"
android:textSize="25dp" />
Value in android:text field helps you display the 3 vertical dots
known as vertical-ellipsis.
Click for more details
You can use the TextView now to perform your further actions. I hope this is what you are looking for. Comment if you are stuck with anything. Thank-You.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.activity_main_actions, menu);
return super.onCreateOptionsMenu(menu);
}
Try to add this code in main activity after adding a view activity_main_actions.xml in res/menu like as below
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Search / will display always -->
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
android:showAsAction="ifRoom"/>
</menu>
Is it possible to take view in menu items of toolbar?
I want view like shown in yellow color between two menu items of toolbar.
Simply create a divider line view in xml file to show a divider line.
dividerLine.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<View
android:layout_width="1dp"
android:layout_height="?android:attr/actionBarSize"
android:background="#android:color/darker_gray"/>
</LinearLayout>
and set actionLayout to an item in menu xml to show divider line
activity_menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/your_icon1"
android:icon="#drawable/image1"
android:title="#string/text1"
app:showAsAction="always"
/>
<item android:id="#+id/icon2TricktoShowDividerLine"
android:actionLayout="#layout/dividerLine"
app:showAsAction="always"
android:title="#string/text2" />
<item android:id="#+id/your_icon3"
android:icon="#drawable/icon"
android:title="#string/text3"
app:showAsAction="always" />
</menu>
android:actionLayout="#layout/dividerLine" shows divider line between menu items. Hope this helps you.
Updated
I am getting this type of view from my above code :
You have to create the custom layout for menuItem uing actionLayout and then in oncreateOptionsMenue get the menuItem view and change your image view icon to vertical drawable
layout_actionitem.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<ImageView
android:id="#+id/actionItemImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="1dp"/>
</LinearLayout>
Your menu xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/item_save"
android:icon="#drawable/exit"
android:showAsAction="always"
android:actionLayout="#layout/layout_actionitem"
android:title=""/>
</menu>
onCreateOptionsMenu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
LinearLayout actionItemLayout = (LinearLayout) menu.findItem(R.id.item_save).getActionView();
ImageView iv = (ImageView)actionItemLayout.findViewById(R.id.actionItemImage);
iv.setBackgroundDrawable(getResources().getDrawable(R.drawable.icon_save));
}
Hope this helps.
I want to create a button in ActionBar with text and icon. Something like on the screenshot below.
I've tried this code. But it doesn't work. It displays only icon without text.
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/create"
android:title="#string/create"
android:icon="#drawable/ic_apply"
android:showAsAction="always|withText" />
</menu>
Read up on Toolbar
Since Toolbar is basically a ViewGroup, you can add child views. An example :
<Toolbar
android:id = "#+id/myToolbar"
android:layout_height = "wrap_content"
android:layout_width = "match_parent"
android:minHeight = "?attr/actionBarSize"
android:background = "?attr/colorPrimary" >
<Button
android:layout_height = "wrap_content"
android:layout_width = "match_parent"
android:text = "My button"
android:layout_gravity = "right" />
</Toolbar>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Search, should appear as action button -->
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
android:showAsAction="ifRoom" />
</menu>
If you mentioned android:showAsAction="ifRoom"
it is considered as Action bar button.
Inflating Menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
Handling Click event:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_search:
openSearch();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Assuming you are using AppCompat:
Your question maybe similar to: https://stackoverflow.com/a/18262141/950427
Make sure you bringing in the correct namespace: xmlns:yourapp="http://schemas.android.com/apk/res-auto".
Here is the example from the docs:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/action_search"
android:icon="#drawable/ic_action_search"
android:title="#string/action_search"
yourapp:showAsAction="ifRoom" />
...
</menu>
Explanation from the docs:
Using XML attributes from the support library Notice that the
showAsAction attribute above uses a custom namespace defined in the
tag. This is necessary when using any XML attributes defined by
the support library, because these attributes do not exist in the
Android framework on older devices. So you must use your own namespace
as a prefix for all attributes defined by the support library.
Documentation: http://developer.android.com/guide/topics/ui/actionbar.html#ActionItems
You can create different xml layout for actionbar and in that use buttons or text.
Example:
actionbar.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="vertical">
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button" />
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Enter Text"
android:textColor="#ffffff"
android:textStyle="bold"
android:textSize="#dimen/actionbar_title"/>
</LinearLayout>
use actionbar.xml in java file:
DisplayMetrics metrics = getResources().getDisplayMetrics();
ActionBar actionbar = getActionBar();
Drawable d=getResources().getDrawable(R.drawable.action2);
getActionBar().setBackgroundDrawable(d);
getActionBar().setIcon(android.R.color.transparent);
TextView title;
getActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getActionBar().setCustomView(R.layout.actiobar);
title= (TextView)findViewById(R.id.title);
title.setText("BUSINESS");
I have an app, which have toggle button in action menu item, though i'm using Actionbar Sherlock, I don't know, how to place the toggle button in the action menu item. I don't want to place as a custom layout in action bar, but i want to place it as a Menu item. If anyone find solution, Please help me out.
Purpose, If I change the state of toggle button, it will sort the person based on ALphabets and again in Date of Birth.
Thanks in Advance!
Just add it like a normal Menu Button, check its state with a boolean variable, and you can change the icon and title when changing the sortmode
boolean birthSort=false;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_toggle:
if(birthSort){
//change your view and sort it by Alphabet
item.setIcon(icon1)
item.setTitle(title1)
birthSort=false;
}else{
//change your view and sort it by Date of Birth
item.setIcon(icon2)
item.setTitle(title2)
birthSort=true;
}
return true;
}
return super.onOptionsItemSelected(item);
}
Don't forget to add it in xml like any other menu button and configure android:showAsAction if you want to show it in overflow or outside of it.
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_toogle"
android:showAsAction="ifRoom"
android:title="Share"
/>
</menu>
Other approach would be to use a custom layout for your ActionBar:
Basically you define a layout that contains your Toggle:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ToggleButton
android:id="#+id/actionbar_service_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Logging On"
android:textOff="Logging Off" />
</RelativeLayout>
ALTERNATIVE 1:
Then in your Activity or Fragment container you do:
ActionBar actionBar = getSupportActionBar();
actionBar.setCustomView(R.layout.actionbar_top);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_SHOW_CUSTOM);
...
ToggleButton button = (ToggleButton) findViewById(R.id.actionbar_service_toggle);
Notice that you are having a real ToggleButton and you are handling it in code as a real object ToggleButton, which has lots of advantages compared to having you re-implement your own toggle (theme, reliability, views hierarchy, native support...).
Source code here.
ALTERNATIVE 2:
Another way to do it is embed your custom view into a regular menu view:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/myswitch"
android:title=""
android:showAsAction="always"
android:actionLayout="#layout/actionbar_service_toggle" />
</menu>
If like me the actionLayout isn't working for you, try app:actionLayout="#layout/actionbar_service_toggle" instead of android:actionLayout="#layout/actionbar_service_toggle" as well as app:showAsAction="always" instead of android:showAsAction="always"
This is because if you use appCompat the android namespace won't be used.
So here's the final version:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<ToggleButton
android:id="#+id/actionbar_service_toggle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Logging On"
android:textOff="Logging Off" />
</RelativeLayout>
and
<?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/myswitch"
android:title=""
app:showAsAction="always"
app:actionLayout="#layout/actionbar_service_toggle" />
</menu>
create xml file in menu:
menu.xml
<menu 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" tools:context="si.ziga.switchinsideab.MainActivity">
<item android:id="#+id/switchId" android:title="" android:showasaction="always" android:actionlayout="#layout/switch_layout">
<item android:id="#+id/action_settings" android:orderincategory="100" android:title="#string/action_settings" app:showasaction="never">
</item></item></menu>
And then navigate to your layout folder make a new xml file
and name it switch_layout.xml
Here's the code:
switch_layout.xml
<!--?xml version="1.0" encoding="utf-8"?-->
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="match_parent" android:orientation="horizontal">
<switch android:id="#+id/switchAB" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerhorizontal="true" android:layout_centervertical="true">
</switch></relativelayout>
In your MainActivity class copy and paste this code:
MainActivity.java
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
switchAB = (Switch)menu.findItem(R.id.switchId)
.getActionView().findViewById(R.id.switchAB);7
Or follow this link about this stuff
Here somthing easy
<?xml version="1.0" encoding="utf-8"?>
<item
android:title="#string/mode"
android:id="#+id/switch1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:switchMinWidth="56dp"
android:layout_marginTop="120dp"
app:showAsAction="ifRoom"
app:actionViewClass="androidx.appcompat.widget.SwitchCompat"
android:checked="false"/>
I want something like this:
The 3rd icon is for notifications and it is just a png image now. Is it possible to do something, so that i can change the text/number ie.., 03 programatically to show the actual no.of notifications.
Thank You
Here is some example code that worked for me.
1: Create a layout for your badge menu item.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="48dp"
android:layout_height="fill_parent"
android:layout_gravity="right" >
<!-- Menu Item Image -->
<ImageView
android:layout_width="48dp"
android:layout_height="fill_parent"
android:clickable="true"
android:src="#drawable/bkg_actionbar_notify_off" />
<!-- Badge Count -->
<TextView
android:id="#+id/actionbar_notifcation_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="#dimen/padding_small"
android:text="99"
android:textColor="#color/holo_orange_dark" />
</RelativeLayout>
2: Create a menu item in res/menu and set the actionLayout to your layout
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/badge"
android:actionLayout="#layout/actionbar_badge_layout"
android:icon="#drawable/icn_menu_posts"
android:showAsAction="always">
</item>
</menu>
3: Then in onCreateOptionsMenu of your activity or fragment you can do something like this...
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.badge, menu);
RelativeLayout badgeLayout = (RelativeLayout) menu.findItem(R.id.badge).getActionView();
TextView tv = (TextView) badgeLayout.findViewById(R.id.actionbar_notifcation_textview);
tv.setText("12");
}
Note: If you wanted to change the badge count later on, you could store a reference to the Menu object passed to onCreateOptionsMenu and use the same code to get the required view and set a value.
=== ApCompat Warning ==================================================
If using the AppCompatActivity then you must set the actionView in onCreateOptionsMenu
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
MenuItem item = menu.findItem(R.id.badge);
MenuItemCompat.setActionView(item, R.layout.actionbar_badge_layout);
RelativeLayout notifCount = (RelativeLayout) MenuItemCompat.getActionView(item);
TextView tv = (TextView) notifCount.findViewById(R.id.actionbar_notifcation_textview);
tv.setText("12");
return super.onCreateOptionsMenu(menu);
One option is to create your own action view for this. Use android:actionLayout in the XML and getActionView() in Java after inflation to manipulate it. Your action view would be an ImageView (for the icon) and... something for the badge. I suspect that you will find that trying to make that badge via text will be difficult, and that you are better served with a bunch of badge images, one of which you layer on top of the icon (e.g., via RelativeLayout or FrameLayout, or by wrapping the icon in a LayerListDrawable).
Another option is simply to have N versions of the icon+badge, perhaps wrapped in a LevelListDrawable, that you choose from at runtime.
Had to make some changes to domji84's answers. For some reason the clicking on imageview was not calling the click event, it works find after removing the clicklabe = "true" from image view.
menu_item_cart.xml
<!-- Menu Item Image -->
<ImageView
android:layout_width="30dp"
android:layout_height="wrap_content"
android:src="#mipmap/ic_launcher" />
<!-- Badge Count -->
<TextView
android:id="#+id/cartCountTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:padding="5dp"
android:layout_marginTop="5dp"
android:text="99"
android:textColor="#android:color/white"
android:textStyle="bold"/>
</RelativeLayout>
menu_main.xml
<menu 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"
tools:context=".MainActivity">
<item
android:id="#+id/action_settings"
android:title="#string/action_settings"
android:orderInCategory="100"
app:showAsAction="never" />
<item
android:id="#+id/action_cart"
android:title="test"
app:actionLayout="#layout/menu_item_cart_count"
app:showAsAction="always">
</item>
</menu>
Activity code
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
menu.findItem(R.id.action_cart).getActionView().setOnClickListener(this);
return true;
}
Here you can use Custom action bar with default action bar...
firstly prepare layout by xml or java.then use display matrics and get window manager.After this inflate the layout. like this
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
ActionBar ab = getSupportActionBar();
View mactionbar = getLayoutInflater().inflate(R.layout.main2, null);