How change position of popup menu on android overflow button?

40,142

Solution 1

Add the following piece of code to your activity:

PopupWindow popupwindow_obj; // create object

popupwindow_obj=popupDisplay();  // initialize in onCreate()

popupwindow_obj.showAsDropDown(clickbtn,-40, 18); // where u want show on view click event

public PopupWindow popupDisplay() { // disply designing your popoup window
    final PopupWindow popupWindow = new PopupWindow(this); // inflet your layout or diynamic add view

    View view; 

    LayoutInflater inflater = (LayoutInflater)   getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    view = inflater.inflate(R.layout.mylayout, null);

    Button item = (LinearLayout) view.findViewById(R.id.button1);

    popupWindow.setFocusable(true);
    popupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
    popupWindow.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
    popupWindow.setContentView(view);

    return popupWindow;
}

Create an XML in res/layout directory and name it mylayout.xml

<LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Window test" />
</LinearLayout>

Solution 2

To overlap only, use this approach:

PopupMenu popupMenu = new PopupMenu(getContext(), this, Gravity.NO_GRAVITY, R.attr.actionOverflowMenuStyle, 0);

To get a PopupMenu with a bright background and a detailed control over the offsets use this approach:

styles.xml

<style name="PopupMenuOverlapAnchor" parent="@style/Theme.AppCompat.Light">
   <item name="android:overlapAnchor">true</item>
   <item name="android:dropDownVerticalOffset">0dp</item>
   <item name="android:dropDownHorizontalOffset">0dp</item>
</style>

Code:

ContextThemeWrapper contextThemeWrapper = new ContextThemeWrapper(getContext(), R.style.PopupMenuOverlapAnchor);
PopupMenu popupMenu = new PopupMenu(contextThemeWrapper, this);

Solution 3

Applying gravity helped in my case

PopupMenu popup = new PopupMenu(this, v, Gravity.RIGHT);

Solution 4

After trying out each approach that I have found, I would think putting an anchoring view might still be an easier and simpler way, especially when you are using a more flexible layout, e.g. ConstraintLayout.

Just put an invisible view to where you want the popup menu to anchor:

<View
    android:id="@+id/anchor_menu"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginTop="10dp"
    app:layout_constraintStart_toStartOf="@+id/button_menu"
    app:layout_constraintTop_toBottomOf="@+id/button_menu"
    />

Then use it as the anchoring view instead:

    mPopupMenu = new PopupMenu(getActivity(), mPopupMenuAnchor);

Boom, it is done.

Share:
40,142
user3266062
Author by

user3266062

Updated on May 21, 2021

Comments

  • user3266062
    user3266062 almost 3 years

    I just like to implement somethings same as popup menu in the Gmail app, anchored to the overflow button at the top-right. for that I used the same code as google tutorial for android Android popup menu, but for me show pop menu on top of edge of actionbar not under that. If you notice on pop menu of gmail overflow you saw that popmenu take place at edge of actionbar.

    This is the xml that I used for popup menu:

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item
            android:id="@+id/item1"
            android:title="lablab"/>
        <item
            android:id="@+id/item2"
            android:title="lablab"/>
    
    </menu>
    

    and at the follow is in my activity:

    public void showFontSetting(View view) {
        PopupMenu popup = new PopupMenu(this, view);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.menu, popup.getMenu());
        popup.show();
    
        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
    
            @Override
            public boolean onMenuItemClick(MenuItem item) {
            // TODO Auto-generated method stub
    
                switch (item.getItemId()) {
                    case R.id.item1:
                        Toast.makeText(Index.this,
                            "You Clicked : " + item.getTitle(),
                        Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.item2:
                        break;
                }
                return true;
            }
        });
    }
    
  • user3266062
    user3266062 almost 10 years
    I am new on android and I searched but I can't find any solution for Inflate my layout.
  • SuN
    SuN almost 10 years
    View view; LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVIC‌​E); view = inflater.inflate(R.layout.mylayout, null); RelativeLayout item = (RelativeLayout) view.findViewById(R.id.item);
  • user3266062
    user3266062 almost 10 years
    What should I put Instead of mylayout on inflate. I got lots of error.
  • SuN
    SuN almost 10 years
    :) you put your own layout. xml file
  • user3266062
    user3266062 almost 10 years
    Did you see my edit for adding code? respect to it I added your code and put view = inflater.inflate(R.menu.menu, null); RelativeLayout item = (RelativeLayout) view.findViewById(R.id.item1); and call it to my showFontSetting method of my code. But I recived lots of exception.
  • mhenry
    mhenry almost 9 years
    This questions is about a PopupMenu, not a PopupWindow.
  • Sanket Kachhela
    Sanket Kachhela almost 9 years
    @mhenry negative vote is accepted but accepted answer is also suggestion of to use a popup window.
  • danijar
    danijar over 8 years
    Any idea why popupMenu.getDragToOpenListener() is an android.widget.PopupMenu for me?
  • user1185087
    user1185087 over 8 years
    I think you analyzed the debug output and detect sth like this: mDragListener = {android.support.v7.widget.PopupMenu$1@7128}. Have a detailed look on the output: The last two signs before the @ are a 1 and a $ which means that the object is an inner anonymous class instance. A real instance of PopupMenu looks like that: this = {android.support.v7.widget.PopupMenu@7123} without $1. The source code of PopupMenu reveals also this fact: mDragListener = new ListPopupWindow.ForwardingListener(mAnchor) {...};
  • Neeraj
    Neeraj almost 8 years
    Sorry, forgot to mention, this has been added in Api 19 developer.android.com/reference/android/widget/…
  • Frank
    Frank over 7 years
    but it's in the support lib for all versions.
  • M.Paunov
    M.Paunov over 7 years
    This does not work. Maybe is worked in the past, but not any longer. Class ListPopupWindow does not define/declare a ForwardingListener. ForwardingListener is located in android.support.v7.widget and its listener.getPopup() does not have a method setVerticalOffset().
  • SeaJelly
    SeaJelly almost 7 years
    android:dropDownVerticalOffset and android:dropDownHorizontalOffset are not working for me, but the bright background works.
  • Jayesh
    Jayesh over 6 years
    @user1185087: please share actionOverflowMenuStyle from R.attr.actionOverflowMenuStyle
  • Rajarshi
    Rajarshi over 5 years
    It's truly replicates the overflow popup menu if the Gravity is set to Gravity.END.