Android仿微信Viewpager-Fragment惰性加载(lazy-loading)

yizhihongxing

下面是“Android仿微信Viewpager-Fragment惰性加载(lazy-loading)”的完整攻略:

1. 背景介绍

在开发Android App过程中,如果需要使用 Viewpager-Fragment 的方式去实现多个页面的滑动展示效果,会面临一个问题:Viewpager默认是会提前加载所有的Fragment的,这样可能会导致内存占用过大,特别是当页面比较多、内容比较复杂时,更容易出现问题。因此,我们需要实现惰性加载(lazy-loading)的功能,即只加载当前正在显示的Fragment,而不预加载其他Fragment。

2. 解决方案

要实现惰性加载,我们需要进行如下步骤:

  1. 继承FragmentPagerAdapter类
  2. 重写getItem()方法,控制Fragment的加载和销毁
  3. 给Viewpager添加OnPageChangeListener监听器,以便及时加载当前展示的Fragment

具体实现步骤如下:

2.1 继承FragmentPagerAdapter类

在自己的项目中新建一个PagerAdapter类,继承FragmentPagerAdapter类,并在构造方法中传入FragmentManager和一个Fragment列表。代码如下:

public class PagerAdapter extends FragmentPagerAdapter {
    private List<Fragment> mFragments;

    public PagerAdapter(@NonNull FragmentManager fm, List<Fragment> fragments) {
        super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
        mFragments = fragments;
    }

    @NonNull
    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }
}

2.2 重写getItem()方法

在上面的代码中,重写了getItem()方法,通过传入的Fragment列表获取当前需要展示的Fragment。注意,这里由于是惰性加载,我们不需要预加载其他的Fragment,因此直接返回当前需要展示的Fragment即可。

2.3 添加OnPageChangeListener监听器

在MainActivity中,我们需要给Viewpager添加一个OnPageChangeListener监听器,以便及时加载当前展示的Fragment。具体代码如下:

public class MainActivity extends AppCompatActivity {

    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mViewPager = findViewById(R.id.view_pager);

        List<Fragment> fragments = new ArrayList<>();
        fragments.add(new Fragment1());
        fragments.add(new Fragment2());
        fragments.add(new Fragment3());
        fragments.add(new Fragment4());
        fragments.add(new Fragment5());

        PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), fragments);
        mViewPager.setAdapter(pagerAdapter);

        mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                Fragment fragment = getSupportFragmentManager().findFragmentById(mViewPager.getId());
                if (fragment instanceof OnPageChangeListener) {
                    ((OnPageChangeListener) fragment).onPageSelected(position);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
    }
}

在上面的代码中,重写了ViewPager的OnPageChangeListener监听器,当翻页结束后,会调用onPageSelected()方法,我们在这个方法里获取当前展示的Fragment,然后判断它是否实现了OnPageChangeListener接口,如果实现了,就调用它的onPageSelected()方法,以便对当前Fragment进行加载操作。

3. 示例说明

以下是两个示例说明:

3.1 示例1

这个示例中,我们需要实现一个类似微信的聊天界面,其中有两个页面:聊天列表和聊天详情。由于聊天列表可能会很长,因此我们需要惰性加载聊天详情,只有当用户点击某条聊天记录时,才动态地加载聊天详情。具体代码如下:

public class ChatActivity extends AppCompatActivity {

    private ViewPager mViewPager;
    private List<ChatFragment> mFragments;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        mViewPager = findViewById(R.id.view_pager);

        int totalCount = getIntent().getIntExtra("totalCount", 0);
        mFragments = new ArrayList<>();
        for (int i = 0; i < totalCount; i++) {
            mFragments.add(ChatFragment.newInstance("聊天" + (i + 1)));
        }

        PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), mFragments);
        mViewPager.setAdapter(pagerAdapter);
    }

    public void switchToChatDetail(int position) {
        if (position < 0 || position >= mFragments.size()) {
            return;
        }

        ChatFragment chatFragment = mFragments.get(position);
        if (chatFragment != null) {
            chatFragment.loadChatDetail();
        }
    }
}

在上面的代码中,我们新建了一个ChatActivity,其中包含一个ViewPager和一个ChatFragment列表。在创建ChatFragment时,我们传入了聊天的标题,并在里面实现了“惰性”加载聊天详情的功能。具体代码如下:

