ViewPager的使用<二>

本文详细介绍如何使用Android中的ViewPager实现无限循环滚动效果和自动滚动功能。通过自定义适配器,重写关键方法,实现了图片轮播效果,并提供源码下载。

布局

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>

此案例中ViewPager每一页的布局就是一个ImageView

代码

    // 初始化
    init();
    // 设置适配器
    mViewPager.setAdapter(mMyPagerAdapter);
    private void init() {
        mViewPager = (ViewPager) findViewById(R.id.viewPager);
        inflater = getLayoutInflater();

        mViews = new ArrayList<>();

        for (int i = 0; i < imgResIds.length; i++) {
            View inflate = inflater.inflate(R.layout.item, null);
            ImageView imageView = (ImageView) inflate.findViewById(R.id.item_img);
            imageView.setBackgroundResource(imgResIds[i]);
            mViews.add(inflate);
        }

        mMyPagerAdapter = new MyPagerAdapter(mViews);

    }

适配器

    /**
     * 创建类继承PagerAdapter,只给我们重写了两个方法getCount(),isViewFromObject()
     * ViewPager要使用的话至少要重写四个方法 instantiateItem(),destroyItem()
     */
    class MyPagerAdapter extends PagerAdapter{

        List<View> mList;

        public MyPagerAdapter(List<View> list) {
            mList = list;
        }

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

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object; // 官方推荐写法
        }

        /**
         * @param container 其实就是ViewPager
         * @return 实际返回的就是子页面的View视图
         */
        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            View view = mList.get(position);
            container.addView(view);

            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(mList.get(position));
        }
    }

进阶1-实现无限滚动

适配器需要修改

        @Override
        public Object instantiateItem(ViewGroup container, int position) {

            position %= mList.size();

            View view = mList.get(position);
            container.addView(view);

            return view;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            // getCount设置为一个无限大的数,导致必须对position进行取余
            // 保证不会超过item的个数,防止下标越界
            position %= mList.size();

            container.removeView(mList.get(position));
        }

        // 实现无限滚动  给数据源个数设置为一个比较大的数值即可
        @Override
        public int getCount() {
            return Integer.MAX_VALUE;
        }

进阶2-实现自动滚动

    private void AutoScroll() {
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {

                // 先获取到当前滚动到的position
                int currentItem = mViewPager.getCurrentItem();


                 mViewPager.setCurrentItem(++currentItem);


                mHandler.postDelayed(this,2000);
            }
        }, 2000);

这里写图片描述 这里写图片描述

源码下载

