日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PopupMenu弹出位置的控制

發布時間:2024/1/8 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PopupMenu弹出位置的控制 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PopupMenu作為彈出菜單是很好用的,但是默認只能彈出在view的下方,而實際中這樣的彈出位置可能無法滿足需求,比如自定義的canvasView,要在canvasView長按的位置彈出菜單,PopupMenu只有一個show的方法,沒有可以設置位置的方法,但當我們跟進源碼去看時發現了這樣的一段代碼:

PopupMenu.class

public void show() {this.mPopup.show();}

再對mPopup.show跟蹤時進入到了MenuPopupHelper,又有如下的代碼

public void show() {if (!this.tryShow()) {throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");}}public void show(int x, int y) {if (!this.tryShow(x, y)) {throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");}}public boolean tryShow() {if (this.isShowing()) {return true;} else if (this.mAnchorView == null) {return false;} else {this.showPopup(0, 0, false, false);return true;}}

this.mPopup.show調用的是tryShow,而tryShow又調用的是showPopup,在showPopup的參數中有傳入xOffset和yOffset,這說明里面是有傳偏移量的,再仔細看MenuPopupHelper的show函數發現有show(x,y)的重載,如果我們能調用show(x,y),可能就能滿足需求。

但MenuPopupHelper又沒辦法直接得到,是包裝到PopupMenu中的,于是我們采用反射的方式來獲取,代碼如下

Field field = popupMenu.getClass().getDeclaredField("mPopup");field.setAccessible(true);MenuPopupHelper helper = (MenuPopupHelper) field.get(popupMenu);helper.show(x, y);

通過反射是得到了MenuPopupHelper,但是會提示錯誤MenuPopupHelper.show can only be called from within the same library group (groupId=com.android.support),跟入到MenuPopupHelper類里面,可以看到有如下圖的限定

為此,我們需要將剛剛反射的部分特別的封裝到一個方法中,并在方法上加入@SuppressLint("RestrictedApi"),這樣就可以正常運行了,代碼如下

public class MenuWorker implements PopupMenu.OnMenuItemClickListener {@SuppressLint("RestrictedApi")private void showPopupMenu(int x, int y) {if (!_drawActivity.isEditing()) {return;}//創建彈出式菜單對象(最低版本11)PopupMenu popupMenu = new PopupMenu(_drawActivity, _view);//第二個參數是綁定的那個view,菜單彈出時默認是顯示該view下方的。initMenu(popupMenu.getMenu());//綁定菜單項的點擊事件popupMenu.setOnMenuItemClickListener(this);//顯示//popupMenu.show();//默認顯示在view的下方,如果要控制具體顯示位置,需要使用反射來實現。try {Field field = popupMenu.getClass().getDeclaredField("mPopup");field.setAccessible(true);MenuPopupHelper helper = (MenuPopupHelper) field.get(popupMenu);y = y - _view.getHeight();//如果y取的是觸摸點的位置,可能需要作此處理,經測試android5.1的設備會彈窗在屏幕之外helper.show(x, y);} catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}/*** 初始化菜單** @param menu*/public void initMenu(Menu menu) {menu.clear();menu.add(1, 10001, 0, "添加");menu.add(1, 10002, 1, "刪除");menu.add(1, 10003, 2, "切換");}/*** 菜單點擊** @param menuItem* @return*/@Overridepublic boolean onMenuItemClick(MenuItem menuItem) {switch (menuItem.getItemId()) {case 10001: {//添加break;}case 10002: {//刪除break;}case 10003: {//切換;break;}default:break;}return false;} }

轉載請注明出處

總結

以上是生活随笔為你收集整理的PopupMenu弹出位置的控制的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。