Android开发 - (适配器)Adapter类中FragmentStatePagerAdapter实现类详细解析

简介

  • 用于 ViewPager,与 Fragment 一起使用,适合大量动态页面

具体作用

  • FragmentStatePagerAdapter是一个用于管理 Fragment 的适配器类通常用于需要在 ViewPager 中切换多个Fragment的场景。它的主要作用是管理和保存Fragment的状态,尤其适合那些需要处理大量Fragment或者Fragment内容动态变化的情况。以下是 FragmentStatePagerAdapter 的一些主要作用和特点

    动态管理Fragment

    • FragmentStatePagerAdapter会在需要时创建Fragment,并在不需要时销毁它们,以节省内存。这与FragmentStatePagerAdapter不同后者会保留所有的Fragment对象即使它们不再可见

    状态保存和恢复

    • Fragment被销毁时状态会被保存,并在重新创建时恢复。这使得在内存紧张的情况下可以释放资源,并在需要时重新加载Fragment

    性能优化

    • 由于FragmentStatePagerAdapter会销毁不再需要的Fragment对象,因此在处理大量Fragment时,它比FragmentStatePagerAdapter更加节省内存和资源

    适用场景

    • 特别适用于那些页面数量多或者页面内容复杂的应用场景,如新闻阅读器图片浏览器

