• 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

  • 相关阅读:
    什么是系统打开文件表?
    为什么Unix只允许对非目录文件实行勾链?
    在Unix系统中,主存索引节点和辅存索引节点从内容上比较有什么不同,为什么要设置主存索引节点?
    Unix系统的文件目录项的内容是什么,这样处理的好处是什么?
    Unix系统使用的地址索引结构有什么特点?
    Unix文件系统的主要特点是什么?
    什么是打开文件操作,什么关闭文件操作,引入这两个操作的目的是什么?
    在非洲运营互联网系统-基础建设
    这一年在非洲(4年一轮回总结完结)
    4年一轮回(后半部)
  • 原文地址:https://www.cnblogs.com/yydcdut/p/4471936.html
Copyright © 2020-2023  润新知