【问题标题】:Get Absolute View Position in ListView获取 ListView 中的绝对视图位置
【发布时间】:2012-07-24 14:17:44
【问题描述】:

我正在尝试在 ListView 内单击的项目上方/下方显示弹出窗口。 但是,问题是来自 OnItemClick 方法的 View 只给了我相对于 ListView 本身的 X 和 Y 值。我还检查了 ListView,尽管上面还有其他视图,但它也给了我 x=0 y=0。

我浏览了 hierarchyviewer 中的所有值,但没有看到我正在寻找的值。 (并不是我在让它再次工作时遇到重大问题)。

有什么建议吗?

@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]);
}

列表中的两个项目都使弹出窗口出现在同一个位置。

【问题讨论】:

    标签: android android-layout android-listview android-view


    【解决方案1】:

    这应该可以工作

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

    位置数组应该具有视图的 x 和 y 值。 'v' 是 onItemClickListener 上传递的视图对象。

    我正在添加一些我用于我的项目的部分。这可能会有所帮助。我在列表视图的顶部有一个操作栏,这段代码似乎工作正常。

    要求是在列表项的顶部或下方放置一个小菜单。因此,选择项目时,请检查所选列表项是否位于屏幕的上半部分,如果使列表项下面的菜单放在列表项的顶部。 这是代码

    ListItem点击码

    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);
        }   
    }
    

    这是我使用的 PopupHelper 类

    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);
        }
    
    }
    

    【讨论】:

    • 谢谢你,但我试过了,它只给了我相对位置。所以第一项是列表是0,0。它很接近,因为我认为这也是解决方案。我相信我在某个地方遇到了一些翻译问题。
    • 你能把你的布局xml。我有同样的要求,但我的布局只有一个列表视图。
    • 废话。可悲的是,这看起来像我需要的代码。我希望有更漂亮的东西,但期待这个,哈哈。谢谢。
    • 是的。这很有效,正是我想要的。如果我能做的不仅仅是投票和接受,我会的。谢谢。
    【解决方案2】:

    对于那些坚持这个问题的人 尝试使用此代码 sn-p

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

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:

      试试这个,看看它是否有效..

      private  void setListViewHeightBasedOnChildren(ListView listView) {
          ListAdapter listAdapter = listView.getAdapter();
          if (listAdapter == null) {
              // pre-condition
              return;
          }
          int totalHeight = 0;
          int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
          for (int i = 0; i < listAdapter.getCount(); i++) {
              View listItem = listAdapter.getView(i, null, listView);
              listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
              totalHeight += listItem.getMeasuredHeight();
          }
      

      }

      //这里listItem.getMeasuredHeight()会得到你每个列表项的高度...你可以通过height*clickedPosition得到你的位置

      【讨论】:

      • 感谢您的回复。获取列表视图的高度没有问题。我正在尝试获取视图的屏幕坐标,以便在它旁边显示一个 PopupWindow。
      猜你喜欢
      • 2011-03-18
      • 2014-09-08
      • 1970-01-01
      • 2014-08-29
      • 2017-05-27
      • 2017-12-06
      • 1970-01-01
      • 2013-04-02
      相关资源
      最近更新 更多