下面来看一下我自定义的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使用的一些小见解,如果大家有什么很好的方法也可以共同交流下!