为了账号安全,请及时绑定邮箱和手机立即绑定

Android零基础入门第70节:ViewPager轻松完成TabHost效果

标签:
Android

   上一期学习了ViewPager的简单使用,本期一起来学习ViewPager的更多用法。

                                              

    相信很多同学都使用过今日头条APP吧,一打开主界面就可以看到顶部有很多Tab,然后通过左右滑动来切换,就可以通过ViewPager来完成。当然具体实现又会有很多方式,我们本期就先来学习最简单的Tab切换吧,有一点类似于之前了解的TabHost。

一、PagerTitleStrip与PagerTabStrip

    在实际运用中,很多时候只有页面滑动是不够的,还需要有标题栏才够友好。首先来学习一下官方自带的,在android.support.v4包中的两个控件PagerTabStrip与PagerTitleStrip。

    上面提到的2个控件,其中PagerTitleStrip是普通文字,PagerTabStrip带有下划线。PagerTabStrip在效果上包含了PagerTitleStrip。

    如果只添加PagerTabStrip可以看到只有线,但是它占的布局是有一定高度的,而且默认是不显示标题的,如果要显示出来,需在适配器里重写getPageTitle(int position)方法。关于标题及这条线的颜色,和整个标识View的背景,都可以在代码里设置。

    还有一个区别就是,PagerTabStrip可以点击切换View,而PagerTitleStrip不能点击。

    接下来通过一个案例来学习PagerTabStrip的使用。

    继续再上一期的案例基础上来进行修改,首先修改viewpager_layout.xml文件,修改后的代码如下:

[代码]xml代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

              android:orientation="vertical"

              android:layout_width="match_parent"

              android:layout_height="match_parent">

 

    <android.support.v4.view.ViewPager

        android:id="@+id/view_pager"

        android:layout_width="match_parent"

        android:layout_height="wrap_content">

 

        <android.support.v4.view.PagerTabStrip

            android:id="@+id/view_pager_tabstrip"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content" />

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

</LinearLayout>

    然后几个页面布局文件不变,既然需要在顶部显示Tab和标题,那就需要我们通过适配器来设置,修改后的ViewPagerAdapter类代码如下:

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

package com.jinyu.cqkxzsxy.android.advancedviewsample.adapter;

 

import android.support.v4.view.PagerAdapter;

import android.view.View;

import android.view.ViewGroup;

 

import java.util.ArrayList;

 

/**

 * @创建者 鑫鱻

 * @描述 Android零基础入门到精通系列教程

 * 首发微信公众号分享达人秀(ShareExpert)

 */

public class ViewPagerAdapter   extends PagerAdapter   {

    private ArrayList<view> mPageLists = null;

    private ArrayList<string> mTitleLists = null;

 

    public ViewPagerAdapter(ArrayList<view>   pageLists, ArrayList<string> titleLists) {

        this.mPageLists   = pageLists;

        this.mTitleLists   = titleLists;

    }

 

    @Override

    public int getCount() {

        return (null == mPageLists) ? 0 :mPageLists.size();

    }

 

    @Override

    public boolean isViewFromObject(View view, Object object) {

        return view == object;

    }

 

    @Override

    public Object instantiateItem(ViewGroup   container, int position)   {

        View   pageView = mPageLists.get(position);

        container.addView(pageView);

        return pageView;

    }

 

    @Override

    public void destroyItem(ViewGroup container, int position, Object object) {

        //   将当前位置的View移除

        container.removeView(mPageLists.get(position));

    }

 

    @Override

    public CharSequence getPageTitle(int position) {

        return (null == mTitleLists && position < mTitleLists.size())

                ?   null :   mTitleLists.get(position);

    }

}

</string></view></string></view>

    接着修改ViewPagerActivity,修改的代码如下:

[代码]java代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

package com.jinyu.cqkxzsxy.android.advancedviewsample;

 

import android.graphics.Color;

import android.os.Bundle;

import android.support.v4.view.PagerTabStrip;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.view.LayoutInflater;

import android.view.View;

import android.widget.Toast;

 

import com.jinyu.cqkxzsxy.android.advancedviewsample.adapter.ViewPagerAdapter;

 