参数、方法解析

  • FragmentStatePagerAdapter(FragmentManager fm);基本的构造方法适用于早期的 Android 版本FragmentManager 用于在适配器中添加、移除或替换 Fragment抽象类无法直接实例化,需要重写一个子类继承它

    public class MyPagerAdapter extends FragmentStatePagerAdapter {
        private List<Fragment> fragmentList; // 自定义参数:Fragment 列表
        
    	// 自定义构造方法:接受 FragmentManager、自定义参数:Fragment 列表
        public MyPagerAdapter(@NonNull FragmentManager fm, List<Fragment> fragmentList) {
            super(fm);
            this.fragmentList = fragmentList;
        }
    
        @NonNull
        @Override
        public Fragment getItem(int position) {
            return fragmentList.get(position);
        }
    
        @Override
        public int getCount() {
            return fragmentList.size();
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return "Page " + (position + 1);
        }
    }
    
    // 在Activity或Fragment中实例化
    List<Fragment> fragments = new ArrayList<Fragment>();
    fragments.add(new Fragment1());
    fragments.add(new Fragment2());
    fragments.add(new Fragment3());
    MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager(), fragments);
    
    • 参数解析
      • fm:用于与 Fragment 进行交互可以是 FragmentActivity 中的 getSupportFragmentManager();也可以是 Fragment 中的 getChildFragmentManager();
  • FragmentStatePagerAdapter(FragmentManager fm, int behavior);此构造方法允许你指定适配器的行为模式,从而更好地控制 Fragment 的生命周期管理抽象类无法直接实例化,需要重写一个子类继承它

    public class MyPagerAdapter extends FragmentStatePagerAdapter {
        private List<Fragment> fragmentList; // 自定义参数:Fragment 列表
    
        // 自定义构造方法:接受 FragmentManager、行为模式、自定义参数:Fragment 列表
        public MyPagerAdapter(@NonNull FragmentManager fm, int behavior, List<Fragment> fragmentList) {
            super(fm, behavior);
            this.fragmentList = fragmentList;
        }
    
        @NonNull
        @Override
        public Fragment getItem(int position) {
            return fragmentList.get(position);
        }
    
        @Override
        public int getCount() {
            return fragmentList.size();
        }
    
        @Override
        public CharSequence getPageTitle(int position) {
            return "Page " + (position + 1);
        }
    }
    // 在Activity或Fragment中实例化
    List<Fragment> fragments = new ArrayList<Fragment>();
    fragments.add(new Fragment1());
    fragments.add(new Fragment2());
    fragments.add(new Fragment3());
    MyPagerAdapter adapter = new MyPagerAdapter(getSupportFragmentManager(), FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, fragments);
    
    • 参数解析
      • fm:用于与 Fragment 进行交互可以是 FragmentActivity 中的 getSupportFragmentManager();也可以是 Fragment 中的 getChildFragmentManager();
      • behavior:表示适配器的行为类型;可以是以下常量之一:
        • FragmentStatePagerAdapter.BEHAVIOR_SET_USER_VISIBLE_HINT:在 API 24 及更低版本中使用,这种行为控制 Fragment 的可见性
        • FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT推荐使用的行为模式,表示只有当前可见的 Fragment 会被设置为活动状态(Resumed)
  • adapter.instantiateItem(ViewGroup container, int position);根据给定的位置创建 Fragment 对象并将其添加到 container 中

    • 参数解析
      • containerViewGroup,即 ViewPager,用于将新创建的 Fragment 添加到这个容器中
      • position:表示当前页面的位置
  • adapter.destroyItem(ViewGroup container, int position, Object object);:从 container 中移除并销毁指定位置的 Fragment 对象

    • 参数解析
      • containerViewGroup,即 ViewPager,用于从这个容器中移除 Fragment
      • position:表示要销毁的页面的位置
      • object:即 Fragment 对象
  • adapter.getItem(int position);返回指定位置的 Fragment 对象每次需要新的 Fragment 时,ViewPager 会调用这个方法。此方法必须被重写返回对应位置的 Fragment

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new Fragment1();
            case 1:
                return new Fragment2();
            case 2:
                return new Fragment3();
            default:
                return null;
        }
    }
    //调用
    Fragment Item = adapter.getItem(0)	//Fragment1 在 ViewPager 中的位置
    
    • 参数解析
      • position返回的 Fragment 在 ViewPager 中的位置
  • adapter.getCount();返回 Fragment 的总数量即 ViewPager 中页面的数量。此方法必须被重写

    @Override
    public int getCount() {
        return 3; // 总共3个页面
    }
    //调用
    int num = adapter.getCount()
    
  • getPageTitle(int position);可以重写此方法来设置 TabLayout 或 ViewPager 页面的标题

    //在自定义 FragmentStatePagerAdapter 类中导入 CharSequence 类重写此方法
    @Override
    public CharSequence getPageTitle(int position) {
        switch (position) {
            case 0:
                return "Page 1";
            case 1:
                return "Page 2";
            case 2:
                return "Page 3";
            default:
                return null;
        }
    }
    //调用
    Char mText = adapter.getPageTitle(0);	//Page 1
    
    • 参数解析
      • position页数索引,用于获取特定页数的标题
  • saveState();用于保存适配器的当前状态。它返回一个 Parcelable 对象,该对象包含适配器需要保存的所有数据。这通常包括当前显示的 Fragment 的状态

    //在自定义 FragmentStatePagerAdapter 类中导入 Parcelable 类重写此方法
    @Override
    public Parcelable saveState() {
        // 调用父类的方法,获取默认的状态信息
        Parcelable p = super.saveState();
        // 你可以在此处添加其他状态保存逻辑
        return p;
    }
    //在大多数情况下,你不需要重写这个方法,因为 FragmentStatePagerAdapter 的默认实现已经处理了大部分常见的状态保存需求
    
  • restoreState(Parcelable state, ClassLoader loader);恢复适配器的状态。它使用先前保存的 Parcelable 对象和 ClassLoader 来恢复 Fragment 和其他状态信息

    //在自定义 FragmentStatePagerAdapter 类中重写此方法
    @Override
    public void restoreState(Parcelable state, ClassLoader loader) {
        // 调用父类的方法,恢复默认的状态信息
        super.restoreState(state, loader);
        // 你可以在此处添加其他状态恢复逻辑
    }
    //在大多数情况下,你不需要重写这个方法,因为 FragmentStatePagerAdapter 的默认实现已经处理了大部分常见的状态保存需求
    
    • 参数解析
      • state:这个参数是之前通过 saveState(); 方法保存的适配器状态;它包含了适配器需要恢复的所有数据可以是一个 Bundle 或其他 Parcelable 实现类,包含 Fragment 的状态和适配器的其他状态信息
      • loader:这个参数是一个 ClassLoader 对象,用于加载 Fragment 类的类加载器。当恢复 Fragment 的对象状态时系统使用这个 ClassLoader 来确保能够正确地加载 Fragment 类。通常,你可以直接传递参数而不需要修改它

