Ale
Ale

Reputation: 2344

android prevent fragment leave on back pressed

I have a ViewPager inside a FragmentActivity. For each page I have a Fragment with an EditText.

I want to prevent the user leaving the screen if the EditText value has changed, showing a warning Dialog asking if he/she really wants to leave the screen.

For that I need to check the EditText value when the back Button is pressed.

I have only found how to do it but using the onBackPressed() method in the container FragmentActivity.

The problem is that I don't know how to access the EditText inside the Fragment from the parent FragmentActivity.

Is it not possible just to do it in the Fragment? I've tried the method onStop and onDetach but they are called after leaving the Fragment, so I cannot stop it.

Any ideas?

Upvotes: 0

Views: 1941

Answers (4)

IrApp
IrApp

Reputation: 1843

Try this in your parent Activity:

@Override
public void onBackPressed() {
     super.onBackPressed();

     YourFragment fragment = (YourFragment) getSupportFragmentManager().getFragments().get(viewPager.getCurrentItem());

}

Then you have access to your Fragment so you can add a parameter in your fragment textHasChanged (for example) and update it when the text changes.

Upvotes: 1

Federico De Gioannini
Federico De Gioannini

Reputation: 927

You could create a Boolean value in the FragmentActivity and keep it updated with the EditText updated. In this way you can check the String value instead the EditText (In fact the fragment could not be loaded in the Pager).

For example:

1) create an interface in order to declare the input protocol

public interface InputInterface {
    void setEditTextNotEmpty(Boolean notEmpty);
}

2) implement this interface in your FragmentActivity

public class MainActivity implements InputInterface {
private Boolean editTextNotEmpty;

...
@Override
void setEditTextNotEmpty(Boolean changed){
    editTextNotEmpty=changed;
}

@Override
public void onBackPressed() {
    ... your custom code....
}

3) You somehow notify the Fragment when it's visualized as for in this post: How to determine when Fragment becomes visible in ViewPager

When the fragment is visualized, you update the activity boolean if necessary.

4) keep your MainActivity updated when you update the edit text:

yourEditText.addTextChangedListener(new TextWatcher() {
      public void afterTextChanged(Editable s) {
          if (getActivity instanceof InputInterface){
              Boolean notEmpty = !TextUtils.isEmpty(s.toString);
             ((InputInterface)getActivity).setEditTextNotEmpty(notEmpty);
          }
      }

      public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

      public void onTextChanged(CharSequence s, int start, int before, int count) {}
   });

I hope it helped.

Upvotes: 0

Sohail Zahid
Sohail Zahid

Reputation: 8149

So you need BackPressed() event in fragment for you problem to check if editext is values is changed or not?

So you have create you own OnBackpressed() interface.

Create a interface OnBackPressedListener

public interface OnBackPressedListener {
    public void doBack();
}

Create a new class name BaseBackPressedListener

public class BaseBackPressedListener implements OnBackPressedListener {
    private final FragmentActivity activity;

    public BaseBackPressedListener(FragmentActivity activity) {
        this.activity = activity;
    }

    @Override
    public void doBack() {
        activity.getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
      //activity.getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }
} 

Create a instance of your newly created class BaseBackPressedListener in your top base Activity where fragment is added

protected OnBackPressedListener onBackPressedListener;

Create a method in your top base activity to set newly created instance of new class above

public void setOnBackPressedListener(OnBackPressedListener onBackPressedListener) {
    this.onBackPressedListener = onBackPressedListener;
}

you will have overide onBackPressed() method in you top base activity modify it like this

@Override
public void onBackPressed() {
    if (onBackPressedListener != null)
        onBackPressedListener.doBack();
    else
        super.onBackPressed();
     }

And lastly you have add this in you fragment onCreateView()

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    Activity activity = getActivity();

    ((BaseActivity)activity).setOnBackPressedListener(new BaseBackPressedListener(activity));


    //your other stuff here

    return view;
}

Now you can check on back pressed in your top base activity weather editext value change our not by modifying this methods

 @Override
    public void doBack() {
    if(!IsEditTextChanged)
        activity.getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
      //activity.getFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    }

IsEditTextChanged is global variable set its values on textchanged

mEditText.addTextChangedListener(new TextWatcher() {

   @Override
   public void afterTextChanged(Editable s) {}

   @Override    
   public void beforeTextChanged(CharSequence s, int start,
     int count, int after) {
   }

   @Override    
   public void onTextChanged(CharSequence s, int start,
     int before, int count) {
      if(s.length() != 0)
        IsEditTextChanged = true;
        // your desired logic here?
   }
  });

Fragment BackPressed thread

Upvotes: 0

dtx12
dtx12

Reputation: 4488

You may create interface which has method onBackPressed(your fragment should implement this interface), then override method onBackPressed in your activity, then find your fragment by tag or id -> cast to this interface and call this method.

Upvotes: 0

Related Questions