import java.util.ArrayList;

 

/**

 * @创建者 鑫鱻

 * @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert

 */

public class ViewPagerActivity   extends AppCompatActivity   implements ViewPager.OnPageChangeListener   {

    private ViewPager mViewPager = null;

    private PagerTabStrip mPagerTabStrip = null;

    private ViewPagerAdapter mAdapter = null;

    private ArrayList<view> mPageLists = null;

    private ArrayList<string> mTitleLists = null;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.viewpager_layout);

 

        mViewPager   = (ViewPager) findViewById(R.id.view_pager);

        mPagerTabStrip   = (PagerTabStrip) findViewById(R.id.view_pager_tabstrip);

 

        //   装入分页显示hi的View视图

        mPageLists   = new ArrayList<>();

        LayoutInflater   inflater = getLayoutInflater();

        mPageLists.add(inflater.inflate(R.layout.viewpager_page1,   null, false));

        mPageLists.add(inflater.inflate(R.layout.viewpager_page2,   null, false));

        mPageLists.add(inflater.inflate(R.layout.viewpager_page3,   null, false));

        mPageLists.add(inflater.inflate(R.layout.viewpager_page4,   null, false));

        //   装入每个页面的Title

        mTitleLists   = new ArrayList<>();

        mTitleLists.add("第一页");

        mTitleLists.add("第二页");

        mTitleLists.add("第三页");

        mTitleLists.add("第四页");

 

        mAdapter   = new ViewPagerAdapter(mPageLists,   mTitleLists);

        mViewPager.setAdapter(mAdapter);

 

        //   更改下划线颜色

        mPagerTabStrip.setTabIndicatorColor(Color.BLUE);

        mViewPager.addOnPageChangeListener(this);

    }

 

    @Override

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

 

    }

 

    @Override

    public void onPageSelected(int position) {

        Toast.makeText(this,   "第" + (position + 1) + "页", Toast.LENGTH_SHORT).show();

    }

 

    @Override

    public void onPageScrollStateChanged(int state) {

 

    }

}

</string></view>

    重新运行程序,可以看到界面中已经出现了久违的Tab和标题,左右滑动页面也可以看到Tab处的线条跟随改变,

    从上面的案例可以发现,PagerTabStrip是ViewPager的一个关于当前页面、上一个页面和下一个页面的一个可交互的指示器。其默认显示在顶部,还可以通过android:layout_gravity 属性设置为TOP或BOTTOM将它显示在ViewPager的顶部或底部。

    关于PagerTitleStrip的使用,和PagerTabStrip基本差不多,只是布局文件中ViewPager包含的控件不同而已,这里就不再详细说明了,建议自己动手练习,如果有问题,欢迎进Android入门讨论群一起探讨。

二、自定义实现

    上面我们使用了系统自带的控件来完成Tab显示,可能有的同学已经发现其与TabHost还是有一定的差别的,上面的Tab只显示3个,而且也不能完全满足实际需求,就需要我们自定义来实现了。

    接下来依然通过一个案例来学习如何自定义ViewPager的Tab标签。

    继续使用WidgetSample工程的advancedviewsample模块,在src/main/res/layout/目录下创建viewpager_custom_layout.xml文件,在其中填充如下代码片段:

[代码]xml代码:

?

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

<?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">

 

    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="48dp"

        android:background="#FFFFFF">

 

        <TextView

            android:id="@+id/viewpager_tv_one"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:layout_weight="1.0"

            android:gravity="center"

            android:text="第一页"

            android:textColor="#000000" />

 

        <TextView

            android:id="@+id/viewpager_tv_two"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:layout_weight="1.0"

            android:gravity="center"

            android:text="第二页"

            android:textColor="#000000" />

 

        <TextView

            android:id="@+id/viewpager_tv_three"

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:layout_weight="1.0"

            android:gravity="center"

            android:text="第三页"

            android:textColor="#000000" />

    </LinearLayout>

 

    <ImageView

        android:id="@+id/cursor_img"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:scaleType="matrix"

        android:class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="@drawable/line" />

 

    <android.support.v4.view.ViewPager

        android:id="@+id/view_pager"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        android:layout_gravity="center"

        android:flipInterval="30"

        android:persistentDrawingCache="animation" />

 

