Android 實(shí)現(xiàn)微信長(zhǎng)按菜單 -FloatMenu
在日常開(kāi)發(fā)中,長(zhǎng)按某個(gè)view出現(xiàn)個(gè)菜單是很常見(jiàn)的需求,Google 也給我們提供了一些組件來(lái)實(shí)現(xiàn),比如PopupMenu。但是在實(shí)際使用中還是發(fā)現(xiàn)他無(wú)法滿(mǎn)足我們的所有需求。
比如:產(chǎn)品要求長(zhǎng)按菜單出現(xiàn)在手指按下的位置,額 這就頭疼了,PopupMenu只能展示在view的底部或者頭部。還有個(gè)問(wèn)題如果你的view過(guò)長(zhǎng)超過(guò)一屏,那么 PopupMenu 就無(wú)法顯示在屏幕里了。
所以沒(méi)辦法,只能硬著頭皮自己擼一個(gè)menu了。 在日常使用中發(fā)現(xiàn)微信的 彈窗菜單 很符合要求,所以就模仿微信來(lái)擼一個(gè)了。
實(shí)現(xiàn)思路
•繼承 PopupWindow 來(lái)實(shí)現(xiàn)長(zhǎng)按彈窗
•獲取當(dāng)前按下 位置,傳給 view 來(lái)顯示
具體實(shí)現(xiàn)
•第一個(gè)很好實(shí)現(xiàn),我用的是recyclerView 來(lái)實(shí)現(xiàn)布局的,而且傳入的資源是 menu。而且另一個(gè)好處就是控制某些 item的可見(jiàn)(因?yàn)槲易约喉?xiàng)目中有這樣需求,所以考慮進(jìn)去了)
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中了
•第二個(gè)需求,就需要在調(diào)用的Activity 中重寫(xiě)dispatchTouchEvent獲取當(dāng)前點(diǎn)擊位置,然后傳給 menu 來(lái)判斷顯示位置了
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);
}
}
}
效果如下

大致思路就是這樣,最后奉上 源碼。
總結(jié)
以上所述是小編給大家介紹的Android 實(shí)現(xiàn)微信長(zhǎng)按菜單 -FloatMenu,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Android編程獲取地理位置的經(jīng)度和緯度實(shí)例
這篇文章主要介紹了Android編程獲取地理位置的經(jīng)度和緯度實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Android操作系統(tǒng)服務(wù)調(diào)用GPS實(shí)現(xiàn)定位的相關(guān)技巧,需要的朋友可以參考下2016-01-01
Android實(shí)現(xiàn)調(diào)用系統(tǒng)分享功能示例的總結(jié)
這篇文章主要介紹了通過(guò)Android調(diào)用系統(tǒng)分享文本信息、單張圖片、多個(gè)文件和指定分享到微信、QQ,同時(shí)分享圖片和文字的功能示例,小編覺(jué)得挺不錯(cuò),一起跟隨小編過(guò)來(lái)看看吧2018-05-05
Kotlin作用域函數(shù)應(yīng)用詳細(xì)介紹
作用域函數(shù):是Kotlin標(biāo)準(zhǔn)庫(kù)中的內(nèi)聯(lián)函數(shù),作用在對(duì)象上時(shí),執(zhí)行給定的block代碼塊??梢栽赽lock代碼塊中通過(guò)it,this代表當(dāng)前對(duì)象,進(jìn)行代碼邏輯處理2022-08-08
Android中使用socket使底層和framework通信的實(shí)現(xiàn)方法
native和framework的通信是通過(guò)jni,但是這一般只是framework調(diào)用native,native如果有消息要怎樣通知上層 呢?android中GSP模塊提供一種解決思路,但是實(shí)現(xiàn)有些復(fù)雜,這里介紹一種使用socket通信的方法可以使native和framework自由通信,感興趣的朋友一起看看吧2016-11-11
Android編程實(shí)現(xiàn)二維碼的生成與解析
這篇文章主要介紹了Android編程實(shí)現(xiàn)二維碼的生成與解析方法,結(jié)合實(shí)例分析了Android二維碼的生成與讀取二維碼的相關(guān)技巧,并提供了二維碼jar包供讀者下載,需要的朋友可以參考下2015-11-11
Android?掃碼槍輸入時(shí)屏蔽軟鍵盤(pán)和頂部狀態(tài)欄的解決方案
在Android設(shè)備上,使用掃碼槍時(shí)常遇到軟鍵盤(pán)和頂部狀態(tài)欄顯示問(wèn)題,本文介紹了在Android 7.1.2版本上,如何通過(guò)設(shè)置inputType為none屏蔽軟鍵盤(pán),以及通過(guò)hideStatusBar和NoActionBar方法隱藏頂部狀態(tài)欄,以?xún)?yōu)化掃碼槍使用界面,這些方法有助于提升使用掃碼槍場(chǎng)景的用戶(hù)體驗(yàn)2024-10-10
Android開(kāi)發(fā)仿掃一掃實(shí)現(xiàn)拍攝框內(nèi)的照片功能
無(wú)論是微信還是支付寶掃一掃功能很常用,那么它基于代碼是如何實(shí)現(xiàn)的呢?今天小編給大家分享android開(kāi)發(fā)之仿掃一掃實(shí)現(xiàn)拍攝框內(nèi)的照片功能,感興趣的朋友一起學(xué)習(xí)吧2016-09-09

