• Android -- Handling back button press Inside Fragments


    干货(1)

    首先创建一个抽象类BackHandledFragment,该类有一个抽象方法onBackPressed(),所有BackHandledFragment的子类在onBackPressed方法中处理各自对Back事件的消费逻辑。onBackPressed返回布尔值,宿主FragmentActivity将会根据该方法的返回值判断子Fragment是否有消费Back事件。此外,宿主FragmentActivity还会保持一份当前Fragment的引用,当用户按下Back键时,宿主Activity会判断当前Fragment是否需要消费该事件,如果没有Fragment消费才会自己消费。

    public abstract class BackHandledFragment extends Fragment {  
      
        protected BackHandledInterface mBackHandledInterface;  
          
        /** 
         * 所有继承BackHandledFragment的子类都将在这个方法中实现物理Back键按下后的逻辑 
         * FragmentActivity捕捉到物理返回键点击事件后会首先询问Fragment是否消费该事件 
         * 如果没有Fragment消息时FragmentActivity自己才会消费该事件 
         */  
        protected abstract boolean onBackPressed();  
          
        @Override  
        public void onCreate(Bundle savedInstanceState) {  
            super.onCreate(savedInstanceState);  
            if(!(getActivity() instanceof BackHandledInterface)){  
                throw new ClassCastException("Hosting Activity must implement BackHandledInterface");  
            }else{  
                this.mBackHandledInterface = (BackHandledInterface)getActivity();  
            }  
        }  
          
        @Override  
        public void onStart() {  
            super.onStart();  
            //告诉FragmentActivity,当前Fragment在栈顶  
            mBackHandledInterface.setSelectedFragment(this);  
        }  
          
    }

    宿主FragmentActivity需要继承BackHandledIntegerface,子Fragment会通过该接口告诉宿主FragmentActivity自己是当前屏幕可见的Fragment。

    public interface BackHandledInterface {  
        public abstract void setSelectedFragment(BackHandledFragment selectedFragment);  
    }

    所以在Fragment的onCreate中会判断宿主FragmentActivity是否已继承了该接口。在Fragment的onStart()方法中就会调用该接口告诉宿主FragmentActivity自己是当前屏幕可见的Fragment。
    宿主FragmentActivity就可以在onBackPressed()方法中对Back事件进行判断处理了。

    public class MainActivity extends FragmentActivity implements BackHandledInterface{  
      
        private BackHandledFragment mBackHandedFragment;  
        private boolean hadIntercept;  
      
        @Override  
        public void setSelectedFragment(BackHandledFragment selectedFragment) {  
            this.mBackHandedFragment = selectedFragment;  
        }  
          
        @Override  
        public void onBackPressed() {  
            if(mBackHandedFragment == null || !mBackHandedFragment.onBackPressed()){  
                if(getSupportFragmentManager().getBackStackEntryCount() == 0){  
                    super.onBackPressed();  
                }else{  
                    getSupportFragmentManager().popBackStack();  
                }  
            }  
        }  
    }

    干货(2)

    在Fragment的onResume中通过View去监听。(要注意setFocusableInTouchMode()和requestFocus())

    @Override
    public void onResume() {
    
        super.onResume();
    
        getView().setFocusableInTouchMode(true);
        getView().requestFocus();
        getView().setOnKeyListener(new View.OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
    
                if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
    
                    // handle back button
    
                    return true;
    
                }
    
                return false;
            }
        });
    }

    我是天王盖地虎的分割线

    参考:http://vinsol.com/blog/2014/10/01/handling-back-button-press-inside-fragments/

    http://stackoverflow.com/questions/22552958/handling-back-press-when-using-fragments-in-android

  • 相关阅读:
    Visual Studio 快捷键
    C#编程使用Managed Wifi API连接无线SSID
    C#两种创建快捷方式的方法
    COJ 1059
    [Unity3D]Unity3D游戏开发之鼠标滚轮实现放大缩小
    cloudstack4.4新增功能前瞻
    hdu 4635 Strongly connected (tarjan)
    freemarker声明变量
    Android 4.4 Kitkat Phone工作流程浅析(六)__InCallActivity显示更新流程
    评教,路上的风景更美
  • 原文地址:https://www.cnblogs.com/yydcdut/p/4471936.html
Copyright © 2020-2023  润新知