</LinearLayout>

    在页面顶部有一个线性布局,里面包含3个TextView,也就是ViewPager顶部的3个Tab标签。然后下面紧跟一个ImageView,主要用于指示当前是哪一个Tab标签对应的页面,也就是常说的滑块。最后在最底下是一个ViewPager,其中android:flipInterval属性设置了动画的时间间隔,android:persistentDrawingCache属性指控件的绘制缓存策略,一共有4个可选值,或者选择2个进行组合,分别如下:

·         none:不在内存中保存绘图缓存。

·         animation:只保存动画绘图缓存。

·         scrolling:只保存滚动效果绘图缓存。

·         all:所有的绘图缓存都应该保存在内存中。

    然后新建几个页面文件,这里继续使用上一期ViewPager快速实现引导页里面的页面文件,同样使用相同的适配器ViewPagerAdapter。

    最后新建ViewPagerCustomActivity.java文件,加载上面新建的布局文件,具体代码如下:

[代码]java代码:

?

001

002

003

004

005

006

007

008

009

010

011

012

013

014

015

016

017

018

019

020

021

022

023

024

025

026

027

028

029

030

031

032

033

034

035

036

037

038

039

040

041

042

043

044

045

046

047

048

049

050

051

052

053

054

055

056

057

058

059

060

061

062

063

064

065

066

067

068

069

070

071

072

073

074

075

076

077

078

079

080

081

082

083

084

085

086

087

088

089

090

091

092

093

094

095

096

097

098

099

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

package com.jinyu.cqkxzsxy.android.advancedviewsample;

 

import android.graphics.BitmapFactory;

import android.graphics.Matrix;

import android.os.Bundle;

import android.support.v4.view.ViewPager;

import android.support.v7.app.AppCompatActivity;

import android.util.DisplayMetrics;

import android.view.LayoutInflater;

import android.view.View;

import android.view.animation.Animation;

import android.view.animation.TranslateAnimation;

import android.widget.ImageView;

import android.widget.TextView;

 

import com.jinyu.cqkxzsxy.android.advancedviewsample.adapter.ViewPagerAdapter;

 

import java.util.ArrayList;

 

/**

 * @创建者 鑫鱻

 * @描述 Android零基础入门到精通系列教程,欢迎关注微信公众号ShareExpert

 */