public class ChatFragment extends Fragment implements OnPageChangeListener {

    private TextView mTitle;
    private TextView mChatDetail;
    private String mChatTitle;

    public ChatFragment() {
    }

    public static ChatFragment newInstance(String param1) {
        ChatFragment fragment = new ChatFragment();
        Bundle args = new Bundle();
        args.putString("title", param1);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mChatTitle = getArguments().getString("title");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_chat, container, false);
        mTitle = view.findViewById(R.id.chat_title);
        mChatDetail = view.findViewById(R.id.chat_detail);
        mTitle.setText(mChatTitle);
        return view;
    }

    public void loadChatDetail() {
        mChatDetail.setText("聊天详情");
    }

    @Override
    public void onPageSelected(int position) {
        loadChatDetail();
    }
}

在上面的代码中,我们实现了OnPageChangeListener接口的onPageSelected()方法,当当前页面被选中时,会自动调用这个方法,然后在这个方法里进行动态加载聊天详情的操作。这样就可以实现惰性加载了。

3.2 示例2

这个示例中,我们需要实现一个类似图片浏览器的应用,可以左右滑动查看多张图片。由于图片可能会很多,因此需要使用惰性加载,只有当前展示的图片才需要加载到内存中。具体代码如下:

public class ImageViewActivity extends AppCompatActivity {

    private ViewPager mViewPager;
    private List<String> mImageUrls;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_image_view);

        mViewPager = findViewById(R.id.view_pager);

        mImageUrls = new ArrayList<>();
        mImageUrls.add("https://img0.baidu.com/it/u=1777723668,3364133462&fm=26&fmt=auto&gp=0.jpg");
        mImageUrls.add("https://img1.baidu.com/it/u=1871415769,2696643648&fm=26&fmt=auto&gp=0.jpg");
        mImageUrls.add("https://img0.baidu.com/it/u=792956869,4176773104&fm=26&fmt=auto&gp=0.jpg");
        mImageUrls.add("https://img2.baidu.com/it/u=1168359362,3784133363&fm=26&fmt=auto&gp=0.jpg");
        mImageUrls.add("https://img0.baidu.com/it/u=3076408024,2736535225&fm=26&fmt=auto&gp=0.jpg");

        List<ImageViewFragment> fragments = new ArrayList<>();
        for (int i = 0; i < mImageUrls.size(); i++) {
            fragments.add(ImageViewFragment.newInstance(mImageUrls.get(i)));
        }

        PagerAdapter pagerAdapter = new PagerAdapter(getSupportFragmentManager(), fragments);
        mViewPager.setAdapter(pagerAdapter);
    }
}

在上面的代码中,我们新建了一个ImageViewActivity,其中包含一个ViewPager和一个图片Url列表。在创建ImageViewFragment时,我们传入了图片的Url,并在里面实现了“惰性”加载图片的功能。具体代码如下:

public class ImageViewFragment extends Fragment implements OnPageChangeListener {

    private ImageView mImageView;
    private String mImageUrl;

    public ImageViewFragment() {
    }

    public static ImageViewFragment newInstance(String imageUrl) {
        ImageViewFragment fragment = new ImageViewFragment();
        Bundle args = new Bundle();
        args.putString("imageUrl", imageUrl);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mImageUrl = getArguments().getString("imageUrl");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_image_view, container, false);
        mImageView = view.findViewById(R.id.image_view);
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        loadImage();
    }

    private void loadImage() {
        Glide.with(this)
                .load(mImageUrl)
                .into(mImageView);
    }
}

在上面的代码中,我们在Fragment的onResume()方法里进行了图片的加载操作,这样就能保证只有当前展示的图片才会被加载。同时,由于我们实现了OnPageChangeListener接口的onPageSelected()方法,因此在用户滑动页面时,也会及时加载新的图片。

4. 总结

通过以上的介绍,我们学习了如何使用惰性加载(lazy-loading)的方式,解决Viewpager预加载过多Fragment导致内存占用过大的问题。

具体实现方式如下:

  1. 继承FragmentPagerAdapter类
  2. 重写getItem()方法,控制Fragment的加载和销毁
  3. 给Viewpager添加OnPageChangeListener监听器,及时加载当前展示的Fragment

