手擼一個 微信長按菜單 - FloatMenu

在日常開發(fā)中,長按某個view出現(xiàn)個菜單是很常見的需求,Google 也給我們提供了一些組件來實現(xiàn),比如PopupMenu。但是在實際使用中還是發(fā)現(xiàn)他無法滿足我們的所有需求。

比如:產品要求長按菜單出現(xiàn)在手指按下的位置,額 這就頭疼了,PopupMenu只能展示在view的底部或者頭部。還有個問
題如果你的view過長超過一屏,那么 PopupMenu 就無法顯示在屏幕里了。

所以沒辦法,只能硬著頭皮自己擼一個menu了。 在日常使用中發(fā)現(xiàn)微信的 彈窗菜單 很符合要求,所以就模仿微信來擼一個了。

實現(xiàn)思路

  • 繼承 PopupWindow 來實現(xiàn)長按彈窗

  • 獲取當前按下 位置,傳給 view 來顯示

具體實現(xiàn)

  • 第一個很好實現(xiàn),我用的是recyclerView 來實現(xiàn)布局的,而且傳入的資源是 menu。而且另一個好處就是控制某些 item的可見(因為我自己項目中有這樣需求,所以考慮進去了)
    private Menu mMenu;
    
    @NonNull
    @SuppressLint("RestrictedApi")
    public Menu getMenu() {
        if (mMenu == null) {
            mMenu = new MenuBuilder(mContext);
        }
        return mMenu;
    }

    @NonNull
    public MenuInflater getMenuInflater() {
        return new MenuInflater(mContext);
    }

    public void inflate(@MenuRes int menuRes) {
        getMenuInflater().inflate(menuRes, getMenu());
    }

然后就是填充數(shù)據(jù)到recyclerView中了


  • 第二個需求,就需要在調用的Activity 中重寫dispatchTouchEvent獲取當前點擊位置,然后傳給 menu 來判斷顯示位置了
private Point mPoint = new Point();

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            mPoint.x = (int) ev.getRawX();
            mPoint.y = (int) ev.getRawY();
        }
        return super.dispatchTouchEvent(ev);
    }
    public void showPopup(View anchorView, int x, int y) {
        if (!getMenu().hasVisibleItems()) {
            return;
        }

        //set visible item data
        int size = getMenu().size();
        mMenuItems.clear();
        for (int i = 0; i < size; i++) {
            MenuItem item = getMenu().getItem(i);
            if (item.isVisible()) {
                mMenuItems.add(item);
            }
        }
        mMenuAdapter.notifyDataSetChanged();
        //show
        int menuHeight = Display.dip2px(mContext, DEFAULT_ITEM_HEIGHT * mMenuItems.size());
        if (x <= mScreenPoint.x / 2) {
            if (y + menuHeight < mScreenPoint.y) {
                setAnimationStyle(R.style.Animation_top_left);
                showAtLocation(anchorView, ANCHORED_GRAVITY, x + X_OFFSET, y);
            } else {
                setAnimationStyle(R.style.Animation_bottom_left);
                showAtLocation(anchorView, ANCHORED_GRAVITY, x + X_OFFSET, y - menuHeight);
            }
        } else {
            if (y + menuHeight < mScreenPoint.y) {
                setAnimationStyle(R.style.Animation_top_right);
                showAtLocation(anchorView, ANCHORED_GRAVITY, x - mMenuWidth - X_OFFSET, y);
            } else {
                setAnimationStyle(R.style.Animation_bottom_right);
                showAtLocation(anchorView, ANCHORED_GRAVITY, x - mMenuWidth + X_OFFSET, y - menuHeight);
            }
        }

    }

效果如下

pic1.png

大致思路就是這樣,最后奉上 源碼,如果你覺得對你有用,歡迎點個贊

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容