【Android 学习笔记】PagerAdapter 模拟屏幕滑动效果

这篇博客详细介绍了如何在Android应用中实现TabLayout的屏幕滑动效果,包括创建工程、关闭默认AppBar、编写activity_main.xml、创建Fragment、编辑Fragment布局、实现PagerAdapter、设置tab名称以及管理屏幕显示。通过使用PagerAdapter和ViewPager,用户可以在同一Activity内切换不同内容的屏幕。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图

概括

you enable the user to go from one sibling to another (at the same level in a multitier hierarchy)
要点1. 使用 TabLayout 来显示 tab ,一般把 tab 层放在bar层下面。
要点2. 使用 PagerAdapter 类 来天从 tab一下的界面,Adapter (适配器),
use the PagerAdapter class to populate screens “pages” inside of a ViewPager。PagerAdapter 经常作为Fragment之间的连接。
要点3.ViewPager 式一个 layout manager 可以让用户来左右滑动屏幕。

This is a common pattern for presenting different screens of content
within an Activity—use an adapter to fill the content screen to show
in the Activity, and a layout manager that changes the content screens
depending on which tab is selected

步骤

第一步:创建

  1. 创建一个工程命名为Tab Experiment
  2. 编辑build.gradle(Module:app) 因为要使用TabLayout 需要依赖 Android Design Support Library,在dependencies 中输入下面代码,如果有红色警告,是提示 有新版本,更新即可,就是下面的 28.0.0 会变成更新的。
    implementation 'com.android.support:design:28.0.0'

第二步:改变原始的 app bar ,这是因为创建时会有一个默认的原始bar,我们需要把这个原始的bar关闭

res > values > styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
   <!-- Other style attributes -->      
   <item name="windowActionBar">false</item>  // 关闭原始的bar和titl,使用我们自己的Toolbar
   <item name="windowNoTitle">true</item>
</style>

第三步: 编写 activity_main.xml内容

有时候我们需要把颜色,数值写成attr属性,这样做是为了屏蔽开发者对应具体数值,比如我们需要设置不同主题下的主色,副色,或者是不同版本的ActionBar大小,亦或者是不同Dpi下的DrawerLayout的宽度等。

<RelativeLayout 
....省
    <android.support.v7.widget.Toolbar
。。。
        android:layout_alignParentTop="true"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
    <android.support.design.widget.TabLayout
    。。。
        android:layout_below="@id/toolbar"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/tab_layout"/>
</RelativeLayout>

如果加入 app:popupTheme后又红色警告,则在RelativeLayout 中加入 (alt+enter)

<RelativeLayout xmlns:app="http://schemas.android.com/apk/res-auto"

第四步: 为每个fragment创建一个类

动图,最后的结果要与最后一个动图一致
命名: TabFragment1 TabFragment2 and TabFragment3

第五步:编辑 Fragment layout

比如tab_fragment1的代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.android.tabexperiment.TabFragment1">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="These are the top stories: "
        android:textAppearance="?android:attr/textAppearanceLarge"/>
</RelativeLayout>

TabFragment2 and TabFragment3 类似,只要把 text改为自己喜欢的即可。

第六步:添加PagerAdapter 类(重点)

adapter-layout manager pattern 最大的特点是,其能在 同一个Activity中提供不同内容的屏幕显示,也就是说 adapter 是 起到适配的作用。

The adapter-layout manager pattern lets you provide different screens of content within an Activity:

Use an adapter to fill the content screen to show in the Activity. Use
a layout manager that changes the content screens depending on which
tab is selected.

添加的PagerAdapter 继承自 FragmentStatePagerAdapter

添加类的操纵见上图,Name the class PagerAdapter,
细节如下:

enter FragmentStatePagerAdapter into the Superclass field. This
entry changes to android.support.v4.app.FragmentStatePagerAdapter
Leave the Public and None options selected, and click OK.
出现红色警告,点击,选 Implement methods,会自动添加 getitem() 和 getCount() 方法。点OK即可。
另一个红色警告选,Create constructor matching super

