http://blog.csdn.net/way_ping_li/article/details/16890419

http://blog.csdn.net/way_ping_li/article/details/16890419

http://blog.csdn.net/way_ping_li/article/details/16890419

http://blog.csdn.net/way_ping_li/article/details/16890419




分类:Android 4339人阅读 评论(20) 收藏 举报

源码奉上:http://download.csdn.net/detail/weidi1989/6595979

新版的Android版百度云界面效果非常炫,给人焕然一新的感觉,如下图所示。

其实仔细研究,会发现也并不是那么复杂:

1.整个界面主容器是一个ViewPager,只是在左下角有一个切换的Button。

2.ViewPager有两个界面,由Fragment实现,并且加入了ViewPager切换动画。

3.ViewPager的两个Fragment都是Tab风格,点击底部Tab又会呈现不同的子Fragment。

其实,就是Fragment用得比较灵活,效果优化得比较好。

下面是本人模仿过的效果:



基本的效果是差不多的,只是那个“传输列表”的Fragment没有再加3个子Fragment了,但是原理是一样的,我这里就步赘述了。


下面来看看代码分析:

1.整个例子只有一个Activity,即MainActivity,注释算是比较多的了,有兴趣的可以看看:

[java] view plain copy
  1. /**
  2. *仿百度云主界面框架
  3. *
  4. *注意继承自FragmentActivity,才会有getSupportFragmentManager()函数
  5. *
  6. *@authorway
  7. *
  8. */
  9. publicclassMainActivityextendsFragmentActivityimplements
  10. OnPageChangeListener{
  11. privatestaticfinalintNUM_PAGES=2;//总页数,2个Fragment
  12. publicstaticfinalintPAGE_PERSONAL=0;//第一个界面ID
  13. publicstaticfinalintPAGE_FILE_SYSTEM=1;//第二个界面ID
  14. privatestaticfinalintROTATE_ANIM_DURATION=300;//左下角切换动画的时间
  15. privateintmCurPage=0;//当前页
  16. privateViewPagermViewPager;//父容器由一个ViewPager实现
  17. privatePagerAdaptermPagerAdapter;//ViewPager适配器
  18. privateImageButtonmSwitchImageButton;//左下角切换Paper按钮
  19. privateImageViewmAnimView;//动画View
  20. privateAnimationmRotateRightAnim;//向右旋转动画
  21. privateAnimationmRotateLeftAnim;//向左旋转动画
  22. @Override
  23. protectedvoidonCreate(BundlesavedInstanceState){
  24. super.onCreate(savedInstanceState);
  25. setContentView(R.layout.activity_main);
  26. initView();
  27. initAnim();
  28. }
  29. /**
  30. *初始化Views
  31. */
  32. privatevoidinitView(){
  33. mAnimView=(ImageView)findViewById(R.id.anim_icon);
  34. mSwitchImageButton=(ImageButton)findViewById(R.id.switch_btn);
  35. mViewPager=(ViewPager)findViewById(R.id.vp_pager);
  36. mPagerAdapter=newScreenSlidePagerAdapter(getSupportFragmentManager());
  37. mViewPager.setAdapter(mPagerAdapter);
  38. mCurPage=PAGE_FILE_SYSTEM;
  39. mViewPager.setCurrentItem(mCurPage);
  40. mViewPager.setOnPageChangeListener(this);
  41. mViewPager.setPageTransformer(true,newDepthPageTransformer());
  42. }
  43. /**
  44. *初始化动画
  45. */
  46. privatevoidinitAnim(){
  47. mRotateRightAnim=newRotateAnimation(0.0f,180.0f,
  48. Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,
  49. 0.5f);
  50. mRotateRightAnim.setDuration(ROTATE_ANIM_DURATION);
  51. mRotateRightAnim.setFillAfter(true);
  52. mRotateLeftAnim=newRotateAnimation(180.0f,0.0f,
  53. Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,
  54. 0.5f);
  55. mRotateLeftAnim.setDuration(ROTATE_ANIM_DURATION);
  56. mRotateLeftAnim.setFillAfter(true);
  57. mRotateRightAnim.setAnimationListener(newAnimationListener(){
  58. @Override
  59. publicvoidonAnimationStart(Animationanimation){
  60. }
  61. @Override
  62. publicvoidonAnimationRepeat(Animationanimation){
  63. }
  64. @Override
  65. publicvoidonAnimationEnd(Animationanimation){
  66. mAnimView.clearAnimation();
  67. mAnimView.setVisibility(View.GONE);
  68. mSwitchImageButton.setVisibility(View.VISIBLE);
  69. mSwitchImageButton
  70. .setImageResource(R.drawable.ic_viewpager_switch_feedlist);
  71. }
  72. });
  73. mRotateLeftAnim.setAnimationListener(newAnimationListener(){
  74. @Override
  75. publicvoidonAnimationStart(Animationanimation){
  76. }
  77. @Override
  78. publicvoidonAnimationRepeat(Animationanimation){
  79. }
  80. @Override
  81. publicvoidonAnimationEnd(Animationanimation){
  82. mAnimView.clearAnimation();
  83. mAnimView.setVisibility(View.GONE);
  84. mSwitchImageButton.setVisibility(View.VISIBLE);
  85. mSwitchImageButton
  86. .setImageResource(R.drawable.ic_viewpager_switch_filesystem);
  87. }
  88. });
  89. }
  90. /**
  91. *点击左下角切换按钮的事件处理
  92. *
  93. *需要事先在布局中声明android:onClick="switchPage"
  94. *
  95. *@paramview
  96. */
  97. publicvoidswitchPage(Viewview){
  98. if(mCurPage==PAGE_FILE_SYSTEM){
  99. mViewPager.setCurrentItem(PAGE_PERSONAL);
  100. }elseif(mCurPage==PAGE_PERSONAL){
  101. mViewPager.setCurrentItem(PAGE_FILE_SYSTEM);
  102. }
  103. }
  104. /**
  105. *开始动画
  106. *
  107. *@parampager
  108. *当前页
  109. */
  110. privatevoidstartAmin(intpager){
  111. if(pager==PAGE_FILE_SYSTEM){
  112. mSwitchImageButton.setVisibility(View.INVISIBLE);
  113. mAnimView.setVisibility(View.VISIBLE);
  114. mAnimView.startAnimation(mRotateLeftAnim);
  115. }elseif(pager==PAGE_PERSONAL){
  116. mSwitchImageButton.setVisibility(View.INVISIBLE);
  117. mAnimView.setVisibility(View.VISIBLE);
  118. mAnimView.startAnimation(mRotateRightAnim);
  119. }
  120. mCurPage=pager;
  121. }
  122. /**
  123. *ViewPager的适配器,我这里只是一个例子,就作为内部类了。
  124. *
  125. *@authorway
  126. *
  127. */
  128. privateclassScreenSlidePagerAdapterextendsFragmentPagerAdapter{
  129. publicScreenSlidePagerAdapter(FragmentManagerfm){
  130. super(fm);
  131. }
  132. /**
  133. *这里可以将Fragment缓存一下,减少加载次数,提高用户体验,我未作处理
  134. */
  135. @Override
  136. publicFragmentgetItem(intposition){
  137. switch(position){
  138. casePAGE_PERSONAL:
  139. returnnewMainPersonalFragment();
  140. casePAGE_FILE_SYSTEM:
  141. returnnewMainFileSystemFragment();
  142. default:
  143. returnnull;
  144. }
  145. }
  146. @Override
  147. publicintgetCount(){
  148. returnNUM_PAGES;
  149. }
  150. }
  151. @Override
  152. publicvoidonPageScrollStateChanged(intarg0){
  153. }
  154. @Override
  155. publicvoidonPageScrolled(intarg0,floatarg1,intarg2){
  156. }
  157. @Override
  158. publicvoidonPageSelected(intarg0){
  159. startAmin(arg0);//手势滑动ViewPager时,也要播放一下动画
  160. }
  161. }


