Элементы панели действий Android остаются при извлечении фрагмента

Я использую панель действий поддержки. Я также использую фрагменты. Обычно я меняю фрагмент с помощью навигационного ящика, и все работает нормально. Каждый фрагмент может вносить изменения в элементы панели действий. Когда я перехожу на новый фрагмент, изменения (новые кнопки) удаляются.

Вот моя проблема. В одном случае я заменяю фрагмент и добавляю существующий фрагмент в задний стек. Когда я возвращаюсь к предыдущему фрагменту, на панели действий все еще есть элементы из предыдущего фрагмента.

Пример: 1) Фрагмент 1 загружает фрагмент 2 и помещает фрагмент 1 в задний стек 2) Фрагмент 2 помещает несколько новых кнопок на панель действий 3) Фрагмент 2 выходит, и теперь я вижу элементы панели действий из фрагментов 1 и 2

Я делаю то же самое с двумя другими фрагментами в другом месте, и у меня нет такой же проблемы. Единственная разница, которую я могу понять между двумя реализациями, - это то, как вторые фрагменты взаимодействуют с панелью действий.

В рабочем случае фрагмент 2 загружает элементы, расширяющие меню в onCreateMenuOptions. Это хорошо работает.

В НЕрабочем случае фрагмент 2 НЕ раздувает меню, а использует пользовательский вид:

         // Set action bar custom view and display options.
    MINMainActivity.getSharedInstance().getSupportActionBar().setCustomView(R.layout.custom_action_bar_viewer);
    MINMainActivity.getSharedInstance().getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO);
    MINMainActivity.getSharedInstance().getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.action_bar_bg));

Это единственная разница, которую я могу найти. Я что-то пропустил? (Очевидно) Но вопрос в чем???

Код, используемый для загрузки фрагмента 2 из фрагмента 1:

 MINMainActivity.getSharedInstance().mDrawerToggle.setDrawerIndicatorEnabled(false);

                        // Load the PDF fragment
                        MINPDFTronFragment fragment = new MINPDFTronFragment();
                        fragment.albumItem = albumItem;
                        getFragmentManager().beginTransaction()
                                .replace(R.id.content_frame, fragment)
                                .addToBackStack(null)
                                .commit();

Код onCreate, используемый для фрагмента 2:

     // ***************************************************************************************************
//
//  onCreate
//
// ***************************************************************************************************
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    //MINMainActivity.getSharedInstance().supportRequestWindowFeature(WindowCompat.FEATURE_ACTION_BAR_OVERLAY);
    setRetainInstance(true);
    setHasOptionsMenu(true);
    getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
}

НОВЫЕ РЕДАКТИРОВАНИЯ:

Это два метода, которые выполняют работу на панели действий. Первый раздел здесь — это код для Фрагмента 1. Фрагмент 1 — это фрагмент, который запускает Фрагмент 2 и размещает себя на заднем стеке:

     // ***************************************************************************************************
//
//  onCreateOptionsMenu
//
// ***************************************************************************************************
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
    mMenu = menu;

    // Inflate GridView menu
    inflater.inflate(R.menu.gridview_combined_menu, menu);

    // Gridview share menu
    MenuItem shareMenuItem = menu.findItem(R.id.MenuItemShare);
    mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareMenuItem);
    setGridViewShareIntent(null); // TODO is this needed?

    super.onCreateOptionsMenu(menu, inflater);
}


// ***************************************************************************************************
//
//  onPrepareOptionsMenu
//
// ***************************************************************************************************
@Override
public void onPrepareOptionsMenu(Menu menu)
{
    setOptionMenuItems();
    super.onPrepareOptionsMenu(menu);
}

Вот те же методы во Фрагменте 2 (фрагмент, запущенный Фрагментом 1:

     // ***************************************************************************************************
//
//  onCreateOptionsMenu
//
// ***************************************************************************************************
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
    mMenu = menu;
    super.onCreateOptionsMenu(menu, inflater);
}