最后再添加一个int 型的成员变量,把它放入构造函数中去,code如下

public class PagerAdapter extends FragmentStatePagerAdapter {
    int mNumOfTabs;
    
    public PagerAdapter(FragmentManager fm, int NumOfTabs) {
        super(fm);
        this.mNumOfTabs = NumOfTabs;
    }

    /**
     * Return the Fragment associated with a specified position.
     *
     * @param position
     */
    @Override
    public Fragment getItem(int position) {
        return null;
    }

    /**
     * Return the number of views available.
     */
    @Override
    public int getCount() {
        return 0;
    }
}

重写上面的getItem() 函数方法,选择要哪一个tab被点击了

@Override
public Fragment getItem(int position) {
        switch (position) {
            case 0: return new TabFragment1();
            case 1: return new TabFragment2();
            case 2: return new TabFragment3();
            default: return null;
        }
}

重写 getCount() 方法,返回被点击的值,这样就可以知道那个页面被点击了

@Override
public int getCount() {
        return mNumOfTabs;
}

第七步:为每个tab取名字

MainActivity

public class MainActivity extends AppCompatActivity {

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

        Toolbar toolbar =
                findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        // Create an instance of the tab layout from the view.
        TabLayout tabLayout = findViewById(R.id.tab_layout);
// Set the text for each tab.
        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label1));
        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label2));
        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label3));
// Set the tabs to fill the entire layout.
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);

String

<string name="tab_label1">Top Stories</string>
<string name="tab_label2">Tech News</string>
<string name="tab_label3">Cooking</string>

第八步 使用PagerAdapter 去管理每个屏幕的显示( 重点步)

// Each page is represented by its own fragment.
final ViewPager viewPager = findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
              (getSupportFragmentManager(), tabLayout.getTabCount());
viewPager.setAdapter(adapter);

接下来 set lister ,利用TabLayoutOnPageChangeListener,探测那个tab被点击了,之后,再相应位置,使用onTabSelected 方法去创建一个新的ViewPager,

// Setting a listener for clicks.
viewPager.addOnPageChangeListener(new
                TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new 
                TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {
    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {
    }
});

此步完整代码:

package com.example.a1104.tabexperiment;

import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.widget.TableLayout;

public class MainActivity extends AppCompatActivity {

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

        Toolbar toolbar =
                findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        // Create an instance of the tab layout from the view.
        TabLayout tabLayout = findViewById(R.id.tab_layout);
// Set the text for each tab.
        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label1));
        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label2));
        tabLayout.addTab(tabLayout.newTab().setText(R.string.tab_label3));
// Set the tabs to fill the entire layout.
        tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
// Use PagerAdapter to manage page views in fragments.

        final ViewPager viewPager = findViewById(R.id.pager);
        final PagerAdapter adapter = new PagerAdapter
                (getSupportFragmentManager(),tabLayout.getTabCount());
        viewPager.setAdapter(adapter);

        viewPager.addOnPageChangeListener(new
                TabLayout.TabLayoutOnPageChangeListener(tabLayout));
        tabLayout.addOnTabSelectedListener(
                new TabLayout.OnTabSelectedListener() {
                    @Override
                    public void onTabSelected(TabLayout.Tab tab) {
                        viewPager.setCurrentItem(tab.getPosition());
                    }

                    @Override
                    public void onTabUnselected(TabLayout.Tab tab) {
                    }

                    @Override
                    public void onTabReselected(TabLayout.Tab tab) {
                    }
                });
    }
}



完整代码展示:
https://github.com/google-developer-training/android-fundamentals-apps-v2/tree/master/TabExperiment


build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.a1104.tabexperiment"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.android.support:support-v4:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/toolbar"
        android:background="?attr/colorPrimary"
        android:minHeight="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:layout_below="@id/tab_layout"/>
</RelativeLayout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值