关于Fragment使用的一些见解

 Fragment的概念相信大家已经很熟悉了,目前经常使用的Fragment有两种,一种是 android.app 包下的 Fragment,一种是 android.support.v4.app 包下的 Fragment,这两种Fragment有什么区别呢?简单来说,第一种是专为3.0以上的系统设计的,而第二种是为了3.0以下的系统适配用的,那么在应用中该采用哪种Fragment呢?这个就要看你开发的应用的支持系统版本来看了,如果你开发的应用不需要适配4.0一下的系统,那么第一种是不二选择。我一般采用的是第二种Fragment,一直以来,开发app时,使用Activity都会继承自我自定义的Activity类,而这个Activity我已经把Fragment展示逻辑继承了进去,下面就来分享下我使用Fragment的一些经验。

下面来看一下我自定义的Fragment的代码:

public abstract class MyFragment extends Fragment{  

    private MyFragment parent;  
    private MyFragment myFragment;  
    private List <String> myFragmentList;  

    @Override  
    public void onCreate(Bundle savedInstanceState) {         
        super.onCreate(savedInstanceState);  
        myFragmentList = new ArrayList<String>();  
    }  


    public MyFragment getParentMyFragment(){  
        if(parent == null)  
            return null;  
        return parent;  
    }  

    public void showFragments(MyFragment myFragment,int frameLayoutId){  

        FragmentTransaction transaction = getFragmentManager().beginTransaction();  
        hideFragments(transaction);  

        if(!myFragmentList.contains(myFragment.getTAG())){  
            transaction.add(frameLayoutId,myFragment, myFragment.getTAG());  
            myFragmentList.add(myFragment.getTAG());  
        }else{  
            transaction.show(myFragment);  
        }  
        this.myFragment=myFragment;  
        transaction.commit();  
    }  

    public void hideFragments(FragmentTransaction transaction){  
        if(transaction!=null&&myFragment!=null){  
            transaction.hide(myFragment);  
        }  
    }  

    public int getFrameLayoutId(){  
        return 0;  
    }  

    public abstract String getTAG();  

    public abstract boolean onBackPressed();  

    public void showToast(String msg){  
        if(getActivity()!=null&msg!=null)  
            Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();       
    }  

    public boolean onKeyDown(int keyCode, KeyEvent event){  
        switch(keyCode){  
        case KeyEvent.KEYCODE_BACK:  
            return onBackPressed();  
        }  
        return false;  
    }  

    public void onDisplay(){  

    }  
}  

再来看下我的自定义Activity类

public class MyActivity extends FragmentActivity{  

    private List <String> myFragmentList;  
    private MyFragment myFragment;  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        //changeLanguage(); 
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);  //去掉标题栏 
        myFragmentList = new ArrayList<String>();  
        ImageLoaderHelper.initImageLoader(this);  
        MyApplication.onActivityStart(this);  
    }  


public void showFragments(final MyFragment myFragment,int frameLayoutId){  


        FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();  
        hideFragments(transaction);  
        if(!myFragmentList.contains(myFragment.getTAG())){  
            transaction.add(frameLayoutId,myFragment);  
            myFragmentList.add(myFragment.getTAG());  
        }else{  
            transaction.show(myFragment);  
        }     
        this.myFragment = myFragment;  
        transaction.commit();  
        mHandler.post(mRun);  
    }  


    Handler mHandler = new Handler(new Handler.Callback() {  

        @Override  
        public boolean handleMessage(Message msg) {  
            myFragment.onDisplay();  
            return false;  
        }  
    });  

    Runnable mRun = new Runnable() {      
        @Override  
        public void run() {  
            if(myFragment.isResumed()){  
                mHandler.sendEmptyMessage(0);  
            }else{  
                mHandler.postDelayed(mRun, 500);  
            }  
        }  
    };  

    public void hideFragments(FragmentTransaction transaction){  
        if(transaction!=null && myFragment!=null){  
            transaction.hide(myFragment);  
        }  
    }  

}  

 上面两个类是我写的一组简单的用来显示Activity的例子,先来看MyFragment中,有个getTAG()方法,是用来获取Fragment的唯一标识的,返回的是该Fragment的完整类名,在Activity中切换时用来辨别子Fragment的,当然有系统自带的方法也可以,但是有一个局限性就是无法获取一个Activity中已加载的全部Fragment。这里,我在Activity中使用一个List来存放已存在的Fragment,这样就可以随时查看已加载的Fragment,调试的时候也很方便。

 显示Fragment我采用的是FragmentTransaction的add()与show()方法,当然也可以采用add()与replace()方法,但是这种方法会导致每次切换Fragment的时候都要重新create(),有时候我们需要像导航栏那样切换页面,而又不想每次都重新加载时,就需要add()与show()来配合使用了。

 在Fragment类中,我定义了一个onDisplay()空方法,这个方法是用来切换Fragment且当该Fragment处于可见状态时使用的,为什么要加这样一个类呢?我通过实验,发现当一个Fragment已经存在于Activity并且处于隐藏状态时,当它再次显示时(onShow()),onStart(),onResume() 方法等统统不会被调用,而这时候如果当这个Fragment初次显示或是再次显示时,我们需要一个触发事件,就可以通过onDisplay()来实现,它的逻辑其实挺简单的,就是当这个Fragment将要被FragmentTransaction.onShow()或onAdd()时,调用一下onDisplay()方法就可以了。这个地方有个有趣的事情,当我们用new方法创建一个Fragment时,Fragment的onCreate()方法是不会被首先调用的,当FragmentTransaction.onShow()或onAdd()这个Fragment时,Fragment才开始正常工作,这个可能是supportV4Fragmen(第二种Fragment)t的特性吧,AppFragment(第一种Fragment)这里我没有做过测试。但当刚刚触发ragmentTransaction.onShow()或onAdd()方法时就调用Fragment.onDisplay()方法是不可取的,因为Fragment的onCreate-onResume()方法需要一小段时间,而Fragment有个isResume()方法可以获取该Fragment是否已经加载完毕,这里我是用Handler与线程来获取Fragment是否已经加载完毕,当Fragment加载完毕时,再调用自己定义的onDisplay()方法,当然,如果该Fragment已经存在于Activity中时,这里第一次调用Fragment.isResume()就会返回true。

 这个是我关于Fragment使用的一些小见解,如果大家有什么很好的方法也可以共同交流下!

你可能感兴趣的:(android,Fragment)