// ***************************************************************************************************
//
//  onPrepareOptionsMenu
//
// ***************************************************************************************************
@Override
public void onPrepareOptionsMenu(Menu menu)
{
    MINMainActivity MINMainActivity = (MINMainActivity) getActivity();
    boolean drawerIsOpen = MINMainActivity.mDrawerLayout.isDrawerOpen(MINMainActivity.mDrawerList);

    if(drawerIsOpen)
    {
    }

    else
    {
        }
    }
    super.onPrepareOptionsMenu(menu);
}

Как видите, Fragment 2 не создает моды этими методами. Ниже приведен код во Фрагменте 2, управляющий панелью действий:

     // ***************************************************************************************************
//
//  onCreateView
//
// ***************************************************************************************************
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    initViewerLayout(inflater, container, savedInstanceState);
 }
     // ***************************************************************************************************
//
//  initViewerLayout
//
// ***************************************************************************************************
private void initViewerLayout(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    // Initialize the library
    try
    {
        PDFNet.initialize(MINMainActivity.getSharedInstance(), R.raw.pdfnet);
    }
    catch (PDFNetException e)
    {
        // Do something...
        e.printStackTrace();
    }

    // Inflate the view and get a reference to PDFViewCtrl
    pageView = inflater.inflate(R.layout.pdf_viewer, container, false);

    // Set action bar custom view and display options.
    MINMainActivity.getSharedInstance().getSupportActionBar().setCustomView(R.layout.custom_action_bar_viewer);
    MINMainActivity.getSharedInstance().getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO);
    MINMainActivity.getSharedInstance().getSupportActionBar().setBackgroundDrawable(getResources().getDrawable(R.drawable.action_bar_bg));

    // Initialize action bar buttons (we are using a custom view, so we
    // need to set click listeners for each item.
    mButtonViewMode = (ImageButton) MINMainActivity.getSharedInstance().getSupportActionBar().getCustomView().findViewById(R.id.ab_action_viewmode);
    mButtonViewMode.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ViewModePickerDialogFragment dialog = new ViewModePickerDialogFragment();
            dialog.mListener = MINPDFTronFragment.this;
            dialog.show(MINMainActivity.getSharedInstance().getSupportFragmentManager(), "view_mode_picker");
            stopHideToolbarsTimer();
        }
    });
    updateButtonViewModeIcon();

    mButtonOutline = (ImageButton) MINMainActivity.getSharedInstance().getSupportActionBar().getCustomView().findViewById(R.id.ab_action_outline);
    mButtonOutline.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FragmentManager fragmentManager = MINMainActivity.getSharedInstance().getSupportFragmentManager();
            // Creates the dialog in full screen mode
            mBookmarksDialog = new BookmarksDialogFragment(mPdfViewCtrl, mBookmarkDialogCurrentTab);
            mBookmarksDialog.setBookmarksDialogFragmentListener(MINPDFTronFragment.this);
            mBookmarksDialog.mOutlineDialogFragmentListener = MINPDFTronFragment.this;
            mBookmarksDialog.mAnnotationDialogFragmentListener = MINPDFTronFragment.this;
            mBookmarksDialog.setStyle(DialogFragment.STYLE_NO_TITLE, android.support.v7.appcompat.R.style.Theme_AppCompat_Light);
            mBookmarksDialog.show(fragmentManager, "bookmarks_dialog");

            stopHideToolbarsTimer();

            // Example of how to show the OutlineDialogFragment as a dialog
            //OutlineDialogFragment outlineDialogFragment = new OutlineDialogFragment(mPdfViewCtrl);
            //outlineDialogFragment.setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light);
            //outlineDialogFragment.show(fragmentManager, "outline_dialog");

            // Example of how to show the AnnotationDialogFragment as a dialog
            //AnnotationDialogFragment annotDialog = new AnnotationDialogFragment(mPdfViewCtrl);
            //annotDialog.setStyle(DialogFragment.STYLE_NO_TITLE, android.support.v7.appcompat.R.style.Theme_Base_AppCompat_Light);
            //annotDialog.show(fragmentManager, "annotation_dialog");
        }
    });

    mSearchView = (SearchView) MINMainActivity.getSharedInstance().getSupportActionBar().getCustomView().findViewById(R.id.ab_action_search);
    mSearchView.setFocusable(false);
    mSearchView.setFocusableInTouchMode(false);
    // Let's get the internal button of the search view widget to change some properties.
    ImageView searchButton = (ImageView) mSearchView.findViewById(android.support.v7.appcompat.R.id.search_button);
    searchButton.setBackgroundDrawable(mSearchView.getContext().getResources().getDrawable(R.drawable.controls_annotation_toolbar_tool_bg));
    searchButton.setImageDrawable(mSearchView.getContext().getResources().getDrawable(R.drawable.ic_action_search));
    mSearchView.setOnQueryTextListener(this);
    mSearchView.setIconifiedByDefault(true);
    mSearchView.setOnSearchClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            SearchView searchView = (SearchView) view;
            if (searchView.isIconfiedByDefault() && !searchView.isIconified()) {
                AnalyticsHandler.getInstance().sendEvent("[Viewer] Find Text clicked");

                // Search has expanded
                startSearchMode();
            }
        }
    });
    mSearchView.setOnCloseListener(new SearchView.OnCloseListener() {
        @Override
        public boolean onClose() {
            exitSearchMode();
            return false;
        }
    });

    mButtonAnnotToolbar = (ImageButton) MINMainActivity.getSharedInstance().getSupportActionBar().getCustomView().findViewById(R.id.ab_action_tools);
    mButtonAnnotToolbar.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mAnnotationToolbar = new AnnotationToolbar(MINApplication.getAppContext(), pageView, mToolManager);
            mAnnotationToolbar.setButtonStayDown(SettingsManager.getContinuousAnnotationEdit(MINApplication.getAppContext()));

            if (SettingsManager.getContinuousAnnotationEdit(MINApplication.getAppContext())) {
                AnalyticsHandler.getInstance().sendEvent("[General] Continuous Annotation Edit enabled");
            }

            mAnnotationToolbar.show();

            AnalyticsHandler.getInstance().sendEvent("[Annotation Toolbar] Annotation Toolbar opened");
        }
    });

    mButtonShare = (ImageButton) MINMainActivity.getSharedInstance().getSupportActionBar().getCustomView().findViewById(R.id.ab_action_share);
    mButtonShare.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {
            if (MiscUtils.isKitKat()) {
                // If KitKat or higher, we show the Share/Print option
                SharePickerDialogFragment dialog = new SharePickerDialogFragment();
                dialog.mListener = MINPDFTronFragment.this;
                dialog.show(MINMainActivity.getSharedInstance().getSupportFragmentManager(), "share_mode_picker");
            } else {
                MiscUtils.sharePdfFile(MINApplication.getAppContext(), albumItem);
                AnalyticsHandler.getInstance().sendEvent("[Viewer] Share clicked");
            }
        }
    });

    // Search prev/next buttons.
    mButtonSearchNext = (ImageButton) pageView.findViewById(R.id.floating_button_next);
    mButtonSearchNext.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mSearchUp = false;
            findText();
        }
    });
    mButtonSearchPrev = (ImageButton) pageView.findViewById(R.id.floating_button_prev);
    mButtonSearchPrev.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mSearchUp = true;
            findText();
        }
    });

    // PDFViewCtrl settings
    mPdfViewCtrl = (CompleteReaderPDFViewCtrl) pageView.findViewById(R.id.pdfviewctrl);
    mPdfViewCtrl.setUrlExtraction(true);
    mPdfViewCtrl.setupThumbnails(true, true, true, 0, 50 * 1024 * 1024, 0.1);
    mPdfViewCtrl.setPageViewMode(PDFViewCtrl.PAGE_VIEW_FIT_PAGE);
    mPdfViewCtrl.setPageRefViewMode(PDFViewCtrl.PAGE_VIEW_FIT_PAGE);
    mPdfViewCtrl.setHighlightFields(true);
    mPdfViewCtrl.setZoomLimits(PDFViewCtrl.ZOOM_LIMIT_RELATIVE, 1.0, 20.0);
    updateViewMode();

    mSeekBar = (ThumbnailSlider) pageView.findViewById(R.id.thumbseekbar);
    // We pass a reference of the PDFViewCtrl to the slider so it can
    // interact with it (know number of pages, change pages, get thumbnails...
    // At this point no doc is set and the slider has no enough data
    // to initialize itself. When a doc is set we need to reset its data.
    mSeekBar.setPDFViewCtrl(mPdfViewCtrl);

    mPageNumberIndicator = (TextView) pageView.findViewById(R.id.page_number_indicator_current_page);

    mSearchProgressDialog = new ProgressDialog(getActivity());
    mSearchProgressDialog.setMessage(getResources().getString(R.string.search_in_progress));
    mSearchProgressDialog.setIndeterminate(true);
    mSearchProgressDialog.setCancelable(true);
    mSearchProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            mPdfViewCtrl.cancelFindText();
        }
    });

    mDownloadDocumentDialog = new ProgressDialog(getActivity());
    mDownloadDocumentDialog.setMessage(getResources().getString(R.string.download_in_progress_message));
    mDownloadDocumentDialog.setIndeterminate(true);
    mDownloadDocumentDialog.setCancelable(true);
    mDownloadDocumentDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            Toast.makeText(MINApplication.getAppContext(), R.string.download_cancelled_message, Toast.LENGTH_SHORT).show();
            //TODO finish();
        }
    });
}