接下来是ViewPager的子Fragment,由于两个Fragment的原理是差不多的,我这里就只贴出一个MainFileSystemFragment的代码了,这里的重点是点击对应Tab按钮切换Fragment,没有过多的使用缓存,待优化:

[java] view plain copy
  1. /**
  2. *文件系统的Fragment
  3. *
  4. *由于与另一个Fragment是对称的,我就只注释此类了,敬请谅解!
  5. *
  6. *@authorway
  7. *
  8. */
  9. publicclassMainFileSystemFragmentextendsFragmentimplements
  10. OnCheckedChangeListener{
  11. privateFragmentManagermFragmentManager;//Fragment管理类
  12. privateFragmentTransactionmFragmentTransaction;
  13. privateStringmCurrentFragmentTag;//当前显示的二级Fragment标签
  14. //底部三个Tab的按钮
  15. RadioButtonmFileListRadioButton;
  16. RadioButtonmToolsRadioButton;
  17. RadioButtonmTransFileRadioButton;
  18. @Override
  19. publicvoidonCreate(BundlesavedInstanceState){
  20. super.onCreate(savedInstanceState);
  21. //初始化FragmentManager,再次提醒需要Activity继承FragmentActivity
  22. mFragmentManager=getActivity().getSupportFragmentManager();
  23. }
  24. @Override
  25. publicvoidonResume(){
  26. super.onResume();
  27. //默认显示Tab为第一个,其实可以记住一下状态onSaveInstanceState,我为简洁未作处理
  28. onCheckedChanged(mFileListRadioButton,true);
  29. mFileListRadioButton.setChecked(true);
  30. mCurrentFragmentTag=getActivity().getResources().getString(
  31. R.string.tab_filelist);
  32. }
  33. @Override
  34. publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
  35. BundlesavedInstanceState){
  36. returninflater.inflate(R.layout.main_filesystem,container,false);
  37. }
  38. @Override
  39. publicvoidonViewCreated(Viewview,BundlesavedInstanceState){
  40. super.onViewCreated(view,savedInstanceState);
  41. //findviews和setAction
  42. mFileListRadioButton=(RadioButton)view
  43. .findViewById(R.id.rb_filelist);
  44. mToolsRadioButton=(RadioButton)view.findViewById(R.id.rb_tools);
  45. mTransFileRadioButton=(RadioButton)view
  46. .findViewById(R.id.rb_transferlist_right);
  47. mFileListRadioButton.setOnCheckedChangeListener(this);
  48. mToolsRadioButton.setOnCheckedChangeListener(this);
  49. mTransFileRadioButton.setOnCheckedChangeListener(this);
  50. }
  51. /**
  52. *初始化FragmentTransaction
  53. *
  54. *@returnFragmentTransaction实例
  55. */
  56. protectedFragmentTransactionensureTransaction(){
  57. if(mFragmentTransaction==null){
  58. mFragmentTransaction=mFragmentManager.beginTransaction();
  59. mFragmentTransaction
  60. .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
  61. }
  62. returnmFragmentTransaction;
  63. }
  64. /**
  65. *根据tag获取对应的Fragment
  66. *
  67. *@paramtag
  68. *标签
  69. *@return对应tag的Fragment实例
  70. */
  71. privateFragmentgetFragment(Stringtag){
  72. Fragmentf=mFragmentManager.findFragmentByTag(tag);
  73. if(f==null){
  74. //在这里判断tag,不同则实例化对应的fragment,
  75. f=SampleFragment.newInstance(tag,MainActivity.PAGE_FILE_SYSTEM);
  76. }
  77. returnf;
  78. }
  79. /**
  80. *将对应的fragment添加到容器中
  81. *
  82. *@paramlayout
  83. *父容器
  84. *@paramf
  85. *fragment实例
  86. *@paramtag
  87. *标签
  88. */
  89. protectedvoidattachFragment(intlayout,Fragmentf,Stringtag){
  90. if(f!=null){
  91. if(f.isDetached()){//如果当前fragment只是隐藏,则显示出来
  92. ensureTransaction();
  93. mFragmentTransaction.attach(f);
  94. }elseif(!f.isAdded()){//如果当前fragment没有添加到容器中,则先要添加到容器中
  95. ensureTransaction();
  96. mFragmentTransaction.add(layout,f,tag);
  97. }
  98. }
  99. }
  100. /**
  101. *将对应fragment隐藏
  102. *
  103. *@paramf
  104. *需要隐藏的fragment
  105. */
  106. protectedvoiddetachFragment(Fragmentf){
  107. if(f!=null&&!f.isDetached()){
  108. ensureTransaction();
  109. mFragmentTransaction.detach(f);
  110. }
  111. }
  112. /**
  113. *保存fragment状态,添加或隐藏fragment最后都需要调用此函数
  114. */
  115. protectedvoidcommitTransactions(){
  116. if(mFragmentTransaction!=null&&!mFragmentTransaction.isEmpty()){
  117. mFragmentTransaction.commit();
  118. mFragmentTransaction=null;
  119. }
  120. }
  121. /**
  122. *点击不同的Tab切换fragment
  123. *
  124. *@paramtag
  125. */
  126. privatevoidswitchFragmen(Stringtag){
  127. if(TextUtils.equals(mCurrentFragmentTag,tag))
  128. return;
  129. if(mCurrentFragmentTag!=null)
  130. detachFragment(getFragment(mCurrentFragmentTag));
  131. attachFragment(R.id.sliding_layer_frame_right,getFragment(tag),tag);
  132. mCurrentFragmentTag=tag;
  133. commitTransactions();
  134. }
  135. @Override
  136. publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked){
  137. if(!isChecked)
  138. return;
  139. Log.i("way","mCurrentFragmentTag="+mCurrentFragmentTag);
  140. switch(buttonView.getId()){
  141. caseR.id.rb_filelist:
  142. switchFragmen(getActivity().getString(R.string.tab_filelist));
  143. break;
  144. caseR.id.rb_tools:
  145. switchFragmen(getActivity().getString(R.string.tab_tools));
  146. break;
  147. caseR.id.rb_transferlist_right:
  148. switchFragmen(getActivity().getString(R.string.tab_transferlist));
  149. break;
  150. default:
  151. break;
  152. }
  153. }
  154. }

