关于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)