首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android ViewPager + Fragment 長按菜單觸發三次:預加載機制導致多實例共存

     編輯:程式設計綜合問答

問題現象

ViewPager 默認預加載左右各一頁,共三個 Fragment 實例同時存在。每個 Fragment 註冊 ContextMenu,長按時三個實例同時響應 → 觸發三次。

解決方案

方案一:設置 offscreenPageLimit = 0 (API 21+)

viewPager.setOffscreenPageLimit(0); // 僅保留當前頁,但可能影響滑動流暢度

方案二:在 Fragment 中判斷是否可見 (推薦)

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
    if (!isVisible()) return; // 只有用戶可見的 Fragment 才註冊/響應
    super.onCreateContextMenu(menu, v, menuInfo);
    // 添加菜單項...
}

Fragment.isVisible() 綜合判斷:added + not hidden + not detached + userVisibleHint=true。

方案三:使用 setUserVisibleHint (舊版)

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser && getActivity() != null) {
        registerForContextMenu(listView);
    } else {
        unregisterForContextMenu(listView); // 關鍵:不可見時取消註冊
    }
}

方案四:升級 RecyclerView + ViewPager2

  • ViewPager2 基於 RecyclerView,生命周期更精確,配合 FragmentStateAdapter 自動銷毀不可见 Fragment。
  • 長按菜單改用 RecyclerView.OnItemLongClickListener,天然無多實例問題。

總結

**ViewPager 預加載導致多 Fragment 共存**,同樣註冊 ContextMenu 會多次觸發。核心修復:**只在 Fragment 可見時註冊/響應菜單**(isVisible() 或 setUserVisibleHint)。長期建議遷移 ViewPager2 + RecyclerView 徹底解決。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved