相关文章推荐
追风的铁链  ·  ova圣华女学园免费网站 - 抖音·  9 月前    · 
腹黑的槟榔  ·  第368批新车公告:EC6换代将采用中创新航 ...·  2 年前    · 
淡定的打火机  ·  西汉博山型熏炉造型出现的时间与器型来源 - 知乎·  2 年前    · 
文武双全的爆米花  ·  Android进阶之沉浸式状态栏原理和使用详 ...·  2 年前    · 
干练的煎饼果子  ·  我就是不按套路出牌漫画86 - 抖音·  2 年前    · 
Code  ›  ViewPager懒加载的实现,理解setUserVisibleHint,而不只是会用就好开发者社区
fragment list 懒加载 viewpager
https://cloud.tencent.com/developer/article/1941084
深情的双杠
2 年前
作者头像
Petterp
0 篇文章

ViewPager懒加载的实现,理解setUserVisibleHint,而不只是会用就好

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > JetPack > ViewPager懒加载的实现,理解setUserVisibleHint,而不只是会用就好

ViewPager懒加载的实现,理解setUserVisibleHint,而不只是会用就好

作者头像
Petterp
发布 于 2022-02-09 11:17:35
574 0
发布 于 2022-02-09 11:17:35
举报

Viewpager默认会缓存临近操作的两个页面,也就是至少会缓存一个页面。但我们有时候的需求是需要当滑动到相应页面后再去更新数据,比如网络请求这种,可能你会说,那直接在onResumel里请求数据不就行了,但是ViewPager预加载机制在你处于前一个页面时,已经加载好了下一个页面。当然你也可以将所有页面全部缓存,但这样所消耗的内存不言而喻,而且如果数据过多,第一次进去的时候的速度不可估量。所以这次我们使用懒加载来实现我们的需求。 Fragment 提供了 setUserVisibleHint 方法检测当前碎片是否处于可见状态,但是需要注意的是,这个方法不可以直接回调,因为它与Fragment的生命周期不是同步的。 setOffscreenPageLimit() 方法,缓存的页面数,默认为1。

下面开始我们的操作: 创建一个基类继承与Fragment,并重写其中的 setUserVisibleHint() 与 onActivityCreated() 方法

public abstract class fragment extends Fragment {
    private boolean isvisible;
    //与碎片关联的活动创建完毕时调用
    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isvisible = true;
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        //是否对用户可见
        pan(isVisibleToUser);
    public void pan(boolean visble) {
        if (isvisible && visble) {
            //等同于onResume()方法
            getShow();
        } else if (isvisible && !visble) {
            //等同于onPause()方法
            getHint();
    public abstract void getShow();
    public abstract void getHint();
}

用一个Demo来验证一下:

我们先继承Fragment类打印一下日志,然后再继承我们重写的基类。对比一下效果

public class F1 extends Fragment{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=View.inflate(getActivity(),R.layout.f1,null);
        Log.e("demo","f1");
        return view;
}
public class F2 extends Fragment{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=View.inflate(getActivity(),R.layout.f2,null);
        Log.e("demo","f2");
        return view;
}
public class F3 extends Fragment{
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view=View.inflate(getActivity(),R.layout.f3,null);
        Log.e("demo","f3");
        return view;
}

适配器

public class ViewPagerAdApter extends FragmentStatePagerAdapter {
    private List<Fragment> list;
    public ViewPagerAdApter(FragmentManager fm, List<Fragment> list) {
        super(fm);
        this.list = list;
    @Override
    public Fragment getItem(int i) {
        return list.get(i);
    @Override
    public int getCount() {
        return list.size();
}

MainActivity

public class MainActivity extends AppCompatActivity {
    private ViewPager viewPager;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        viewPager=findViewById(R.id.viewpager);
        List<Fragment> list=new ArrayList();
        list.add(new F1());
        list.add(new F2());
        list.add(new F3());
        ViewPagerAdApter adApter=new ViewPagerAdApter(getSupportFragmentManager(),list);
        viewPager.setAdapter(adApter);
}

查看一下Log的打印

可以看到在我们切换到第二个页面时,第三个页面已经被默认加载好了 ,现在我们将子碎片继承自我们的基类,并实现其中的抽象方法。

//另外两个碎片同理
public class F1 extends fragment {
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = View.inflate(getActivity(), R.layout.f1, null);
        return view;
    @Override
    public void getShow() {
        Log.e("demo","F1可见");
    @Override
    public void getHint() {
        Log.e("demo","F1不可见");
}

效果如下,可以看到当滑动到第二个页面时,Log处就打出了F1不可见,F2可见。

现在对一些疑点进行分析: 为什么从第三个页面滑动到第二个页面,打印了两次不可见呢?

 
推荐文章
追风的铁链  ·  ova圣华女学园免费网站 - 抖音
9 月前
腹黑的槟榔  ·  第368批新车公告:EC6换代将采用中创新航电池 - 知乎
2 年前
淡定的打火机  ·  西汉博山型熏炉造型出现的时间与器型来源 - 知乎
2 年前
文武双全的爆米花  ·  Android进阶之沉浸式状态栏原理和使用详解-android 沉浸式状态栏
2 年前
干练的煎饼果子  ·  我就是不按套路出牌漫画86 - 抖音
2 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号