使用环境与完整代码解析

  • FragmentStatePagerAdapter 用于高效地管理大量的 Fragment。它适合以下多种使用场景,特别是在需要处理动态内容优化内存和管理大量页面的情况下

    多步骤表单(Multi-Step Forms)

    • 需求:分步填写用户信息,每一步都由不同的 Fragment 显示

    • 代码示例

      • 创建布局文件

        • 主布局文件activity_form.xml

          <?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
          
              <!-- ViewPager 用于展示不同步骤的 Fragment -->
              <androidx.viewpager.widget.ViewPager
                  android:id="@+id/viewPager"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
          
          </RelativeLayout>
          
        • Fragment 布局文件:fragment_step1.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 第一步的布局内容 -->
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Step 1: Enter Your Name" />
          </LinearLayout>
          
        • Fragment 布局文件fragment_step2.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 第二步的布局内容 -->
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Step 2: Enter Your Address" />
          </LinearLayout>
          
        • Fragment 布局文件fragment_step3.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 第三步的布局内容 -->
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Step 3: Review and Submit" />
          </LinearLayout>
          
      • 创建 Fragment 类

        • Step1Fragment.java

          import androidx.fragment.app.Fragment;
          import android.os.Bundle;
          import android.view.LayoutInflater;
          import android.view.View;
          import android.view.ViewGroup;
          
          /**
           * 第一步 Fragment
           * 这个 Fragment 代表多步骤表单的第一步。
           */
          public class Step1Fragment extends Fragment {
              @Override
              public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                  // 返回第一个步骤的布局文件
                  return inflater.inflate(R.layout.fragment_step1, container, false);
              }
          }
          
        • Step2Fragment.java

          import androidx.fragment.app.Fragment;
          import android.os.Bundle;
          import android.view.LayoutInflater;
          import android.view.View;
          import android.view.ViewGroup;
          
          /**
           * 第二步 Fragment
           * 这个 Fragment 代表多步骤表单的第二步。
           */
          public class Step2Fragment extends Fragment {
              @Override
              public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                  // 返回第二个步骤的布局文件
                  return inflater.inflate(R.layout.fragment_step2, container, false);
              }
          }
          
        • Step3Fragment.java

          import androidx.fragment.app.Fragment;
          import android.os.Bundle;
          import android.view.LayoutInflater;
          import android.view.View;
          import android.view.ViewGroup;
          
          /**
           * 第三步 Fragment
           * 这个 Fragment 代表多步骤表单的第三步。
           */
          public class Step3Fragment extends Fragment {
              @Override
              public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                  // 返回第三个步骤的布局文件
                  return inflater.inflate(R.layout.fragment_step3, container, false);
              }
          }
          
      • 启动类直接在活动或片段中定义适配器

        import androidx.appcompat.app.AppCompatActivity;
        import androidx.fragment.app.Fragment;
        import androidx.fragment.app.FragmentStatePagerAdapter;
        import androidx.viewpager.widget.ViewPager;
        import android.os.Bundle;
        
        import java.util.ArrayList;
        import java.util.List;
        
        /**
         * 多步骤表单活动类
         * 这个活动类包含一个 ViewPager,用于显示不同步骤的表单页面。
         */
        public class FormActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                // 设置活动的布局文件
                setContentView(R.layout.activity_form);
        
                // 获取 ViewPager 实例
                ViewPager viewPager = findViewById(R.id.viewPager);
        
                // 创建 Fragment 列表,每个 Fragment 代表一个步骤
                List<Fragment> fragments = new ArrayList<Fragment>();
                fragments.add(new Step1Fragment()); // 第一步
                fragments.add(new Step2Fragment()); // 第二步
                fragments.add(new Step3Fragment()); // 第三步
        
                // 创建 FragmentStatePagerAdapter 适配器:没有专门创建适配器类的情况下,直接在活动或片段中定义适配器
                // 通过继承 FragmentStatePagerAdapter 并实现必要的方法,你可以在没有创建新的适配器类文件的情况下直接定义适配器
                FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager(),
                    FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
        
                    @Override
                    public Fragment getItem(int position) {
                        // 根据当前位置返回对应的 Fragment
                        return fragments.get(position);
                    }
        
                    @Override
                    public int getCount() {
                        // 返回 Fragment 的总数
                        return fragments.size();
                    }
                };
        
                // 将适配器设置给 ViewPager
                viewPager.setAdapter(adapter);
            }
        }
        

    新闻阅读器(News Readers)

    • 需求显示不同的新闻条目,每个条目由一个 Fragment 显示

    • 代码示例

      • 创建布局文件

        • 主布局文件activity_news.xml

          <?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
          
              <!-- ViewPager 用于展示不同新闻的 Fragment -->
              <androidx.viewpager.widget.ViewPager
                  android:id="@+id/viewPager"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
          
          </RelativeLayout>
          
        • Fragment 布局文件fragment_news.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 新闻内容展示 -->
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="News Content" />
          </LinearLayout>
          
      • 创建Fragment类NewsFragment.java

        import androidx.fragment.app.Fragment;
        import android.os.Bundle;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        
        /**
         * 新闻 Fragment
         * 这个 Fragment 用于显示单条新闻的内容。
         */
        public class NewsFragment extends Fragment {
            private static final String ARG_NEWS_ID = "news_id";
        
            // 创建一个新的实例,并传递新闻 ID
            public static NewsFragment newInstance(int newsId) {
                NewsFragment fragment = new NewsFragment();
                Bundle args = new Bundle();
                args.putInt(ARG_NEWS_ID, newsId);
                fragment.setArguments(args);
                return fragment;
            }
        
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                int newsId = getArguments().getInt(ARG_NEWS_ID);
                // 返回新闻布局文件
                return inflater.inflate(R.layout.fragment_news, container, false);
            }
        }
        
      • 启动类直接在活动或片段中定义适配器

        import androidx.appcompat.app.AppCompatActivity;
        import androidx.fragment.app.Fragment;
        import androidx.fragment.app.FragmentStatePagerAdapter;
        import androidx.viewpager.widget.ViewPager;
        import android.os.Bundle;
        
        import java.util.ArrayList;
        import java.util.List;
        
        /**
         * 新闻活动类
         * 这个活动类包含一个 ViewPager,用于显示不同新闻页面。
         */
        public class NewsActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                // 设置活动的布局文件
                setContentView(R.layout.activity_news);
        
                // 获取 ViewPager 实例
                ViewPager viewPager = findViewById(R.id.viewPager);
        
                // 创建新闻 Fragment 列表
                List<Fragment> fragments = new ArrayList<Fragment>();
                for (int i = 1; i <= 10; i++) {
                    // 为每条新闻创建一个 Fragment
                    fragments.add(NewsFragment.newInstance(i));
                }
        
                // 创建 FragmentStatePagerAdapter 适配器:没有专门创建适配器类的情况下,直接在活动或片段中定义适配器
                // 通过继承 FragmentStatePagerAdapter 并实现必要的方法,你可以在没有创建新的适配器类文件的情况下直接定义适配器
                FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager(),
                    FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
        
                    @Override
                    public Fragment getItem(int position) {
                        // 根据当前位置返回对应的 Fragment
                        return fragments.get(position);
                    }
        
                    @Override
                    public int getCount() {
                        // 返回 Fragment 的总数
                        return fragments.size();
                    }
                };
        
                // 将适配器设置给 ViewPager
                viewPager.setAdapter(adapter);
            }
        }
        

    产品展示(Product Showcases)

    • 需求展示不同的产品视图(如图片、描述、评论),每个视图由一个 Fragment 显示

    • 代码示例

      • 创建布局文件

        • 主布局文件activity_product.xml

          <?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
          
              <!-- ViewPager 用于展示产品的不同视图 -->
              <androidx.viewpager.widget.ViewPager
                  android:id="@+id/viewPager"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
          
          </RelativeLayout>
          
        • Image布局文件fragment_product_images.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 产品图片视图 -->
              <ImageView
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:src="@drawable/sample_image" />
          </LinearLayout>
          
        • Text描述布局文件fragment_product_description.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 产品描述视图 -->
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Product Description" />
          </LinearLayout>
          
        • Text评论布局文件fragment_product_reviews.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 产品评论视图 -->
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Product Reviews" />
          </LinearLayout>
          
      • 创建 Fragment 文件ProductFragment.java

        import androidx.fragment.app.Fragment;
        import android.os.Bundle;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        
        /**
         * 产品 Fragment
         * 这个 Fragment 用于显示产品的不同视图(图片、描述、评论)。
         */
        public class ProductFragment extends Fragment {
            private static final String ARG_VIEW_TYPE = "view_type";
        
            // 创建一个新的实例,并传递视图类型
            public static ProductFragment newInstance(int viewType) {
                ProductFragment fragment = new ProductFragment();
                Bundle args = new Bundle();
                args.putInt(ARG_VIEW_TYPE, viewType);
                fragment.setArguments(args);
                return fragment;
            }
        
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                int viewType = getArguments().getInt(ARG_VIEW_TYPE);
                // 根据视图类型返回对应的布局文件
                switch (viewType) {
                    case 0:
                        return inflater.inflate(R.layout.fragment_product_images, container, false);
                    case 1:
                        return inflater.inflate(R.layout.fragment_product_description, container, false);
                    case 2:
                        return inflater.inflate(R.layout.fragment_product_reviews, container, false);
                    default:
                        return null;
                }
            }
        }
        
      • 启动类直接在活动或片段中定义适配器

        import androidx.appcompat.app.AppCompatActivity;
        import androidx.fragment.app.Fragment;
        import androidx.fragment.app.FragmentStatePagerAdapter;
        import androidx.viewpager.widget.ViewPager;
        import android.os.Bundle;
        
        import java.util.ArrayList;
        import java.util.List;
        
        /**
         * 产品展示活动类
         * 这个活动类包含一个 ViewPager,用于显示产品的不同视图。
         */
        public class ProductActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                // 设置活动的布局文件
                setContentView(R.layout.activity_product);
        
                // 获取 ViewPager 实例
                ViewPager viewPager = findViewById(R.id.viewPager);
        
                // 创建产品 Fragment 列表
                List<Fragment> fragments = new ArrayList<Fragment>();
                fragments.add(ProductFragment.newInstance(0)); // 图片视图
                fragments.add(ProductFragment.newInstance(1)); // 描述视图
                fragments.add(ProductFragment.newInstance(2)); // 评论视图
        
                // 创建 FragmentStatePagerAdapter 适配器:没有专门创建适配器类的情况下,直接在活动或片段中定义适配器
                // 通过继承 FragmentStatePagerAdapter 并实现必要的方法,你可以在没有创建新的适配器类文件的情况下直接定义适配器
                FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager(),
                    FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
        
                    @Override
                    public Fragment getItem(int position) {
                        // 根据当前位置返回对应的 Fragment
                        return fragments.get(position);
                    }
        
                    @Override
                    public int getCount() {
                        // 返回 Fragment 的总数
                        return fragments.size();
                    }
                };
        
                // 将适配器设置给 ViewPager
                viewPager.setAdapter(adapter);
            }
        }
        

    电子书阅读器(E-Book Readers)

    • 需求:用户可以滑动浏览不同的章节每章由一个 Fragment 显示

    • 代码示例

      • 创建布局文件

        • 主布局文件activity_ebook.xml

          <?xml version="1.0" encoding="utf-8"?>
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
          
              <!-- ViewPager 用于展示电子书的各章节 -->
              <androidx.viewpager.widget.ViewPager
                  android:id="@+id/viewPager"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent" />
          
          </RelativeLayout>
          
        • Fragment 布局文件fragment_chapter.xml

          <?xml version="1.0" encoding="utf-8"?>
          <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
          
              <!-- 章节内容 -->
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Chapter Content" />
          </LinearLayout>
          
      • 创建 Fragment 类ChapterFragment.java

        import androidx.fragment.app.Fragment;
        import android.os.Bundle;
        import android.view.LayoutInflater;
        import android.view.View;
        import android.view.ViewGroup;
        
        /**
         * 章节 Fragment
         * 这个 Fragment 用于显示电子书的单个章节内容。
         */
        public class ChapterFragment extends Fragment {
            private static final String ARG_CHAPTER_ID = "chapter_id";
        
            // 创建一个新的实例,并传递章节 ID
            public static ChapterFragment newInstance(int chapterId) {
                ChapterFragment fragment = new ChapterFragment();
                Bundle args = new Bundle();
                args.putInt(ARG_CHAPTER_ID, chapterId);
                fragment.setArguments(args);
                return fragment;
            }
        
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                int chapterId = getArguments().getInt(ARG_CHAPTER_ID);
                // 根据章节 ID 加载相应的布局
                return inflater.inflate(R.layout.fragment_chapter, container, false);
            }
        }
        
      • 启动类直接在活动或片段中定义适配器

        import androidx.appcompat.app.AppCompatActivity;
        import androidx.fragment.app.Fragment;
        import androidx.fragment.app.FragmentStatePagerAdapter;
        import androidx.viewpager.widget.ViewPager;
        import android.os.Bundle;
        
        import java.util.ArrayList;
        import java.util.List;
        
        /**
         * 电子书活动类
         * 这个活动类包含一个 ViewPager,用于显示电子书的各章节。
         */
        public class EBookActivity extends AppCompatActivity {
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                // 设置活动的布局文件
                setContentView(R.layout.activity_ebook);
        
                // 获取 ViewPager 实例
                ViewPager viewPager = findViewById(R.id.viewPager);
        
                // 创建章节 Fragment 列表
                List<Fragment> fragments = new ArrayList<Fragment>();
                for (int i = 1; i <= 20; i++) {
                    // 为每个章节创建一个 Fragment
                    fragments.add(ChapterFragment.newInstance(i));
                }
        
                // 创建 FragmentStatePagerAdapter 适配器:没有专门创建适配器类的情况下,直接在活动或片段中定义适配器
                // 通过继承 FragmentStatePagerAdapter 并实现必要的方法,你可以在没有创建新的适配器类文件的情况下直接定义适配器
                FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(getSupportFragmentManager(),
                    FragmentStatePagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
        
                    @Override
                    public Fragment getItem(int position) {
                        // 根据当前位置返回对应的 Fragment
                        return fragments.get(position);
                    }
        
                    @Override
                    public int getCount() {
                        // 返回 Fragment 的总数
                        return fragments.size();
                    }
                };
        
                // 将适配器设置给 ViewPager
                viewPager.setAdapter(adapter);
            }
        }
        
posted @ 2024-08-02 11:53  阿俊学JAVA  阅读(202)  评论(0编辑  收藏  举报