用Fragment实现Tab页面切换效果初步总结

前言:

最近在Android项目中需要在活动中实现多页面切换的功能,第一次是实现的过程中,是让Activity同时去加载三个界面的,通过点击tab按钮对页面设置隐藏和显示,实现页面切换效果,但是后面发现这种实现方式其实存在很多问题:

  1. 首先,同时去加载三个页面,切换Activity的速度会变慢,尤其是布局中如果有很多ImageView,ImageButton等使用到图片资源的控件时,切换效果非常不好;
  2. 其次,由于使用了很多图片资源,在退出Activity的时候,像Drawable,Bitmap等一些资源并不会随着Activity的销毁而立即回收,导致手机占用很多内存空间,导致ANR(应用程序无响应)或者OOM(内存溢出)的Bug。然而,很多经验不足的Android开发人员,包括我自己,每次写Activity的时候,并没有去考虑这些问题,导致项目后面出现一系列的问题,还好没到那种无可挽回的地步,知道这点以后,一定要养成好的代码习惯。
  3. 然后,一个Activity里面会有大量的初始化控件的代码,还有其他的一些方法等等,是的Activity变的非常臃肿,难以维护,有时候出现一个错误,都不太好找。

然后网上找到一些资料,使用Fragment去实现Tab切换,是一个很不错的方式,基本可以解决以上问题。

我对Fragment的理解:中文翻译就叫碎片,它可以最大限度的利用手机和平板的显示空间,让开发者可以活用布局,实现很多不错的布局效果,当然要学会使用它,需要了解它的一些基本特性,方法,以及生命周期等。

关于Fragment的详细介绍,在这里推荐弘扬的博客http://blog.csdn.net/lmj623565791/article/details/37970961,里面分了三篇将Fragment的使用以及一些需要注意的地方讲的非常详细,篇幅比较长,所以需要拿出点耐心来看。

第一部分:

在开展项目的这段时间中,将遇到的一些Bug贴出来,网上并不是那么容易就能找到答案的Bug,同时也是困扰了很久才解决的

Bug1:

描述:(java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.zaina/wayto.com.cn.task.TaskInfoActivity}: android.view.InflateException: Binary XML file line #17: Error inflating class <unknown>)

思路分析:起初认为是布局文件的错误,然而并没有找到答案,之后再网上搜寻答案,大部分都是说由于使用了自定义控件导致的,其他的原因也有,无奈的是,我并没有使用自定义控件,只是简单的不了个局,为控件使用了统一的Style样式而已。但是这个Bug有点奇怪的是,程序刚运行的时候,进入多页面的Activity,退出再进,没问题,随着次数的增多,程序就报这个错误。Bug的出现并没有固定的一个时机,于是,我就想到,可能是手机内存不足导致,后面用了eclipse里面一个强大的插件内存分析工具MAT(Memory Analyzer Tool) ,果然不出所料,找到了内存泄露的地方,正是布局里面使用了过多的图片资源而没有手动回收导致异常。

解决方案:1,在Activity中使用了图片资源,一定要记得在onStop()方法里面去手动释放资源,这里贴一段代码,也是网上找到的,仅供参考。

 1 try {
 2             for (ImageView image : imageList) {
 3                 if (image!=null) {
 4 //                    Drawable d=image.getDrawable();
 5 //                    if (d!=null) d.setCallback(null);
 6 //                    image.setImageDrawable(null);
 7                     BitmapDrawable bd=(BitmapDrawable) image.getBackground();
 8                     if (bd!=null) {
 9                         System.gc();
10                         //释放的大小
11                         long size=Runtime.getRuntime().totalMemory();
12                         bd.setCallback(null);
13                         bd.getBitmap().recycle();
14                         bd=null;
15                         System.gc();
16                         Log.i("TaskInfo", "释放"+size);
17                     }
18                 }
19                 image=null;
20             }
21             imageList=null;
22         } catch (Exception e) {
23             e.printStackTrace();
24             Log.i("TaskInfo", "错误"+e.getMessage());
25         }