MainFileSystemFragment对应的布局,main_filesystem.xml,使用RadioGroup和RadioButton实现Tab。

[html] view plain copy
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:background="@color/black">
  6. <RadioGroup
  7. android:id="@+id/rg_tabs"
  8. android:layout_width="fill_parent"
  9. android:layout_height="wrap_content"
  10. android:layout_alignParentBottom="true"
  11. android:layout_toRightOf="@android:id/icon"
  12. android:background="@drawable/tabbar_background"
  13. android:gravity="bottom"
  14. android:orientation="horizontal"
  15. android:paddingBottom="0.0dip"
  16. android:paddingLeft="50.0dip"
  17. android:paddingRight="0.0dip"
  18. android:paddingTop="4.0dip">
  19. <RadioButton
  20. android:id="@+id/rb_filelist"
  21. style="@style/NetDisk.Unified.Smaller.Blue2TabBarGray"
  22. android:layout_width="fill_parent"
  23. android:layout_height="fill_parent"
  24. android:layout_weight="1.0"
  25. android:background="@android:color/transparent"
  26. android:button="@null"
  27. android:drawableTop="@drawable/tab_filelist"
  28. android:gravity="center"
  29. android:paddingTop="4.0dip"
  30. android:text="@string/tab_filelist"/>
  31. <RadioButton
  32. android:id="@+id/rb_tools"
  33. style="@style/NetDisk.Unified.Smaller.Blue2TabBarGray"
  34. android:layout_width="fill_parent"
  35. android:layout_height="fill_parent"
  36. android:layout_weight="1.0"
  37. android:background="@android:color/transparent"
  38. android:button="@null"
  39. android:drawableTop="@drawable/tab_tools"
  40. android:gravity="center"
  41. android:paddingTop="4.0dip"
  42. android:text="@string/tab_tools"/>
  43. <RadioButton
  44. android:id="@+id/rb_transferlist_right"
  45. style="@style/NetDisk.Unified.Smaller.Blue2TabBarGray"
  46. android:layout_width="fill_parent"
  47. android:layout_height="fill_parent"
  48. android:layout_weight="1.0"
  49. android:background="@android:color/transparent"
  50. android:button="@null"
  51. android:drawableTop="@drawable/tab_transferlist"
  52. android:gravity="center"
  53. android:paddingTop="4.0dip"
  54. android:text="@string/tab_transferlist"/>
  55. </RadioGroup>
  56. <FrameLayout
  57. android:id="@+id/sliding_layer_frame_right"
  58. android:layout_width="match_parent"
  59. android:layout_height="match_parent"
  60. android:layout_above="@id/rg_tabs"
  61. android:background="@color/black"/>
  62. <ImageView
  63. android:id="@+id/iv_guide"
  64. android:layout_width="wrap_content"
  65. android:layout_height="wrap_content"
  66. android:layout_alignParentBottom="true"
  67. android:layout_marginBottom="169.0dip"
  68. android:src="@drawable/ic_swipe_guide_right"
  69. android:visibility="gone"/>
  70. </RelativeLayout>