public class ViewPagerCustomActivity   extends AppCompatActivity

        implements ViewPager.OnPageChangeListener,   View.OnClickListener {

    private ViewPager mViewPager = null;

    private ImageView mCursorImg = null;

    private TextView mOneTv = null;

    private TextView mTwoTv = null;

    private TextView mThreeTv = null;

 

    private ViewPagerAdapter mAdapter = null;

    private ArrayList<view> mPageList = null;

 

    private int mOffset = 0;// 移动条图片的偏移量

    private int mCurrIndex = 0; // 当前页面的编号

    private int mOneDis = 0; // 移动条滑动一页的距离

    private int mTwoDis = 0; // 滑动条移动两页的距离

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.viewpager_custom_layout);

 

        //   获取界面组件

        mViewPager   = (ViewPager) findViewById(R.id.view_pager);

        mCursorImg   = (ImageView) findViewById(R.id.cursor_img);

        mOneTv   = (TextView) findViewById(R.id.viewpager_tv_one);

        mTwoTv   = (TextView) findViewById(R.id.viewpager_tv_two);

        mThreeTv   = (TextView) findViewById(R.id.viewpager_tv_three);

 

        //   初始化指示器位置

        initCursorPosition();

 

        mPageList   = new ArrayList<>();

        LayoutInflater   inflater = getLayoutInflater();

        mPageList.add(inflater.inflate(R.layout.viewpager_page1,   null, false));

        mPageList.add(inflater.inflate(R.layout.viewpager_page2,   null, false));

        mPageList.add(inflater.inflate(R.layout.viewpager_page3,   null, false));

 

        //   设置适配器

        mAdapter   = new ViewPagerAdapter(mPageList);

        mViewPager.setAdapter(mAdapter);

 

        //   文本框点击监听器

        mOneTv.setOnClickListener(this);

        mTwoTv.setOnClickListener(this);

        mThreeTv.setOnClickListener(this);

 

        //   页面改变监听器

        mViewPager.addOnPageChangeListener(this);

        //   初始默认第一页

        mViewPager.setCurrentItem(0);

    }

 

    private void initCursorPosition() {

        //   获取指示器图片宽度

        int cursorWidth =   BitmapFactory.decodeResource(getResources(), R.drawable.line).getWidth();

 

        //   获取分辨率宽度

        DisplayMetrics   dm = new DisplayMetrics();

        getWindowManager().getDefaultDisplay().getMetrics(dm);

        int screenWidth = dm.widthPixels;

 

        //   计算偏移量

        mOffset   = (screenWidth / 3 - cursorWidth) / 2;

 

        //   设置动画初始位置

        Matrix   matrix = new Matrix();

        matrix.postTranslate(mOffset,   0);

        mCursorImg.setImageMatrix(matrix);

 

        //   计算指示器图片的移动距离

        mOneDis   = mOffset * 2 +   cursorWidth;// 页卡1 -> 页卡2 偏移量

        mTwoDis   = mOneDis * 2;// 页卡1 -> 页卡3 偏移量

    }

 

    @Override

    public void onClick(View v) {

        switch (v.getId()) {

            case R.id.viewpager_tv_one:

                mViewPager.setCurrentItem(0);

                break;

            case R.id.viewpager_tv_two:

                mViewPager.setCurrentItem(1);

                break;

            case R.id.viewpager_tv_three:

                mViewPager.setCurrentItem(2);

                break;

        }

    }

 

    @Override

    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

 

    }

 

    @Override

    public void onPageSelected(int position) {

        //   指示器图片动画设置

        Animation   animation = null;

        switch (position) {

            case 0:

                if (1 == mCurrIndex) {

                    animation   = new TranslateAnimation(mOneDis,   0, 0, 0);

                }   else if (2 == mCurrIndex) {

                    animation   = new TranslateAnimation(mTwoDis,   0, 0, 0);

                }

                break;

            case 1:

                if (0 == mCurrIndex) {

                    animation   = new TranslateAnimation(mOffset,   mOneDis, 0, 0);

                }   else if (2 == mCurrIndex) {

                    animation   = new TranslateAnimation(mTwoDis,   mOneDis, 0, 0);

                }

                break;

            case 2:

                if (0 == mCurrIndex) {

                    animation   = new TranslateAnimation(mOffset,   mTwoDis, 0, 0);

                }   else if (1 == mCurrIndex) {

                    animation   = new TranslateAnimation(mOneDis,   mTwoDis, 0, 0);

                }

                break;

            default:

                break;

        }

        mCurrIndex   = position;

        animation.setFillAfter(true);   // True:图片停在动画结束位置

        animation.setDuration(300);

        mCursorImg.startAnimation(animation);

    }

 

    @Override

    public void onPageScrollStateChanged(int state) {

 

    }

}

</view>

    可以发现这里的代码和上期大致相同,只是在其中增加了滑块的位置及动画设置,为3个Tab标签监听了点击事件。其中initCursorPosition()方法主要初始化指示器图标的位置,需要根据屏幕宽度来计算游标显示位置。然后同样设置了页面监听器,主要根据滑动到的页面把游标滑动找指定位置。关于动画的这一块代码,可能有很多新人不太懂,不要太介意这个了,后续会专门进行学习,这里只需要知道可以这样使用就行。

    修改程序启动的Activity,运行程序,然后左右滑动屏幕或点击Tab标签,

    通过上面的学习,是不是发现开发一个这样的漂亮界面其实非常简单。除了系统自带的和上面的自定义方法,在实际开发中常会结合Fragment来一起开发,建议后期学完Fragment后再来进一步学习。

    除了学习的PagerAdapter适配器,还有另外2个FragmentPagerAdapter和FragmentStatePagerAdapter,主要也是结合Fragment一起使用的,这里先不做过多学习。

    今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

原文链接:http://www.apkbus.com/blog-205190-72820.html

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消