Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Absolute View Position in ListView

I am trying to make a popup window appear above/below an item that is clicked inside of a ListView. However, the problem is that the View that is coming in from the OnItemClick method is only giving me its X & Y values relative to the ListView itself. I also checked the ListView and that is also giving me x=0 y=0 despite the fact that there are other views above it.

I ran through all the values in hierarchyviewer, but didn't see the values I was looking for. (And not I'm having major problems getting it to work again).

Any advice?

@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
    LayoutInflater inflater = getLayoutInflater(null);
    PopupWindow quickRail = new PopupWindow(
            inflater.inflate(R.layout.quanitity_controls, null), view.getMeasuredWidth(),
            view.getMeasuredHeight());

    int[] location = {
            0, 0
    };

    // This doesn't place this window right on top of the view
    quickRail.showAtLocation(view, Gravity.CENTER, 0, location[1]);
}

Both items in the list are making the Popup appear in the same place. Popup Not Appearing In desired positions

like image 614
Frank Sposaro Avatar asked Jul 24 '12 14:07

Frank Sposaro


2 Answers

This should work

//Activity windows height
int totalHeight = getWindowManager().getDefaultDisplay().getHeight();
int[] location = new int[2];
v.getLocationOnScreen(location);

The location array should have the x and y values of the view. 'v' is the view object passed on the onItemClickListener.

Im adding some parts I used for my project. It might be helpful. I had an actionbar on the top of the listview and this code seemed to work fine.

The requirement was to bring a small menu either on top or below a list item. So when an item is selected, I check if the selected list item is in the upper half of the screen, if so put the menu below the list item otherwise put it on top of the list item. Here's the code

ListItem click code

listView.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view, int position
           , long id) {
        showQuickActionMenu(position,view);
    }   
});

private void showQuickActionMenu(int pos, View v){
    LayoutInflater inflater = 
            (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    //This is just a view with buttons that act as a menu.  
    View popupView = inflater.inflate(R.layout.ticket_list_menu, null);
    popupView.findViewById(R.id.menu_view).setTag(pos);
    popupView.findViewById(R.id.menu_change_status).setTag(pos);
    popupView.findViewById(R.id.menu_add_note).setTag(pos);
    popupView.findViewById(R.id.menu_add_attachment).setTag(pos);

    window = PopupHelper.newBasicPopupWindow(TicketList.this);
    window.setContentView(popupView);
    int totalHeight = getWindowManager().getDefaultDisplay().getHeight();
    int[] location = new int[2];
    v.getLocationOnScreen(location);

    if (location[1] < (totalHeight / 2.0)) {
        PopupHelper.showLikeQuickAction(window, popupView, v
                , getWindowManager(),0,0,PopupHelper.UPPER_HALF);
    } else {
        PopupHelper.showLikeQuickAction(window, popupView, v
                , getWindowManager(),0, 0,PopupHelper.LOWER_HALF);
    }   
}

This the PopupHelper class I use

public class PopupHelper {
    public static final int UPPER_HALF = 0;
    public static final int LOWER_HALF = 1;

    public static PopupWindow newBasicPopupWindow(Context context) {
        final PopupWindow window = new PopupWindow(context);

        // when a touch even happens outside of the window
        // make the window go away
        window.setTouchInterceptor(new OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
                if(event.getAction() == MotionEvent.ACTION_OUTSIDE) {
                    window.dismiss();
                    return true;
                }
                return false;
            }
        });

        window.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
        window.setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
        window.setTouchable(true);
        window.setFocusable(true);
        window.setOutsideTouchable(true);

        window.setBackgroundDrawable(
                new ColorDrawable(android.R.color.darker_gray));        
        return window;
    }

    /**
     * Displays like a QuickAction from the anchor view.
     * 
     * @param xOffset
     *            offset in the X direction
     * @param yOffset
     *            offset in the Y direction
     */
     public static void showLikeQuickAction(PopupWindow window, View root, 
             View anchor, WindowManager windowManager, int xOffset
             ,int yOffset,int section) {

         //window.setAnimationStyle(R.style.Animations_GrowFromBottomRight);

         int[] location = new int[2];
         anchor.getLocationOnScreen(location);

         Rect anchorRect = new Rect(location[0], location[1], location[0] + 
                 anchor.getWidth(), location[1] + anchor.getHeight());

         root.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

         int rootWidth = root.getMeasuredWidth();
         int rootHeight = root.getMeasuredHeight();

         int screenWidth = windowManager.getDefaultDisplay().getWidth();
         int screenHeight = windowManager.getDefaultDisplay().getHeight();

         int xPos = ((screenWidth - rootWidth) / 2) + xOffset;
         int yPos = anchorRect.top - rootHeight + yOffset;

         xPos = (screenWidth - rootWidth);
         if(section == UPPER_HALF){
             yPos = anchorRect.top + anchor.getMeasuredHeight();    
         } else {
             yPos = anchorRect.top - rootHeight;
         }
         window.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);
    }

}
like image 138
blessanm86 Avatar answered Nov 18 '22 15:11

blessanm86


for those who stick on this issue try use this code snippet

popWindow.showAsDropDown(v);//v is your listview or recyclerview item Element that clicked.

hope this help.

like image 1
Setmax Avatar answered Nov 18 '22 16:11

Setmax