getuservisiblegethint.asp和isvisible的区别

android知识点(74)
/a/anzhuokaifa/androidkaifa/13.html
我们在做应用开发的时候,一个Activity里面可能会以viewpager(或其他容器)与多个Fragment来组合使用,而如果每个fragment都需要去加载数据,或从本地加载,或从网络加载,那么在这个activity刚创建的时候就变成需要初始化大量资源。这样的结果,我们当然不会满意。那么,能不能做到当切换到这个fragment的时候,它才去初始化呢?
答案就在Fragment里的setUserVisibleHint这个方法里。请看关于Fragment里这个方法的API文档(国内镜像地址:):
Set&a&hint&to&the&system&about&whether&this&fragment's&UI&is&currently&visible&to&the&user.&This&hint&defaults&to&true&and&is&persistent&across&fragment&instance&state&save&and&restore.An&app&may&set&this&to&false&to&indicate&that&the&fragment's&UI&is&scrolled&out&of&visibility&or&is&otherwise&not&directly&visible&to&the&user.&This&may&be&used&by&the&system&to&prioritize&operations&such&as&fragment&lifecycle&updates&or&loader&ordering&behavior.ParametersisVisibleToUser&true&if&this&fragment's&UI&is&currently&visible&to&the&user&(default),&false&if&it&is&not.
代码如下:
/*&*&Date:&14-7-17&*&Project:&Access-Control-V2&*/package&cn.irains.access_control_v2.common;import&android.support.v4.app.Fragment;/**&*&Author:&msdx&()&*&Time:&14-7-17&下午5:46&*/public&abstract&class&LazyFragment&extends&Fragment&{&&&&protected&boolean&isVisible;&&&&/**&&&&&*&在这里实现Fragment数据的缓加载.&&&&&*&@param&isVisibleToUser&&&&&*/&&&&@Override&&&&public&void&setUserVisibleHint(boolean&isVisibleToUser)&{&&&&&&&&super.setUserVisibleHint(isVisibleToUser);&&&&&&&&if(getUserVisibleHint())&{&&&&&&&&&&&&isVisible&=&true;&&&&&&&&&&&&onVisible();&&&&&&&&}&else&{&&&&&&&&&&&&isVisible&=&false;&&&&&&&&&&&&onInvisible();&&&&&&&&}&&&&}&&&&protected&void&onVisible(){&&&&&&&&lazyLoad();&&&&}&&&&protected&abstract&void&lazyLoad();&&&&protected&void&onInvisible(){}}
在LazyFragment,我增加了三个方法,一个是onVisiable,即fragment被设置为可见时调用,一个是onInvisible,即fragment被设置为不可见时调用。另外再写了一个lazyLoad的抽象方法,该方法在onVisible里面调用。你可能会想,为什么不在getUserVisibleHint里面就直接调用呢?
我这么写是为了代码的复用。因为在fragment中,我们还需要创建视图(onCreateView()方法),可能还需要在它不可见时就进行其他小量的初始化操作(比如初始化需要通过AIDL调用的远程服务)等。而setUserVisibleHint是在onCreateView之前调用的,那么在视图未初始化的时候,在lazyLoad当中就使用的话,就会有空指针的异常。而把lazyLoad抽离成一个方法,那么它的子类就可以这样做:
public&class&OpenResultFragment&extends&LazyFragment{&&&&//&标志位,标志已经初始化完成。&&&&private&boolean&isPrepared;&&&&@Override&&&&public&View&onCreateView(LayoutInflater&inflater,&ViewGroup&container,&Bundle&savedInstanceState)&{&&&&&&&&Log.d(LOG_TAG,&&onCreateView&);&&&&&&&&View&view&=&inflater.inflate(R.layout.fragment_open_result,&container,&false);&&&&&&&&//XXX初始化view的各控件&&&&isPrepared&=&true;&&&&&&&&lazyLoad();&&&&&&&&return&view;&&&&}&&&&@Override&&&&protected&void&lazyLoad()&{&&&&&&&&if(!isPrepared&||&!isVisible)&{&&&&&&&&&&&&return;&&&&&&&&}&&&&&&&&//填充各控件的数据&&&&}}
在上面的类当中,我们增加了一个标志位isPrepared,用于标志是否初始化完成。然后在我们所需要的初始化操作完成之后调用,如上面的例子当中,在初始化view之后,设置 isPrepared为true,同时调用lazyLoad()方法。而在lazyLoad()当中,判断isPrepared和isVisible只要有一个不为true就不往下执行。也就是仅当初始化完成,并且可见的时候才继续加载,这样的避免了未初始化完成就使用而带来的问题。
在这里我对fragment的懒加载实现的介绍就到此为止,如果你有兴趣,可以基于此再深入探究,比如写一个带有缓初始化和可见时刷新的特性的Fragment。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3337次
排名:千里之外
原创:82篇
转载:47篇ljh0242 的BLOG
用户名:ljh0242
文章数:443
评论数:94
访问量:1169660
注册日期:
阅读量:5863
阅读量:12276
阅读量:357656
阅读量:1054202
51CTO推荐博文
request.getParameter(),request.setAttribute()区别如下:
(1)request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据,request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段。
(2)request.getParameter()方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。request.getParameter()方法返回String类型的数据。
request.setAttribute()和getAttribute()方法传递的数据只会存在于Web容器内部
还有一点就是,HttpServletRequest类有setAttribute()方法,而没有setParameter()方法。
拿一个例子来说一下吧,假如两个WEB页面间为链接关系时,就是说要从1.jsp链接到2.jsp时,被链接的是2.jsp可以通过getParameter()方法来获得请求参数.
假如1.jsp里有
&form name="form1" method="post" action="2.jsp"&
请输入用户姓名:&input type="text" name="username"&
&input type="submit" name="Submit" value="提交"&
&/form&的话在2.jsp中通过request.getParameter("username")方法来获得请求参数username:
&% String username=request.getParameter("username"); %&
但是如果两个WEB间为转发关系时,转发目的WEB可以用getAttribute()方法来和转发源WEB共享request范围内的数据,也还是说一个例子吧。
有1.jsp和2.jsp
1.jsp希望向2.jsp传递当前的用户名字,如何传递这一数据呢?先在1.jsp中调用如下setAttribute()方法:
String username=request.getParameter("username");
request.setAttribute("username",username);
&jsp:forward page="2.jsp" /&
在2.jsp中通过getAttribute()方法获得用户名字:
&% String username=(String)request.getAttribute("username"); %&
了这篇文章
类别:┆阅读(0)┆评论(0)
17:01:15 09:20:00 20:11:52 14:47:36ViewPager+fragment延时加载,懒加载(数据缓存)
ViewPager+fragment延时加载,懒加载(数据缓存)
今天开发遇到数据缓存的问题, ViewPager+2个fragment,大家都知道ViewPager有预加载的功能,每次都会把下一个页面同时加载,这样虽然有时很好,但是用户只需看一个Fragment时,我们就做了一些多余工作加载了第二个Fragment。在这只需要取消Fragment的预加载即可,只有当用户切换到某个Fragment才加载..这样用户体验会好一点,在网上查询过,LazyViewPager可以实现,但是切换页面的时候发现都会重新加载,
并没有把之前加载过的缓存起来,这样效果不理想, 这个念头打消后变想下一个办法
首先,介绍两个方法void
setUserVisibleHint(boolean isVisibleToUser)、boolean getUserVisibleHint(),它们分别用作设置/获得Fragment可见状态,我们可以重写Fragment在其中做判断,代码如下:
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if(isVisibleToUser&&isInit)//isInit
默认是false 没有初始化控件过,不然会空指针
loadData();
isInit=//不可见,设置为false 第二次可见的时候不执行加载数据的方法
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
isInit=//初始化后 将其设置成true
表示已经初始化控件过了
改fragment的 第一次进入走的几个方法& 当然他的其他生命周期的方 法我就不写了。&setUserVisibleHint()
-----》onCreateView()------》onViewCreate()-----》
&&在你每次切换fragment的时候,都会调用setUserVisbleHint(),当第一次预加载的时候isVisibleToUser=false &isInit=false,执行到onViewCreate()的时候isInit=true,条件不成立,所以不会执行加载数据的方法,当切换切换到这个fragment的时候isVisibleToUser=true了
,&isInit=true, 执行加载数据 ,而当用户切换上一个fragment的时候 ,会再次调用setUserVisibleHint()此时isVisibleToUser=false,会走else方法,
isInit=false了 , 再次切换到当前fragment的时候便不会再加载数据,也就实现了延时加载+数据缓存的效果了
转载请注明出处
我的热门文章
即使是一小步也想与你分享

我要回帖

更多关于 getlocalvisiblerect 的文章

 

随机推荐