最后是每个Tab的Fragment了,由于我这里仅仅是一个例子,所以6个Tab对应的Fragment都是使用的此Fragment,只是在切换不同的Tab时,改变了标题栏名称和背景颜色而已:

[java] view plain copy
  1. /**
  2. *每个Tab中的fragment
  3. *
  4. *@authorway
  5. *
  6. */
  7. publicclassSampleFragmentextendsFragment{
  8. privatestaticfinalStringARG_TEXT="text";
  9. privatestaticfinalStringARG_PAGER="pager";
  10. publicstaticSampleFragmentnewInstance(Stringtext,intpager){
  11. SampleFragmentf=newSampleFragment();
  12. Bundleargs=newBundle();
  13. args.putString(ARG_TEXT,text);
  14. args.putInt(ARG_PAGER,pager);
  15. f.setArguments(args);
  16. returnf;
  17. }
  18. @Override
  19. publicViewonCreateView(LayoutInflaterinflater,ViewGroupcontainer,
  20. BundlesavedInstanceState){
  21. Viewv=inflater.inflate(R.layout.fragment_sample,container,false);
  22. ((TextView)v.findViewById(R.id.text)).setText(getArguments()
  23. .getString(ARG_TEXT));
  24. TextViewtitle=(TextView)v.findViewById(R.id.title);
  25. title.setText(getArguments().getString(ARG_TEXT));
  26. intpager=getArguments().getInt(ARG_PAGER);
  27. if(pager==MainActivity.PAGE_FILE_SYSTEM)//如果是文件系统的Fragment
  28. title.setBackgroundColor(Color.parseColor("#ff3995e3"));//蓝色标题栏
  29. else
  30. title.setBackgroundColor(Color.parseColor("#ffde4125"));
  31. returnv;
  32. }
  33. }

OK,谢谢你看到了文章末尾,由于在公司无法上传代码,回家后将源码奉上,请稍安勿燥!

急着下班,文章讲解不够,如果各位有啥问题,欢迎留言。Thanks!





更多相关文章

  1. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Fedora镜像
  2. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Debian镜像
  3. Android(安卓)Activity界面切换添加动画特效
  4. Android屏幕分辨率正确获取及PX,DPI,DP,SP等的对应关系
  5. android实现字体闪烁动画的方法
  6. IM-A820L限制GSM,WCDMA上网的原理(其他泛泰机型可参考)7.13
  7. Android:interpolator用法
  8. Android——开发环境
  9. 创建android逐帧动画的两种方式

随机推荐

  1. 个人网站对xss跨站脚本攻击(重点是富文本
  2. MySQL 5.6 插入缓冲测试
  3. 从数据库sql中删除一个单词
  4. mysql常用命令/语句学习三
  5. MySQL忘记密码破解密码的方法
  6. mysql 执行计划和慢日志记录
  7. mysql数据库之表的操作
  8. Django查询优化:根据多对一到多对多查找对
  9. 关于autotrace和explain plan是否可以反
  10. 教你如何彻底卸载MySQL数据库