2,如果程序中有多次重复使用图片资源的情况,可以使用SoftReference或者LruCache一些缓存机制去处理,而不是每次去重新加载图片,相关内容可以参考http://blog.csdn.net/xiaanming/article/details/9825113,也是写的非常好的一篇博客,里面主要是讲到使用LruCache+线程池的方式异步下载图片,设计到的技术点也很多了。

相关参考:http://www.2cto.com/kf/201408/326452.html

     http://stackoverflow.com/questions/7536988/android-app-out-of-memory-issues-tried-everything-and-still-at-a-loss/7576275

Bug2:

描述:Android FragmentManager BackStackRecord.run throwing NullPointerException

思路分析:这是我后面采用Fragment实现多页面效果的过程中遇到的一个错误,也是困扰了我一段时间,其实后面想想,根本原因还是自己对Fragment还不够了解,使用过程中遇到的一些错误就不知道该从哪里入手分析,后面还是借助百度找到了答案。其实是使用Fragment切换页面过程中,之前用每次都是用FragmentTransaction的replace()方法去实现,没有问题,但是每次都是销毁上一个Fragment,然后重新加载新的Fragment,这样也可以,然是效率不高,因为每次切换都要重新new 一个Fragment,重新createView(),切换页面过程中会有卡顿。看了弘扬的博客里面写到,如果想要保留前一个Fragment的参数,最好使用FragmentTransaction的hide()和show()方法。

第一次的写法:

//Fragment 声明三个Fragment为全局变量
    private TaskDetailFragment detailFragment;
    private TaskTimeLineFragment timeLineFragment;
    private TaskAttachFragment attachFragment;