Java是一种具备卓越性能与广泛平台适应性的高级程序设计语言,最初由Sun Microsystems(现属Oracle公司)的James Gosling及其团队于1995年正式发布。该语言在设计上追求简洁性、稳定性、可移植性以及并发处理能力,同时具备动态执行特性。其核心特征与显著优点可归纳如下: **平台无关性**:遵循“一次编写,随处运行”的理念,Java编写的程序能够在多种操作系统与硬件环境中执行,无需针对不同平台进行修改。这一特性主要依赖于Java虚拟机(JVM)的实现,JVM作为程序与底层系统之间的中间层,负责解释并执行编译后的字节码。 **面向对象范式**:Java全面贯彻面向对象的设计原则,提供对封装、继承、多态等机制的完整支持。这种设计方式有助于构建结构清晰、模块独立的代码,提升软件的可维护性与扩展性。 **并发编程支持**:语言层面集成了多线程处理能力,允许开发者构建能够同时执行多项任务的应用程序。这一特性尤其适用于需要高并发处理的场景,例如服务器端软件、网络服务及大规模分布式系统。 **自动内存管理**:通过内置的垃圾回收机制,Java运行时环境能够自动识别并释放不再使用的对象所占用的内存空间。这不仅降低了开发者在内存管理方面的工作负担,也有效减少了因手动管理内存可能引发的内存泄漏问题。 资源来源于网络分享,仅用于学习交流使用,请勿用于商业,如有侵权请联系我删除!
在 Android 中,**推荐使用 `newInstance()` 静态工厂方法** 来创建并传递参数给 `Fragment`。如果你需要传递一个 `ArrayList<CustomBean>`,你的 `CustomBean` 类必须实现 **`Parcelable` 或 `Serializable` 接口**,否则无法通过 `Bundle` 传递。 --- ### ✅ 步骤一:确保 `CustomBean` 实现 `Parcelable`(推荐) > ⚠️ 不推荐用 `Serializable`,性能较差;`Parcelable` 是 Android 专用、高效的方式。 ```kotlin data class CustomBean( val id: Int, val name: String, val email: String ) : Parcelable { constructor(parcel: Parcel) : this( parcel.readInt(), parcel.readString() ?: "", parcel.readString() ?: "" ) override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeInt(id) parcel.writeString(name) parcel.writeString(email) } override fun describeContents(): Int = 0 companion object : Parcelable.Creator<CustomBean> { override fun createFromParcel(parcel: Parcel): CustomBean { return CustomBean(parcel) } override fun newArray(size: Int): Array<CustomBean?> { return arrayOfNulls(size) } } } ``` > 💡 使用 Android Studio 插件(如 “Android Parcelable Code Generator”)可自动生成 `Parcelable` 代码。 --- ### ✅ 步骤:在 Fragment 中定义 `newInstance()` 方法 ```kotlin class MyFragment : Fragment() { private var dataList: ArrayList<CustomBean>? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 从 arguments 恢复数据 arguments?.let { dataList = it.getParcelableArrayList("data_list") } } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { // 使用 dataList 渲染 UI return inflater.inflate(R.layout.fragment_my, container, false) } companion object { // ✅ 工厂方法:创建带参数的 Fragment fun newInstance(dataList: ArrayList<CustomBean>): MyFragment { val fragment = MyFragment() val args = Bundle().apply { putParcelableArrayList("data_list", dataList) } fragment.arguments = args return fragment } } } ``` --- ### ✅ 步骤三:使用 `newInstance()` 创建 Fragment ```kotlin val dataList = arrayListOf( CustomBean(1, "张三", "zhangsan@example.com"), CustomBean(2, "李四", "lisi@example.com") ) val fragment = MyFragment.newInstance(dataList) // 添加到 Activity 或 ViewPager 等 supportFragmentManager.beginTransaction() .replace(R.id.container, fragment) .commit() ``` --- ### ✅ 注意事项与最佳实践 | 要点 | 说明 | |------|------| | 🔹 必须实现 `Parcelable` | 否则 `putParcelableArrayList()` 会失败 | | 🔹 使用 `ArrayList<CustomBean>` 而非 `List` | 因为 `Bundle` 只支持 `ArrayList` 的 `putParcelableArrayList` | | 🔹 不要直接传 `List` 给 `arguments` | 必须先放入 `Bundle` | | 🔹 避免传大量数据 | `Bundle` 有大小限制(~1MB),大数据建议用 `ViewModel` 或 `Repository` 共享 | | 🔹 支持 Kotlin 默认值和 `@Parcelize` | 更简洁写法见下 | --- ### ✅ 使用 Kotlin `@Parcelize` 简化代码(推荐) 启用 `@Parcelize`(需在 `build.gradle` 启用): ```kotlin // build.gradle (app level) android { ... buildFeatures { viewBinding true // Or if using kapt: } } // 必须开启 apply plugin: 'kotlin-parcelize' ``` 然后简化 `CustomBean`: ```kotlin import android.os.Parcelable import kotlinx.parcelize.Parcelize @Parcelize data class CustomBean( val id: Int, val name: String, val email: String ) : Parcelable ``` > ✅ 自动生成 `Parcelable` 实现,无需手写! --- ### ❌ 常见错误 ```kotlin // ❌ 错误:没有实现 Parcelable putParcelableArrayList("list", list) // ❌ 错误:用了 MutableList 但不是 ArrayList val list: MutableList<CustomBean> = mutableListOf(...) // 运行时类型不是 ArrayList // ❌ 错误:在 Fragment 构造函数中传参 MyFragment(list) // 不推荐!Fragment 必须有无参构造函数 ``` --- ### ✅ 替代方案(适用于大数据或复杂场景) 如果列表很大或频繁更新,建议: - 使用 `SharedViewModel` - 通过 `LiveData` 或 `StateFlow` 共享数据 - Fragment 只持有 ID 或索引,自行加载数据 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值