首先來看一下android.support.v4.app.Fragment和android.app.Fragment這兩包的區別:
1.最低支持版本不同
android.app.Fragment 兼容的最低版本是android:minSdkVersion="11" 即3.0版
android.support.v4.app.Fragment 兼容的最低版本是android:minSdkVersion="4" 即1.6版
2.需要導jar包
fragment 在定義的時候,要導入的包不同
android.support.v4.app.Fragment 需要引入包android-support-v4.jar
android.app.Fragment 需要導入的是android-app.jar
3.繼承的父類不同,在fragmentManager 在Activity中取的方法不同
android.support.v4.app.Fragment使用 fragmentManager=getSupportFragmentManager()獲得 ,并且當前的類必須繼成FragmentActivity
android.app.Fragment使用 fragmentManager=getFragmentManager() 獲得 ,繼承Activity即可。
4.<fragment>標簽問題
app.fragment和v4.fragment都是可以使用<fragment>標簽。
只是在使用的時候如果是app.fragment則沒有什么特殊的地方繼承Activity即可。
當v4.fragment使用<fragment>標簽的時候就要特別注意了:
當這個Activity的布局中有<fragment>標簽的時候,這個Activity必須繼承FragmentActivity,否則就會報錯。
關于這個<fragment>標簽的問題要著重強調一下,app.fragment是可以使用<fragment>標簽的,很多網上都得文章說是不支持,是錯誤的。
綜上所述,在安卓4.4 5.0 乃至6.0系統的今天,源碼下的Fragment可以使用了。也許你會說,閑著沒事改V4包下的Fragment干嘛啊,沒辦法這都是被被逼的啊,產品需求。。。如圖:
原先的關注按鈕直接跳轉一個Activity展示別的頁面,而現在需求是點擊選擇展示成另一個界面,并且下面的四個按鈕是仍然展示的。
很顯然原先的Activity現在不可行了,只能是Fragment了。老大找了開源的項目,也是Fragment翻轉的,核心的代碼就是:
getFragmentManager() .beginTransaction().setCustomAnimations(
R.animator.card_flip_horizontal_right_in,
R.animator.card_flip_horizontal_left_out,
R.animator.card_flip_horizontal_left_in,
R.animator.card_flip_horizontal_right_out)
.replace(R.id.container, attentionFragment)
.commit();
在Values文件夾下新建animator文件夾置代碼里面的四個動畫文件,內容如圖所示:
萬事具備只欠東風,程序運行點擊按鈕,程序就崩潰了。報錯為:
Unknown animation name: objectAnimator異常,谷歌搜索答案很多,終于找到一個靠譜的,網址如下
http://blog.csdn.net/xyz_fly/article/details/36179515
總結一下就是,在使用V4包中Fragment時,使用的切換動畫效果,其動畫文件中不能包含objectAnimator,Animator這類標簽。如果必須要使用,請將工程中使用的V4包中Fragment相關類,換成源碼中的Fragment相關類。
意思很明確,就是V4包下 的Fragment不支持屬性動畫,只支持位移動畫,要做旋轉的話只能用源碼中的Fragment。。。。仔細看了看三方代碼里面用的是android.app.Fragment。
原先項目中的Fragment的初始化時放在XML的<fragment>標簽中的,一開始上網搜索經不權威人士的文章誤導,以為android.app.Fragment不支持<fragment>標簽,這樣一改就改大發了,遂想另一個辦法:
不對Fragment進行屬性動畫設置,改為設置成替換的布局的屬性動畫,即對布局進行單獨的屬性動畫設置:
ObjectAnimator ra = ObjectAnimator.ofFloat(view, "rotationY", 0, 360);
ra.setDuration(1500);
ra.start();
效果的話就不盡人意了,可以理解為空中旋轉一周,體驗很差,我們的要求是一般旋轉180度就好,改為180度后,旋轉話畫面直接就直接倒置了,誰讓是對布局進行的動畫呢。這一方案也破滅了。。。
后來發現android.app.Fragment也支持<fragment>標簽了,這告訴我們要理論聯系實際啊。要把項目里的V4包下的Fragment全部換成android.app.Fragment,因為項目里面沒有做一個基類的BaseFragment,這工作量你懂得。。。 不光Fragment的引用要改,
getSupportFragmentManager()也要改為getFragmentManager(),少年你以為這些就夠了嗎?后面還有更大的坑呢。。。
改到FragmentPageAdapter的時候就出問題了,因為源碼里面沒有這個類。。。沒辦法,繼續谷歌,找到如下文章:
http://www.xiufm.com/thread-14680-1-1.html
大體意思就是,原先改的時候就是在V4包下的FragmentPageAdapter里面修改getSupportFragmentManager()為getFragmentManager(),不過后來谷歌意識到了這個問題在V13包里面添加了這個FragmentPageAdapter類,也可以直接在build里面添加V13包的引用,但是為了一個類把包全引用有點浪費,不如直接在源碼里面直接把相對應的類及其相關的都拷貝出來放到代碼里面。
期間引用的三方項目里面也有引用V4包FragmentPageAdapter的地方沒辦法,去看源碼,改依賴為直接粘貼代碼到項目中。
另一個展示的頁面如下布局:
這是一個Fragment,里面用的是Viewpager,欄目跟健康號可以來回切換,上面掛載的是兩個Fragment,經過上面的操作,動畫可以完美運行了,但是當第二次進入這個頁面的時候,掛載的Fragment的數據不展示了,挺費解的,遂谷歌一番。找到如下網頁:
http://blog.csdn.net/u014452224/article/details/45920315?spm=5176.8246799.blogcont.4.nDyPzm
大體意思就是第二次加載的時候重復調用了onCreateView()這個方法,重新new了一個pageadapter導致子fragment不顯示,原因的話現在還有點費解,先解決問題上代碼,在主Fragment里面做如下操作
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view != null) {
unbinder = ButterKnife.bind(this, view);
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) {
parent.removeView(view);
}
return view;
}
view = inflater.inflate(R.layout.activity_my_attention, null);
unbinder = ButterKnife.bind(this, view);
initView();
return view;
}
請注意我里面用的是ButterKnife來初始化話控件,
unbinder = ButterKnife.bind(this, view);
這句代碼必須放在每個判斷語句里面,不然的話會報錯。
這樣的話我們就完成了Fragment的替換,真是一波三折啊,動畫效果的話也完美實現
前人鋪路,后人共勉啊。。。。