I follow the answer from this question: link
But I get this on my app:
As you can see on the ActionBar's right side there are two refresh icons (they were actually rotating when I took the screenshot). But I just want one to be there. I'm quite sure the problem is one of them is the item from the Menu XML file and the other is the ImageView from the actionbar_inderterminate_progress.xml file.
Here is my menu.xml file:
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.mypackage.android.design.appdesgin.MainActivity" >
<item android:id="#+id/action_search"
android:title="Search"
android:icon="#drawable/ic_action_search"
android:showAsAction="always"
android:actionViewClass="android.widget.SearchView"
android:visible="false" />
<item android:id="#+id/action_create_local_backup"
android:title="Search"
android:icon="#drawable/ic_action_new"
android:showAsAction="always"
android:visible="false" />
<item
android:id="#+id/action_refresh"
android:icon="#drawable/ic_menu_refresh"
android:showAsAction="always"
android:title="Refresh">
</item>
<TextView
android:id="#+id/status_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"/>
And here is my actionbar_inderterminate_progress.xml:
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/indeterminate_progress"
style="#android:style/Widget.ActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="#string/app_name"
android:src="#drawable/ic_menu_refresh" />
My animation XML file:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
android:interpolator="#android:anim/accelerate_decelerate_interpolator" />
And my java code:
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.main, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
refreshItem = item;
refresh();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void refresh() {
/* Attach a rotating ImageView to the refresh item as an ActionView */
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView imageView = (ImageView) inflater.inflate(R.layout.refresh_button, null);
Animation rotation = AnimationUtils.loadAnimation(getActivity(), R.animator.rotate_refresh);
rotation.setRepeatCount(Animation.INFINITE);
imageView.startAnimation(rotation);
refreshItem.setActionView(imageView);
}
Can anyone point me where and what am I doing wrong to make it only display one animated refresh button?
I was inflating the refresh button two times, one in MyActivity class and the other one on the Fragment that requires the refresh button.
Related
Currently, my options menu is aligned to the end of the screen. I want to give it a margin, something like android:layout_marginEnd = "20dp". How can I achieve this?
My options menu:
<?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"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".MainActivity">
<item
android:id="#+id/menu_items"
android:icon="#drawable/menu_icon"
app:showAsAction="always">
<menu>
<group android:id="#+id/item1">
<item
android:id="#+id/download"
android:icon="#drawable/download_icon"
android:title="Download"></item>
</group>
<group android:id="#+id/item2">
<item
android:id="#+id/invite"
android:icon="#drawable/invite_icon"
android:title="Invite"></item>
</group>
</menu>
</item>
</menu>
My Custom Toolbar:
<androidx.appcompat.widget.Toolbar
android:id="#+id/menu_toolbar"
app:popupTheme="#style/ThemeOverlay.MyTheme"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_below="#id/greetText"> <!--assume it comes somewhere in the centre due to this-->
</androidx.appcompat.widget.Toolbar>
My Theme for menu items:
<style name="ThemeOverlay.MyTheme" parent="ThemeOverlay.AppCompat.Light">
<item name="android:textColor">#color/dimGray</item>
<item name="android:textSize">14sp</item>
<item name="android:layout_marginEnd">20dp</item> <!-- doesn't work-->
<item name="android:fontFamily">#font/quicksand_medium</item>
<item name="android:background">#drawable/options_menu_background</item>
</style>
Here is the image of my problem. It shows how the end of the menu and the screen are aligned. I want space/margin between these two.
This is an interesting problem. I tried with many things found on the internet, but nothing works. I tried setting the actionOverflowMenuStyle with dropDownHorizontalOffset attribute which does not work either. Finally, I ended up getting a PopupMenu which works just fine. Here is the implementation.
Get your initial menu shorter with a single item which will open up the popup menu as a submenu.
<?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/menu_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Then create another menu, in your /res/menu/ folder, named popup_menu.xml like the following.
<?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/menu_items"
android:icon="#drawable/ic_close_swipe"
android:title="#string/app_name"
app:showAsAction="always" />
</menu>
Now in your MainActivity, just add the following functions to handle the click action of the menu button and the popup menu.
public class MainActivity extends AppCompatActivity implements PopupMenu.OnMenuItemClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar myToolbar = findViewById(R.id.menu_toolbar);
setSupportActionBar(myToolbar);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_items:
showPopupMenu();
return true;
default:
return false;
}
}
public void showPopupMenu() {
PopupMenu popup = new PopupMenu(this, findViewById(R.id.menu_items));
popup.setOnMenuItemClickListener(this);
popup.inflate(R.menu.popup_menu);
popup.setGravity(Gravity.END);
Object menuHelper;
Class[] argTypes;
try {
Field fMenuHelper = PopupMenu.class.getDeclaredField("mPopup");
fMenuHelper.setAccessible(true);
menuHelper = fMenuHelper.get(popup);
argTypes = new Class[]{boolean.class};
menuHelper.getClass().getDeclaredMethod("setForceShowIcon", argTypes).invoke(menuHelper, true);
} catch (Exception e) {
e.printStackTrace();
}
popup.show();
}
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.invite:
Toast.makeText(this, "Invite", Toast.LENGTH_LONG).show();
return true;
case R.id.download:
Toast.makeText(this, "Download", Toast.LENGTH_LONG).show();
return true;
default:
return false;
}
}
}
I put the working code in this Github Branch. You might consider cloning from that branch and run the application to check if that suffices your expectation.
Hope that helps!
This question already has answers here:
How to make an overflow menu like in Chrome?
(2 answers)
Closed 4 years ago.
How to create menu items aligned horizontally in the first row like google chrome
I created the first item with a menu child but by this way i got a row that send me to the other menu, So how to do that using menu file ? i don't want to use Dialog
Here is my menu 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">
<group android:id="#+id/toolbar_menu"
android:visible="true">
<item
android:id="#+id/item_tabs"
android:icon="#drawable/ic_tabs_24dp"
android:title="#null"
app:showAsAction="always"/>
<item
android:id="#+id/icon_row_menu_id"
android:title="#null"
android:visible="true">
<menu>
<item
android:id="#+id/item_back"
android:icon="#drawable/ic_arrow_back_24dp"
android:title="#string/go_back" />
<item
android:id="#+id/item_forward"
android:icon="#drawable/ic_arrow_forward_24dp"
android:title="#string/go_forward" />
<item
android:id="#+id/item_bookmark_page"
android:icon="#drawable/ic_star_border_24dp"
android:title="#string/bookmark_this_page" />
<item
android:id="#+id/item_download_page"
android:icon="#drawable/ic_download_24dp"
android:title="#string/download_page" />
<item
android:id="#+id/item_info"
android:icon="#drawable/ic_info_outline_24dp"
android:title="#string/view_site_information" />
</menu>
</item>
<item
android:id="#+id/item_new_tab"
android:title="#string/new_tab" />
<item
android:id="#+id/item_new_incognito_tab"
android:title="#string/new_incognito_tab" />
<item
android:id="#+id/item_bookmarks"
android:title="#string/bookmarks" />
<item
android:id="#+id/item_history"
android:title="#string/history" />
<item
android:id="#+id/item_downloads"
android:title="#string/download" />
<item
android:id="#+id/item_settings"
android:title="#string/settings" />
</group>
</menu>
And here how i use it :
#Override
public boolean onCreateOptionsMenu(Menu menu) {
mainMenu = menu;
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
You can use app:actionLayout="#layout/layout_name" property of item tag like
<item
android:id="#+id/menu_id"
android:title="#string/title"
app:showAsAction="never"
app:actionLayout="#layout/layout_name"/>
and your layout_name is any layout file like
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
// add your horizontal menu item here
</LineearLayout>
and you can access this item
#Override
public boolean onPrepareOptionsMenu(Menu menu)
{
MenuItem item = menu.findItem(R.id.menu_id);
Linearlayout rootView = (LinearLayout)item.getActionView();
YourControlClass control = (YourControlClass)
rootView.findViewById(R.id.control_id);
return true;
}
you can also try with PopUp window this may help you check above codes
popup.xml layout file not menu,
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#color/cardview_light_background"
android:layout_margin="20dp">
<LinearLayout
android:layout_margin="5dp"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
//your images with horizontal
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:layout_margin="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
// your vertical list view
</LinearLayout>
</LinearLayout>
and you can Add the following code to the onClick() method:
LayoutInflater layoutInflater
= (LayoutInflater) context
.getSystemService(LAYOUT_INFLATER_SERVICE);
final View popupView = layoutInflater.inflate(R.layout.popup, null);
final PopupWindow popupWindow = new PopupWindow(
popupView,
ActionMenuView.LayoutParams.WRAP_CONTENT,
ActionMenuView.LayoutParams.WRAP_CONTENT, true);
popupWindow.setOutsideTouchable(true);
popupWindow.setFocusable(true);
popupWindow.setBackgroundDrawable(new BitmapDrawable());
View parent = view.getRootView();
popupWindow.showAtLocation(parent, Gravity.TOP|Gravity.END,0,0);
How I can force menu item to show under overflow icon. I am providing app support from api level 8 and above. for now it is showing as actionview .
My menuLayout is as follows.
//main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<item
android:id="#+id/action_menu_setting"
android:title="#string/menuItemSetting"
app:showAsAction="ifRoom"/>
<item
android:id="#+id/action_signout"
android:title="#string/menuItemLogout"
app:showAsAction="ifRoom"/>
</menu>
in Java class
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
I have tried with other options of showAsAction but none of them worked. Please suggest me how I can show above two menu itme under overflow icon(when i click on over these two will appearer as actionlist.)
layout for custom action bar
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:background="#drawable/header"
android:orientation="vertical" >
<TextView
android:id="#+id/tvActionBarTitle"
android:layout_width="match_parent"
android:layout_height="?android:attr/actionBarSize"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="30sp" />
<Button.../>
<!-- your code for button -->
</LinearLayout>
You can call below function in onCreate and define button in this function as I have defined appName text view and its OnClick event
private void createCutomActionBarTitle()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
this.getActionBar().setHomeButtonEnabled(true);
}
this.getActionBar().setDisplayShowCustomEnabled(true);
this.getActionBar().setDisplayShowTitleEnabled(false);
this.getActionBar().setBackgroundDrawable(drawable);
this.getActionBar().setIcon(logo);
LayoutInflater inflator = LayoutInflater.from(this);
View v = inflator.inflate(R.layout.custom_action_bar, null);
((TextView) v.findViewById(R.id.tvActionBarTitle)).setText(Global.ACTIVITY_NAME);
this.getActionBar().setCustomView(v);
}
Hope this will be useful for you :)
But clicking physical button of device will not trigger this button you have to look for it, as I don't have any idea about it
Could you post java code ? Do you have code below in your activity ?
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
getMenuInflater().inflate(R.menu.menu, menu);;
return super.onCreateOptionsMenu(menu);
}
Edit :
I alway use code like this(when i click action_settings it will show action list contains setting and bar, i think just replace android:title="#string/action_settings" with android:icon)
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:showAsAction="always"
android:title="#string/action_settings">
<menu>
<item
android:enabled="true"
android:visible="true"
android:title="setting"
android:id="#+id/setting">
</item>
<item
android:enabled="true"
android:visible="true"
android:title="B"
android:id="#+id/bar">
</item>
</menu>
</item>
<item
android:id="#+id/action_settings1"
android:orderInCategory="100"
android:showAsAction="always"
android:title="#string/action_settings"/>
</menu>
Hope it helps
I'm trying to get my refresh button on my Actionbar to rotate, but I'm having some trouble getting it to work. The View just seems to lose it's horziontal margin/padding (which I haven't set anywhere), and does not rotate. I get no null errors, crashes, or anything else that could point me in the right direction. What am I doing wrong? Any help would be much apreciated.
Main.java:
public class Main extends ActionBarActivity{
...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
refresh();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
public void refresh() {
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ImageView imageView = (ImageView) inflater.inflate(R.layout.action_refresh, null);
Animation rotation = AnimationUtils.loadAnimation(this, R.anim.rotate);
rotation.setRepeatCount(Animation.INFINITE);
imageView.startAnimation(rotation);
MenuItem item = menu.findItem(R.id.action_refresh);
item.setActionView(R.layout.action_refresh);
}
}
Menu.XML
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:yourapp="http://schemas.android.com/apk/res-auto" >
<item android:id="#+id/action_refresh"
android:icon="#drawable/ic_action_refresh"
android:title="refresh"
android:actionLayout="#layout/action_refresh"
yourapp:showAsAction="ifRoom"
/>
<item
android:id="#+id/category_spinner_item"
android:showAsAction="ifRoom"
android:actionLayout="#layout/action_sort"
/>
</menu>
action_refresh.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_refresh"
/>
anim/rotate.xml
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%"
android:duration="10000"
android:interpolator="#android:anim/linear_interpolator" />
Just change this line:
item.setActionView(R.layout.action_refresh);
To this:
MenuItemCompat.setActionView(item, imageView);
The reason it doesn't animate with the original line is because you are setting the action view to the static image resource, not the imageView that you set up to animate.
I am trying to implement an action bar in which one of the buttons on click shows a popup menu.
Here's the menu. XML (menu items in the action bar)
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/search"
android:icon="#drawable/ic_action_search"
android:orderInCategory="0"
android:showAsAction="always"
android:title="#string/menu_search"/>
<item
android:id="#+id/refresh"
android:icon="#drawable/ic_action_refresh"
android:orderInCategory="1"
android:showAsAction="always"
android:title="#string/menu_refresh"/>
<Item
android:id="#+id/popup"
android:icon="#drawable/ic_action_search"
android:onClick="showPopup"
android:orderInCategory="1"
android:showAsAction="always"
android:title="#string/menu_search" />
I wish to show a popup menu on the click of the item having id "#+id/popup".
here is the XML for the popup menu
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/item1"
android:icon="#drawable/ic_action_search"
android:orderInCategory="0"
android:showAsAction="always"
android:title="#string/menu_search"/>
<item
android:id="#+id/item2"
android:icon="#drawable/ic_action_search"
android:orderInCategory="1"
android:showAsAction="always"
android:title="#string/menu_search"/>
here is the onClick method for the button
public void showPopup(View v) {
PopupMenu popup = new PopupMenu(this, v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.overflow, popup.getMenu());
popup.show();
}
And the problem is that no popup shows up on click of that button. Need help folks.
I found this here: http://developer.android.com/guide/topics/ui/menus.html
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/selectImg"
android:icon="#android:drawable/ic_dialog_dialer"
android:showAsAction="always">
<menu>
<item android:id="#+id/top"
android:title="#string/topimg"/>
<item android:id="#+id/bottom"
android:title="#string/botimg" />
</menu>
</item>
</menu>
You can put a menu within a menu to present sub-menus when the item is clicked. Then, in Java, you can use the same methods as usual.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
// View v = findViewById(R.id.f);
switch (item.getItemId()) {
case R.id.top:
//action
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The id of 'top' in the xml is still recognized even though it is a sub menu. This worked for me and it looks just like the popup menu.
Hi every one, that's my own solution : i created the showPopup method, and then i called it in the onOptionsItemSelected like this :
public void showPopup(){
View menuItemView = findViewById(R.id.menu_save);
PopupMenu popup = new PopupMenu(getActivity(), menuItemView);
MenuInflater inflate = popup.getMenuInflater();
inflate.inflate(R.menu.popup, popup.getMenu());
popup.show();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_save:
showPopup();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
popup.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/decon"
android:showAsAction="ifRoom"
android:title="#string/decon"/>
<item
android:id="#+id/mRes"
android:showAsAction="ifRoom"
android:title="#string/mesRes"/>
</menu>
main.xml => it's called onCreateOptionsMenu
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/menu_save"
android:enabled="true"
android:icon="#drawable/action_save"
android:showAsAction="ifRoom|withText"
android:title="#string/action_save"
android:visible="true"/>
</menu>
Finally i
implements PopupMenu.OnMenuItemClickListener to #Override onMenuItemClick method.
As the popup menu is a MENU, you have to handle this by implementing the "onOptionsItemSelected". You'll be able to say what to do for each menu option. It will replace the "onClick" option you defined and will be called automatically.
Try to change 'this' to getActivity().
public void showPopup(View v) {
PopupMenu popup = new PopupMenu(getActivity(), v);
MenuInflater inflater = popup.getMenuInflater();
inflater.inflate(R.menu.overflow, popup.getMenu());
popup.show();
}
Hope it helps..!!
I found a solution to this. Instead to using the menu XML to inflate the popup menu, I made a XML layout file.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#8b8989"
android:orientation="vertical"
android:padding="10dip" >
<TextView
android:id="#+id/menuItem1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="#string/menu1" />
<TextView
android:id="#+id/menuItem2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="#string/menu2" />
<TextView
android:id="#+id/menuItem3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="#string/menu3" />
</LinearLayout>
and i changed the onClick method
public void showPopup(View v) {
LayoutInflater inflater = (LayoutInflater) MainActivity.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
PopupWindow pw = new PopupWindow(inflater.inflate(
R.layout.overflow_layout, null, false), 300, 400, true);
pw.showAtLocation(findViewById(R.id.container), Gravity.CENTER, 0,
0);
}
This solved the issue
android:onClick="popup"
may be you should change it to android:onClick="showPopup"?