person JustLearningAgain    schedule 19.07.2014    source источник


Ответы (2)


Попробуйте вызвать invalidateOptionsMenu() в onResume из ваших 1 фрагмент.

РЕДАКТИРОВАТЬ:

Если пользовательская панель действий была установлена ​​во фрагменте 2, вам необходимо отключить ее в первом фрагменте (например, в onResume()):

MINMainActivity.getSharedInstance().getSupportActionBar().setDisplayOptions(Act‌​ionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO);
person Dmide    schedule 22.07.2014
comment
Я уже пробовал это, но это была хорошая идея. Лично я считаю, что это должно работать, и я не уверен, почему это не так. Каким-то образом он сохраняет эти кнопки, даже когда вы отключаете меню параметров. Я не знаю, как, поскольку supportInvalidateOptionsMenu должен все очистить. Если кнопки каким-то образом повторно добавляются, даже если мы не перезагружаем фрагмент 2, это указывает на то, как фрагмент 2 инициализирует меню параметров в первую очередь. Я продолжаю думать, что это должно иметь какое-то отношение к .setCustomView - person JustLearningAgain; 22.07.2014
comment
есть ли шансы, что у вас есть неправильный экземпляр Context с вашим методом getSharedInstance()? - person Dmide; 23.07.2014
comment
Я использую один и тот же контекст во всем приложении. Так что я не думаю, что это проблема. Как бы я проверил? - person JustLearningAgain; 23.07.2014
comment
Может быть, вам следует вызвать MINMainActivity.getSharedInstance().getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME | ActionBar.DISPLAY_USE_LOGO); в 1 фрагменте onResume()? то есть отключить пользовательский вид - person Dmide; 24.07.2014

Вот моя проблема. В одном случае я заменяю фрагмент и добавляю существующий фрагмент в задний стек. Когда я возвращаюсь к предыдущему фрагменту, на панели действий все еще есть элементы из предыдущего фрагмента. Где вы вызываете метод, который меняет вашу панель действий новыми кнопками? если вы вызовете его во фрагменте onCreate(), он не будет вызван. попробуйте вызвать его из фрагмента onActivityCreated (Bundle saveInstanceState).

взгляните на методы жизненного цикла фрагментов Методы жизненного цикла фрагментов

person Ibrahim Disouki    schedule 19.07.2014
comment
Вся работа выполняется двумя способами. Я изменю свой вопрос выше с помощью методов из Фрагмента 1 (фрагмент, запускающий Фрагмент 2) и Фрагмента 2 (фрагмент, запущенный Фрагментом 1). - person JustLearningAgain; 19.07.2014