1

EDIT:
After some more tinkering around, I found out the reason for my previous problem (see below. TL;DR: I'm trying to pass a Bundle from an activity to its fragment by replacing the fragment) is that when replacing fragments like this:

    AddEditActivityFragment fragment = new AddEditActivityFragment();
    Bundle arguments = getIntent().getExtras();
    fragment.setArguments(arguments);
    getSupportFragmentManager().beginTransaction()
        .replace(R.id.add_edit_fragment, fragment)
        .commit();

the replaced fragment does not get destroyed (as it should be according to a bunch of sources), which I verified by overriding and adding logging to onPause, onStop, onDestroyView, onDestroy, etc. None of them are called.
Calling popBackStackImmediate also does nothing. What can I do?




Previous question title: "Setting FloatingActionButton icon dynamically with setImageDrawable doesn't have any effect."
I have a FAB inside a fragment (called AddEditFragment), that serves to save user input to database.
To differentiate between editing rows from the DB and creating new ones, I had its icon set either a "send" icon or a "save" icon. By default, the button is set to "send":

    <android.support.design.widget.FloatingActionButton
    android:id="@+id/add_edit_fab"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/fab_margin"
    app:layout_anchor="@id/add_edit_toolbar"
    app:layout_anchorGravity="bottom|right|end"
    app:srcCompat="@drawable/ic_send_white_24dp"/>

I used to set the icon to "save" by implementing an interface in my fragment, which serves to pass data from the containing activity to the fragment, using this method:

    @Override
public void receiveData(Serializable data) {
    Log.d(TAG, "receiveData: called");
    mFoodItem = (FoodItem) data;
    if (mFoodItem != null) {
        mEditMode = true;
        fab.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_save_white_24dp));
        utilDisplayFoodItem();
    }
}

The call the setImageDrawable worked fine and changed the icon from "send" to "save" properly.


Here is when I run into trouble.
I am trying to remove my AddEditFragment class' dependency on my AddEditActivity class, by removing said interface implementation and passing the data required by the fragment via Bundle:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "onCreate: starts");
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_add_edit);

    AddEditActivityFragment fragment = new AddEditActivityFragment();
    Bundle arguments = getIntent().getExtras();
    boolean editMode = arguments != null;
    fragment.setArguments(arguments);

    getSupportFragmentManager().beginTransaction()
            .replace(R.id.add_edit_fragment, fragment)
            .commit();

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
    getSupportActionBar().setTitle((editMode) ? "Edit Item:" : "Create Item:");
    getSupportActionBar().setElevation(0);
    Log.d(TAG, "onCreate: ends");
}


In this context, I removed receiveData method from the fragment, and placed this line:

fab.setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.ic_save_white_24dp));

in various likely places in my fragment class (the likeliest being inside its onCreateView method).
It doesn't seem to have any effect. My cases are:

  1. Just adding said setImageDrawable call - sets icon to "save" in both add/edit modes, but then I have no "send" icon.
  2. Setting either case dynamically (setImageDrawable call is inside if block) - icon is set to "send" in both add/edit modes.
  3. Removing default "send" icon from XML, then setting either case dynamically - icon is set to "send" in both add/edit modes.
  4. Removing default icon from XML, then setting only to "save" dynamically (no if block) - sets icon to "save" in both add/edit modes, but then I have no "send" icon.

It seems the setImageDrawable call, which worked perfectly in my receiveData interface method, doesn't have any effect (at least when an icon is already set, or when inside if block).

I'm at a loss and would appreciate any help!


In reply to @ColdFire:

        @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    Log.d(TAG, "onCreateView: starts");
    View view = inflater.inflate(R.layout.fragment_add_edit, container, false);
    ButterKnife.bind(this, view);

    Bundle arguments = getArguments();
    if (arguments != null) {
        mFoodItem = (FoodItem) arguments.getSerializable(FoodItem.class.getSimpleName());
        if (mFoodItem != null) {
            mEditMode = true;
            // Tried calling setImageDrawable here
        }
    }

    // Tried calling setImageDrawable here

    if (!mEditMode) {
        // If adding an item, initialize it for right now's date and time
        Calendar now = Calendar.getInstance();
        mFoodItem.setDate(now.get(Calendar.YEAR), now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH));
        mFoodItem.setTime(now.getTimeInMillis() / Constants.MILLISECONDS);
    }
    utilDisplayFoodItem();
    utilSetOnClickListeners();
    setHasOptionsMenu(true);

    // Tried calling setImageDrawable here

    Log.d(TAG, "onCreateView: ends");
    return view;
}

I should mention that everything else that depends on the Bundle data works correctly.

gelbermann
  • 15
  • 1
  • 9

1 Answers1

0

You might want to clear back stack by using the following method

private void clearBackStack() {
    FragmentManager manager = getSupportFragmentManager();
    if(manager.getBackStackEntryCount() > 0) {
        FragmentManager.BackStackEntry first = manager.getBackStackEntryAt(0);
        manager.popBackStackImmediate(first.getId(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }
}

You might want to check this post, Thanks

This will only destroy the current fragment to be replaced. If you want to destroy all you might want to read this stack question

Emmanuel Mtali
  • 4,383
  • 3
  • 27
  • 53
  • 3
    Sadly this doesn't work for me (nor do the questions you linked). The problem isn't that the fragment isn't replaced, but that the replaced fragment isn't destroyed, so I keep seeing some of its views (FAB specifically) on top of the new fragment, meaning it is still there. – gelbermann Oct 13 '17 at 09:04
  • @gelbermann Were you able to solve this? – HasIEluS Jun 13 '23 at 14:44
  • @HaslElus no idea, it's been a long time. Sorry – gelbermann Jun 14 '23 at 15:24