Android之实现百度云主界面框架

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 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 仿百度云主界面框架 
  3.  *  
  4.  * 注意继承自FragmentActivity,才会有getSupportFragmentManager()函数 
  5.  *  
  6.  * @author way 
  7.  *  
  8.  */  
  9. public class MainActivity extends FragmentActivity implements  
  10.         OnPageChangeListener {  
  11.     private static final int NUM_PAGES = 2;// 总页数,2个Fragment  
  12.     public static final int PAGE_PERSONAL = 0;// 第一个界面ID  
  13.     public static final int PAGE_FILE_SYSTEM = 1;// 第二个界面ID  
  14.     private static final int ROTATE_ANIM_DURATION = 300;// 左下角切换动画的时间  
  15.   
  16.     private int mCurPage = 0;// 当前页  
  17.     private ViewPager mViewPager;// 父容器由一个ViewPager实现  
  18.     private PagerAdapter mPagerAdapter;// ViewPager适配器  
  19.     private ImageButton mSwitchImageButton;// 左下角切换Paper按钮  
  20.     private ImageView mAnimView;// 动画View  
  21.     private Animation mRotateRightAnim;// 向右旋转动画  
  22.     private Animation mRotateLeftAnim;// 向左旋转动画  
  23.   
  24.     @Override  
  25.     protected void onCreate(Bundle savedInstanceState) {  
  26.         super.onCreate(savedInstanceState);  
  27.         setContentView(R.layout.activity_main);  
  28.         initView();  
  29.         initAnim();  
  30.     }  
  31.   
  32.     /** 
  33.      * 初始化Views 
  34.      */  
  35.     private void initView() {  
  36.         mAnimView = (ImageView) findViewById(R.id.anim_icon);  
  37.         mSwitchImageButton = (ImageButton) findViewById(R.id.switch_btn);  
  38.   
  39.         mViewPager = (ViewPager) findViewById(R.id.vp_pager);  
  40.         mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());  
  41.         mViewPager.setAdapter(mPagerAdapter);  
  42.         mCurPage = PAGE_FILE_SYSTEM;  
  43.         mViewPager.setCurrentItem(mCurPage);  
  44.         mViewPager.setOnPageChangeListener(this);  
  45.         mViewPager.setPageTransformer(truenew DepthPageTransformer());  
  46.     }  
  47.   
  48.     /** 
  49.      * 初始化动画 
  50.      */  
  51.     private void initAnim() {  
  52.         mRotateRightAnim = new RotateAnimation(0.0f, 180.0f,  
  53.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  
  54.                 0.5f);  
  55.         mRotateRightAnim.setDuration(ROTATE_ANIM_DURATION);  
  56.         mRotateRightAnim.setFillAfter(true);  
  57.         mRotateLeftAnim = new RotateAnimation(180.0f, 0.0f,  
  58.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  
  59.                 0.5f);  
  60.         mRotateLeftAnim.setDuration(ROTATE_ANIM_DURATION);  
  61.         mRotateLeftAnim.setFillAfter(true);  
  62.         mRotateRightAnim.setAnimationListener(new AnimationListener() {  
  63.   
  64.             @Override  
  65.             public void onAnimationStart(Animation animation) {  
  66.             }  
  67.   
  68.             @Override  
  69.             public void onAnimationRepeat(Animation animation) {  
  70.             }  
  71.   
  72.             @Override  
  73.             public void onAnimationEnd(Animation animation) {  
  74.                 mAnimView.clearAnimation();  
  75.                 mAnimView.setVisibility(View.GONE);  
  76.                 mSwitchImageButton.setVisibility(View.VISIBLE);  
  77.                 mSwitchImageButton  
  78.                         .setImageResource(R.drawable.ic_viewpager_switch_feedlist);  
  79.             }  
  80.         });  
  81.         mRotateLeftAnim.setAnimationListener(new AnimationListener() {  
  82.   
  83.             @Override  
  84.             public void onAnimationStart(Animation animation) {  
  85.             }  
  86.   
  87.             @Override  
  88.             public void onAnimationRepeat(Animation animation) {  
  89.             }  
  90.   
  91.             @Override  
  92.             public void onAnimationEnd(Animation animation) {  
  93.                 mAnimView.clearAnimation();  
  94.                 mAnimView.setVisibility(View.GONE);  
  95.                 mSwitchImageButton.setVisibility(View.VISIBLE);  
  96.                 mSwitchImageButton  
  97.                         .setImageResource(R.drawable.ic_viewpager_switch_filesystem);  
  98.             }  
  99.         });  
  100.     }  
  101.   
  102.     /** 
  103.      * 点击左下角切换按钮的事件处理 
  104.      *  
  105.      * 需要事先在布局中声明 android:onClick="switchPage" 
  106.      *  
  107.      * @param view 
  108.      */  
  109.     public void switchPage(View view) {  
  110.         if (mCurPage == PAGE_FILE_SYSTEM) {  
  111.             mViewPager.setCurrentItem(PAGE_PERSONAL);  
  112.         } else if (mCurPage == PAGE_PERSONAL) {  
  113.             mViewPager.setCurrentItem(PAGE_FILE_SYSTEM);  
  114.         }  
  115.     }  
  116.   
  117.     /** 
  118.      * 开始动画 
  119.      *  
  120.      * @param pager 
  121.      *            当前页 
  122.      */  
  123.     private void startAmin(int pager) {  
  124.         if (pager == PAGE_FILE_SYSTEM) {  
  125.             mSwitchImageButton.setVisibility(View.INVISIBLE);  
  126.             mAnimView.setVisibility(View.VISIBLE);  
  127.             mAnimView.startAnimation(mRotateLeftAnim);  
  128.         } else if (pager == PAGE_PERSONAL) {  
  129.             mSwitchImageButton.setVisibility(View.INVISIBLE);  
  130.             mAnimView.setVisibility(View.VISIBLE);  
  131.             mAnimView.startAnimation(mRotateRightAnim);  
  132.         }  
  133.         mCurPage = pager;  
  134.     }  
  135.   
  136.     /** 
  137.      * ViewPager的适配器,我这里只是一个例子,就作为内部类了。 
  138.      *  
  139.      * @author way 
  140.      *  
  141.      */  
  142.     private class ScreenSlidePagerAdapter extends FragmentPagerAdapter {  
  143.   
  144.         public ScreenSlidePagerAdapter(FragmentManager fm) {  
  145.             super(fm);  
  146.         }  
  147.   
  148.         /** 
  149.          * 这里可以将Fragment缓存一下,减少加载次数,提高用户体验,我未作处理 
  150.          */  
  151.         @Override  
  152.         public Fragment getItem(int position) {  
  153.             switch (position) {  
  154.             case PAGE_PERSONAL:  
  155.                 return new MainPersonalFragment();  
  156.             case PAGE_FILE_SYSTEM:  
  157.                 return new MainFileSystemFragment();  
  158.             default:  
  159.                 return null;  
  160.             }  
  161.         }  
  162.   
  163.         @Override  
  164.         public int getCount() {  
  165.             return NUM_PAGES;  
  166.         }  
  167.   
  168.     }  
  169.   
  170.     @Override  
  171.     public void onPageScrollStateChanged(int arg0) {  
  172.     }  
  173.   
  174.     @Override  
  175.     public void onPageScrolled(int arg0, float arg1, int arg2) {  
  176.     }  
  177.   
  178.     @Override  
  179.     public void onPageSelected(int arg0) {  
  180.         startAmin(arg0);//手势滑动ViewPager时,也要播放一下动画  
  181.     }  
  182. }  


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

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

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns: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.   
  7.     <RadioGroup  
  8.         android:id="@+id/rg_tabs"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:layout_alignParentBottom="true"  
  12.         android:layout_toRightOf="@android:id/icon"  
  13.         android:background="@drawable/tabbar_background"  
  14.         android:gravity="bottom"  
  15.         android:orientation="horizontal"  
  16.         android:paddingBottom="0.0dip"  
  17.         android:paddingLeft="50.0dip"  
  18.         android:paddingRight="0.0dip"  
  19.         android:paddingTop="4.0dip" >  
  20.   
  21.         <RadioButton  
  22.             android:id="@+id/rb_filelist"  
  23.             style="@style/NetDisk.Unified.Smaller.Blue2TabBarGray"  
  24.             android:layout_width="fill_parent"  
  25.             android:layout_height="fill_parent"  
  26.             android:layout_weight="1.0"  
  27.             android:background="@android:color/transparent"  
  28.             android:button="@null"  
  29.             android:drawableTop="@drawable/tab_filelist"  
  30.             android:gravity="center"  
  31.             android:paddingTop="4.0dip"  
  32.             android:text="@string/tab_filelist" />  
  33.   
  34.         <RadioButton  
  35.             android:id="@+id/rb_tools"  
  36.             style="@style/NetDisk.Unified.Smaller.Blue2TabBarGray"  
  37.             android:layout_width="fill_parent"  
  38.             android:layout_height="fill_parent"  
  39.             android:layout_weight="1.0"  
  40.             android:background="@android:color/transparent"  
  41.             android:button="@null"  
  42.             android:drawableTop="@drawable/tab_tools"  
  43.             android:gravity="center"  
  44.             android:paddingTop="4.0dip"  
  45.             android:text="@string/tab_tools" />  
  46.   
  47.         <RadioButton  
  48.             android:id="@+id/rb_transferlist_right"  
  49.             style="@style/NetDisk.Unified.Smaller.Blue2TabBarGray"  
  50.             android:layout_width="fill_parent"  
  51.             android:layout_height="fill_parent"  
  52.             android:layout_weight="1.0"  
  53.             android:background="@android:color/transparent"  
  54.             android:button="@null"  
  55.             android:drawableTop="@drawable/tab_transferlist"  
  56.             android:gravity="center"  
  57.             android:paddingTop="4.0dip"  
  58.             android:text="@string/tab_transferlist" />  
  59.     </RadioGroup>  
  60.   
  61.     <FrameLayout  
  62.         android:id="@+id/sliding_layer_frame_right"  
  63.         android:layout_width="match_parent"  
  64.         android:layout_height="match_parent"  
  65.         android:layout_above="@id/rg_tabs"  
  66.         android:background="@color/black" />  
  67.   
  68.     <ImageView  
  69.         android:id="@+id/iv_guide"  
  70.         android:layout_width="wrap_content"  
  71.         android:layout_height="wrap_content"  
  72.         android:layout_alignParentBottom="true"  
  73.         android:layout_marginBottom="169.0dip"  
  74.         android:src="@drawable/ic_swipe_guide_right"  
  75.         android:visibility="gone" />  
  76.   
  77. </RelativeLayout>  

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

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 每个Tab中的fragment 
  3.  *  
  4.  * @author way 
  5.  *  
  6.  */  
  7. public class SampleFragment extends Fragment {  
  8.   
  9.     private static final String ARG_TEXT = "text";  
  10.     private static final String ARG_PAGER = "pager";  
  11.   
  12.     public static SampleFragment newInstance(String text, int pager) {  
  13.         SampleFragment f = new SampleFragment();  
  14.   
  15.         Bundle args = new Bundle();  
  16.         args.putString(ARG_TEXT, text);  
  17.         args.putInt(ARG_PAGER, pager);  
  18.         f.setArguments(args);  
  19.   
  20.         return f;  
  21.     }  
  22.   
  23.     @Override  
  24.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  25.             Bundle savedInstanceState) {  
  26.         View v = inflater.inflate(R.layout.fragment_sample, container, false);  
  27.   
  28.         ((TextView) v.findViewById(R.id.text)).setText(getArguments()  
  29.                 .getString(ARG_TEXT));  
  30.         TextView title = (TextView) v.findViewById(R.id.title);  
  31.         title.setText(getArguments().getString(ARG_TEXT));  
  32.         int pager = getArguments().getInt(ARG_PAGER);  
  33.         if (pager == MainActivity.PAGE_FILE_SYSTEM)// 如果是文件系统的Fragment  
  34.             title.setBackgroundColor(Color.parseColor("#ff3995e3"));// 蓝色标题栏  
  35.         else  
  36.             title.setBackgroundColor(Color.parseColor("#ffde4125"));  
  37.         return v;  
  38.     }  
  39. }  

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

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





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值