private void ChangeFragment(int tabId){
        FragmentManager fm=getFragmentManager();
        //开发Fragment事务
        FragmentTransaction transaction = fm.beginTransaction();
        String tag="";
        switch (tabId) {
        case R.id.btn_detail:
            //详情
            if (detailFragment==null) {
                detailFragment=TaskDetailFragment.newInstance(ticket);
                transaction.add(R.id.taskinfo_content,detailFragment,"DETAIL");
                break;
            }
            transaction.show(detailFragment);//隐藏
            transaction.hide(timeLineFragment);//显示
            transaction.hide(attachFragment);//显示
            break;
            /后面代码类似...
            }    

依次按顺序,从第一个Fragment切换第二的Fragment,然后切换到第三个,都没问题,但是,从第一个切换到第二个Fragment,然后再切换回第一个Fragment时,第三个Fragment并没有加载,也就是为null,这也就是为什么会出现这个空指针的Bug。

解决:在执行FragmentTransaction的hide(),show(),replace(),add(),detach()等方法时,首先要判断Frangment是否为null,这里就直接贴代码了,判断为空的方式在代码中体现出来了

首先在transaction的add()方法中为Fragment制定Tag,然后用FragmentManager的findFragmentByTag("DETAIL")方法,判断返回值是否为空。

    //开始Fragment事务
        FragmentTransaction transaction = fm.beginTransaction();
//        String tag="";
        switch (tabId) {
        case R.id.btn_detail:
            //详情
            if (detailFragment==null) {
                detailFragment=TaskDetailFragment.newInstance(ticket);
                transaction.add(R.id.taskinfo_content,detailFragment,"DETAIL");
                break;
            }
            if(fm.findFragmentByTag("DETAIL")!=null)transaction.show(detailFragment);
            if(fm.findFragmentByTag("TIME")!=null)transaction.hide(timeLineFragment);
            if(fm.findFragmentByTag("ATTACH")!=null)transaction.hide(attachFragment);
            break;

相关参考:http://stackoverflow.com/questions/13393693/android-fragmentmanager-backstackrecord-run-throwing-nullpointerexception

第三部分:

最后,总结以上几点,发现自己对于Android的学习还是存在很多需要认真钻研的地方,对于自己不熟悉的技术和知识,一定要知其根源,多加练习,才能熟练运用,被自己所掌握,然后,分析问题的时候,思维不能形成固式,多发散,多参考资料,最终要的还是要多分析自己的代码,不要盲目修改,这样只会把Bug越改越多。

ps:项目还剩不到两周时间就要交差了,自己一定要好好努力,争取把自己第一个项目做好,做到不让自己留下遗憾!

时间: 2024-10-27 09:09:23

用Fragment实现Tab页面切换效果初步总结的相关文章

[Jquery]tab页面切换效果

思路:取得头部和内容的div,头部当前点击的高亮,其余的去除高亮,并通过index()方法获得当前点击的索引,然后内容div通过.eq(index)显示和隐藏 优化:当前做法,从第一个快速移到最后一个,中间每个内容都会相继显示出来.比较好的用户体验是,从某个标签迅速移到另一个标签,中间不想看的内容不显示出来.这就需要延迟切换效果(每次划每次加载信息,必将影响性能) 使用定时器:setTimeout(500毫秒),每次鼠标滑过的时候,先判断定时器存不存在,存在的话先清除定时器,然后开启定时器,执行

在uwp仿IOS的页面切换效果

有时候我们需要编写一些迎合IOS用户使用习惯的uwp应用,我在这里整理一下仿IOS页面切换效果的代码. 先分析IOS的页面切换.用户使用左右滑动方式进行前进和后退,播放类似于FlipView的切换动画.导航到新页面时,使用页面前进的动画. UWP自带很多切换效果,位于 Windows.UI.Xaml.Media.Animation 中.与苹果的切换效果最接近的是 PaneThemeTransition (而不是EdgeUIThemeTransition). PaneThemeTransition

搞定tab标签切换效果

<!doctype html><html lang="en"><head>    <meta charset="UTF-8">    <title>搞定tab标签切换效果</title><style>*{ margin:0; padding:0;list-style: none;}body {font:12px/1.5 Tahoma;}#big{border: 1px solid b

html5各种页面切换效果和模态对话框

页面动画:data-transition 属性可以定义页面切换是的动画效果.例如:<a href="index.html" data-transition="pop">I'll pop</a>data-transition 参数表:参数说明slide 从右侧向左滑入页面slideup 从底部向上滑入slidedown 从上向下滑入pop 从中心渐显展开fade 渐显flip 翻转备注:如果想要在目标页面中显示后退按钮,可以在链接中加入 dat

iOS开源项目 页面切换效果TransitionAnimation

RT:页面切换效果 https://github.com/xietao3/RMPZoomTransitionAnimatorDemo#rmpzoomtransitionanimatordemo 版权声明:本文为博主原创文章,未经博主允许不得转载.

纵向tab标签切换效果

html   css  js直接用就好 <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>纵向tab标签切换效果</title> <style> *{ margin:0; padding:0;list-style: none;} body {font:12px/1.5 Tahoma;} #out

js页面切换效果学习(基础)

css代码 .div1{ width: 130px; height: 130px; }.div2{ width: 20px;height:160px; margin-top: 0px; float: left;}body{ font-size: 12px;}.div2 li{ list-style-type: none; margin-top: 3px; background-color: wheat; height: 40px; text-align: center; padding-top:

基于html5和css3响应式全屏滚动页面切换效果

分享一款全屏响应式的HTML5和CSS3页面切换效果.这个页面布局效果对于那些页面要求固定100%高度和宽度的网站和APP来说是十分有用的.效果图如下: 在线预览   源码下载 HTML wrapper div的class为st-container,里面包含作为导航按钮的radio和用于页面切换的面板st-scroll. <div class="st-container"> <input type="radio" name="radio-

Android实现连续并排的若干个TextView单击改变背景颜色达到选项卡Tab栏切换效果

<Android实现连续并排的若干个TextView单击改变背景颜色达到选项卡Tab栏切换效果> 实现的组件交互目的很简单,就是要达到类似tab选项卡的导航栏一样,当用户点击了连续并排的若干个TextView其中之一时候,要产生一定的交互效果(背景颜色改变等).这种实现的方式有不少可选方案,现在通过背景的selector.xml实现. 效果如下: A.初始状态: B.当用户单击了TextView 2,但此时用户的手指一直在按下并未松开的状态,(注意交互设计效果!TextView 2的背景颜色变