目录
[Android ViewPager (页面切换组件)](#Android ViewPager (页面切换组件))
[Android ViewPager 翻页标签栏](#Android ViewPager 翻页标签栏)
[Android ViewPager 翻页标签栏(含下划线)](#Android ViewPager 翻页标签栏(含下划线))
Android ViewPager (页面切换组件)
Android 中的 ViewPager 组件是一个可以在多个页面之间进行滑动切换的视图容器。它通常用于创建包含多个页面(Fragment 或 View)的用户界面,用户可以通过手势(左右滑动)或者程序控制来切换不同的页面。
使用 ViewPager 可以实现一些常见的功能,比如创建引导页、图片轮播、选项卡式布局等。通过适配器(Adapter)来为 ViewPager 提供页面内容,并利用 FragmentPagerAdapter 或 FragmentStatePagerAdapter 来管理页面的生命周期。
ViewPaper
在创建 ViewPager 时,可以通过 XML 布局文件定义 ViewPager 控件,然后通过特定的 Adapter(PagerAdapter 的子类)将 View 和 ViewPager 绑定在一起。对于 ViewPager,推荐使用 Fragment 来填充每个页面,这样能更方便地生成和管理每个页面的生命周期。
Android 官方推荐使用 FragmentPagerAdapter 或 FragmentStatePagerAdapter 这两个专用的 Adapter 类来管理 ViewPager 中的页面。它们分别适用于不同的场景:
- FragmentPagerAdapter:适合固定页面较少的情况,它会缓存当前页面以及左右相邻的页面,而其他页面则会被销毁,有助于节省内存资源。
- FragmentStatePagerAdapter:适合页面较多或页面内容复杂、需要占用大量内存的情况。当 Fragment 不可见时,整个 Fragment 实例会被销毁,只保留状态信息,而在需要重新显示页面时会重新生成页面实例,从而有效管理内存占用。
PagerAdapter
PagerAdapter 是一个抽象类,需要创建子类并重写其中的四个方法来实现对 ViewPager 中页面的管理:
- getCount():用于获取 ViewPager 中包含多少个 view(页面)。
- destroyItem():移除给定位置的 view,在 finishUpdate(viewGroup) 返回时确保视图能够被正确移除。
- instantiateItem():将给定位置的 view 添加到 ViewGroup(容器)中,并创建并显示出来。需要返回一个代表新增页面的 Object(通常是直接返回 view 本身)。
- isViewFromObject():判断 instantiateItem(ViewGroup, int) 函数所返回的 key 是否与页面视图是同一个对象。
通过重写这四个方法,可以实现对 ViewPager 中页面的管理和操作,包括添加、移除和判断页面对象。这使得开发者能够灵活地控制 ViewPager 中每个页面的行为,并根据需要进行定制化的处理。
范例
1、创建布局文件 activity_main.xml:
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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
2、创建 fragment_layout.xml 布局文件,作为 ViewPager 中每个页面的布局:
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"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="页面内容" />
</LinearLayout>
3、创建一个简单的 Fragment 类 MyFragment.java:
java
package com.example.myapplication;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class MyFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}
}
4、在 MainActivity 中设置 ViewPager 和 FragmentStatePagerAdapter:
java
package com.example.myapplication;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
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);
MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
}
private class MyPagerAdapter extends FragmentStatePagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@NonNull
@Override
public Fragment getItem(int position) {
return new MyFragment();
}
@Override
public int getCount() {
return 3; // 例如,这里返回3表示有3个页面
}
}
}
参考文档
Android ViewPager 翻页标签栏
上面的ViewPager 总觉得还缺少些什么,能添加上标题一起切换就好了。Android 官方早就帮我们想好了,它们提供了 PagerTitleStrip 与 PagerTabStrip 用来制作 ViewPaper 的标题栏,前者是普通文字,后者会附带下划线,它们会随着页面切换而切换。
PagerTitleStrip
在 XML 中创建 PagerTitleStrip 的示例代码如下:
XML
<androidx.viewpager.widget.PagerTitleStrip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:textColor="#FB0707"/>
然后,可以通过以下方法来定制 PagerTitleStrip 的外观:
- getTextSpacing():获取标题之间的间距
- setGravity(int gravity):设置文本对齐方式
- setNonPrimaryAlpha(float alpha):设置用于非主要页面标题的 Alpha 值
- setTextColor(int color):设置文本颜色
- setTextSize(int unit, float size):将默认文字大小设置为给定的单位和值
- setTextSpacing(int spacingPixels):设置标题段之间的间距
范例
1、创建布局文件 activity_main.xml:
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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.PagerTitleStrip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:textColor="#FB0707"/>
</androidx.viewpager.widget.ViewPager>
</LinearLayout>
2、创建 fragment_layout.xml 布局文件,作为 ViewPager 中每个页面的布局:
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"
android:gravity="center">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="页面内容" />
</LinearLayout>
3、创建一个简单的 Fragment 类 MyFragment.java:
java
package com.example.myapplication;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
public class MyFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_layout, container, false);
}
}
4、在 MainActivity 中设置 ViewPager 和 FragmentStatePagerAdapter,并为每个页面设置标题:
java
package com.example.myapplication;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentStatePagerAdapter;
import androidx.viewpager.widget.ViewPager;
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);
MyPagerAdapter pagerAdapter = new MyPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(pagerAdapter);
}
private class MyPagerAdapter extends FragmentStatePagerAdapter {
private String[] pageTitle = {"页 1", "页 2", "页 3"};
public MyPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
@Override
public CharSequence getPageTitle(int position) {
return pageTitle[position];
}
@NonNull
@Override
public Fragment getItem(int position) {
return new MyFragment();
}
@Override
public int getCount() {
return 3; // 例如,这里返回3表示有3个页面
}
}
}
参考文档
Android ViewPager 翻页标签栏(含下划线)
我们就来试一试 PagerTabStrip 来给 ViewPager 的标题添加下划线效果。
范例
接着用上面的范例,只需要将activity_main.xml 修改一下。
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"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:gravity="center"
tools:context=".MainActivity">
<androidx.viewpager.widget.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.viewpager.widget.PagerTabStrip
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:textColor="#FB0707"/>
</androidx.viewpager.widget.ViewPager>
</LinearLayout>