Search code examples
javaandroidinterfaceonbackpressed

override onBackPressed from interface


I use many times in my app the onBackPressed method.

I had like to override it so it will check every time if the activity is the root activity in order to show a dialog saying "are you sure you want to exit?"

Since I use it many times in my app, I thought to create an interface and place it there.

Im new with working with interfaces but I trying the following:

public interface App_Interfaces {

    void BackPressed(Context contect);

}

class customBackPressed implements App_Interfaces{
    @Override
    public void BackPressed(Context context) {

        if(isTaskRoot()){

            final Dialog dialog = new Dialog( context );
            dialog.setContentView( R.layout.are_you_sure );
            dialog.getWindow().setBackgroundDrawable( new ColorDrawable( Color.TRANSPARENT ) );
            
            if (!((Activity) context).isFinishing()) {
                dialog.show();
            }
            
        }else{
            super.onBackPressed();
        }
    }

}

My problem is that I get errors on isTaskRoot and onBackPressed saying the following:

Cannot resolve method 'isTaskRoot' in 'customBackPressed'

Cannot resolve method 'onBackPressed' in 'Object'

Can someone please explain to me how to work to solve this problems?

Thank you


Solution

  • You shouldn't represent behavior by interface method, you should represent it by whole interface.

    public interface OnBackPressedListener {
        void onBackPressedEvent()
    }
    

    And then, you should attach this behavior to the activity/fragment/view root. For example:

    public class MyActivity extends Activity implements OnBackPressedListener {
    
        // Initialize your activity's fields
        
        private boolean isTaskRoot() {
        // implement your task root method
        }
    
        @Override
        public void onBackPressed() { // This method is provided by activity "from the box".
            onBackPressedEvent();
        }
    
        @Override
        public void onBackPressedEvent() {
            if(isTaskRoot()) {
                final Dialog dialog = new Dialog(this);
                dialog.setContentView( R.layout.are_you_sure );
                dialog.getWindow().setBackgroundDrawable( new ColorDrawable( Color.TRANSPARENT ) );
            
                if (!this.isFinishing()) {
                    dialog.show();
                }
            }   
        }
    }
    

    Note that your onBackPressedListener interface should NOT depend on any other methods, behaviors. Its main purpose is to provide an ability to mark the class as the class, which can react to onBackPressed event.

    One of the possible usages is to inherit your fragments from onBackPressedListener and then call their onBackPressedEvent methods when parent Activity is notified that back button was pressed.

    @Override
    public void onBackPressed() {
        // ...
        if (currFragment instanceof onBackPressedListener) {
            currFragment.onBackPressedEvent();
        }
        // ...
    }
    

    UPD: If you want to provide ready-to-use behavior for all classes inheriting onBackPressedListener you can use default keyword to create default interface method.

    public interface onBackPressedListener() {
        boolean isTaskRoot()
    
        default void onBackPressedEvent() {
            // Your implementation. 
            // It should not contain calls of methods, which are not presented by this interface. 
            if (isTaskRoot()) // ...
        }
    }
    

    OR you can create BaseActivity class, in which you will override onBackPressedEvent from interface

    public class BaseActivity extends Activity implements OnBackPressedListener { 
        @Override
        public void onBackPressed() {
        ...
        }
    }
    

    And then you inherit your activities from it public class MyActivity extends BaseActivity { ... }