通过以上的代码示例,我们可以更好地理解惰性加载的原理,进而在实际开发中应用到我们的项目中,提高应用的性能和用户体验。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android仿微信Viewpager-Fragment惰性加载(lazy-loading) - Python技术站

(0)
上一篇 2023年6月27日
下一篇 2023年6月27日

相关文章

  • Python中Enum使用的几点注意事项

    下文会为您详细讲解Python中Enum使用的几点注意事项。 Enum定义 首先,我们应该明确Enum的定义。Enum是一个枚举类,它将一组常量定义为一个特定类型的有限集合。在Python中,可以使用标准库中的枚举类Enum来定义一个枚举类。一般的Enum定义方式如下: from enum import Enum class Color(Enum): RED…

    other 2023年6月26日
    00
  • Mac实用操作技巧(二)

    Mac实用操作技巧(二) 本文将为您提供Mac实用操作技巧(二)的完整攻略,包括Mac快捷键、Finder的使用技巧、以及两个示例说明。 Mac快捷键 Mac快捷键是Mac OS X操作系统中的一种快捷键,可以帮助用户更快地完成一些常用的操作。以下是一些常用的Mac快捷键: Command + C:复制选中的内容。 Command + V:粘贴复制的内容。 …

    other 2023年5月6日
    00
  • 在Linux下用软件实现RAID功能

    在Linux下使用软件实现RAID可以提高磁盘性能和数据可靠性。以下是完整的攻略: 确定RAID等级 首先需要确定您希望使用的RAID等级。RAID 0、RAID 1、RAID 5、RAID 6 等都是常见的RAID等级,各有不同的优缺点。在选择RAID等级时需要权衡不同RAID等级的优点和缺点,根据实际需求做出决定。 安装需要的工具 安装mdadm工具,用…

    other 2023年6月27日
    00
  • 使用批处理命令设置windows系统的ip地址和dns附图

    当你需要使用批处理命令设置Windows系统的IP地址和DNS时,可以按照以下步骤进行操作: 打开文本编辑器,例如记事本,创建一个新的批处理文件(以.bat为扩展名)。 在批处理文件中,使用以下命令来设置IP地址和子网掩码: netsh interface ipv4 set address name=\”本地连接\” static IP地址 子网掩码 其中,…

    other 2023年7月30日
    00
  • thinkpad怎么把视频添加右键菜单?

    以下是完整的ThinkPad如何添加视频右键菜单攻略: 1. 确定注册表键值 在添加右键菜单之前需要先在注册表中找到相应的键值。以一般的MP4视频为例,在注册表中找到以下键值: HKEY_CLASSES_ROOT\SystemFileAssociations\.mp4 在该键值下新建一个名为”Shell”的子键,之后在”Shell”下新建一个名为”Open …

    other 2023年6月27日
    00
  • 有不同的主题论坛 百度宣布7月4日在京召开AI开发者大会

    有不同的主题论坛 在网上,我们可以找到很多不同主题的论坛,例如技术类、娱乐类等等。这些论坛主要是为了让用户在相同兴趣爱好的圈子里互相交流、分享经验、解决问题等。 例如,以技术类论坛为例,用户可以在论坛上发布自己的问题、经验或者文章等,其他用户可以对其进行回复、点赞等等。这样,用户之间可以相互帮助、提高自己的技术水平。 百度宣布7月4日在京召开AI开发者大会 …

    other 2023年6月26日
    00
  • C++ 打开选择文件夹对话框选择目录的操作

    下面是详细的攻略: 目录选择框的使用方法 C++ 通过调用 Windows API 流程来打开选择文件夹对话框,选择和获取用户选择的目录信息。具体步骤如下: 通过 CoInitialize 函数来初始化 COM 库。 调用 Windows API 函数 CoCreateInstance 获取 IFileOpenDialog 的 Interface 指针,同时…

    other 2023年6月27日
    00
  • Android GridView实现横向列表水平滚动

    当在Android应用程序中使用GridView实现横向列表水平滚动时,可以按照以下完整攻略进行操作: … … 在布局文件中,添加一个GridView控件,并设置相应的属性。 <GridView … android:id=\"@+id/gridView\" … android:layout_width=\"…

    other 2023年9月5日
    00
合作推广
合作推广
分享本页
返回顶部