Android自定义引导玩转ViewPager的方法详解

ViewPager简介:

ViewPager(android.support.v4.view.ViewPager)是android扩展包v4包中的类,这个类可以让用户左右切换当前的view,实现滑动切换的效果。

注意:

ViewPager类直接继承了ViewGroup类,也就是说它和我们经常打交道的LinearLayout一样,都是一个容器,需要在里面添加我们想要显示的内容。

  ViewPager类需要一个PagerAdapter适配器类给它提供数据,这个和ListView类似。

ViewPager基础使用

具体步骤:

1.在布局文件里加入

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

2.在Activity中加载要显示的Views,通过动态加载布局得到一个个View

  mViewList = new ArrayList<View>();
  LayoutInflater lf = getLayoutInflater().from(MainActivity.this);
  View view1 = lf.inflate(R.layout.we_indicator1, null);
  View view2 = lf.inflate(R.layout.we_indicator2, null);
  View view3 = lf.inflate(R.layout.we_indicator3, null);
  mViewList.add(view1);
  mViewList.add(view2);
  mViewList.add(view3);

3.自定义PagerAdapter,以便将步骤2中的Views数据加载到ViewPager容器中

public class ViewPagerAdatper extends PagerAdapter {
 private List<View> mViewList ;

 public ViewPagerAdatper(List<View> mViewList ) {
  this.mViewList = mViewList;
 }

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

 @Override
 public boolean isViewFromObject(View view, Object object) {
  return view==object;
 }

 @Override
 public Object instantiateItem(ViewGroup container, int position) {
  container.addView(mViewList.get(position));
  return mViewList.get(position);
 }

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

4.将ViewPager和自定义的PagerAdapter关联起来

mIn_vp.setAdapter(new ViewPagerAdatper(mViewList));

通过简单使用ViewPager,得到的展示效果,仅仅支持左右滑动,效果比较单一。

ViewPager进阶使用——实现跟随式小圆点效果

步骤:

1.添加小圆点

在布局中的设置如下:

<RelativeLayout
  android:id="@+id/rl_dots"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_alignParentBottom="true"
  android:layout_centerHorizontal="true"
  android:layout_marginBottom="60dp">

  <LinearLayout
   android:id="@+id/in_ll"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:orientation="horizontal">
  </LinearLayout>

  <ImageView
   android:id="@+id/iv_light_dots"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:src="@drawable/light_dot"/>
 </RelativeLayout>

随后在LinearLayout中动态添加3个小黑点,小白点默认覆盖在第一个小黑点的上面。

在Activity中的添加小黑点,代码如下:

private void addDots() {
  mOne_dot = new ImageView(this);
  mOne_dot.setImageResource(R.drawable.gray_dot);
  LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
  layoutParams.setMargins(0, 0, 40, 0);
  mIn_ll.addView(mOne_dot, layoutParams);
  mTwo_dot = new ImageView(this);
  mTwo_dot.setImageResource(R.drawable.gray_dot);
  mIn_ll.addView(mTwo_dot, layoutParams);
  mThree_dot = new ImageView(this);
  mThree_dot.setImageResource(R.drawable.gray_dot);
  mIn_ll.addView(mThree_dot, layoutParams);
  setClickListener();

 }

2.获得两个点之间的距离

实现小白点动态跟随的思路是:根据页面的移动情况,通过设置小白点的 leftMargin 实现小红点的动态跟随。因此首要的是获得两个点之间的距离,根据页面移动到的位置,进行相应的运算。

需要注意的是:在onCreate()中直接获得小白点的左边距 getLeft()结果为0,这是因为View组件布局要在onResume回调后完成。

因此使用另一种方法:

mLight_dots.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
      @Override
      public void onGlobalLayout() {
        //获得两个圆点之间的距离
        mDistance = mIn_ll.getChildAt(1).getLeft() - mIn_ll.getChildAt(0).getLeft();
        mLight_dots.getViewTreeObserver()
            .removeGlobalOnLayoutListener(this);
      }
    });

在布局发生改变或者某个视图的可视状态发生改变时调用该事件。但此方法会被多次调用,因此需要在获取到视图的宽度和高度后执行 remove 方法移除该监听事件。

3.监听页面的移动情况

 mIn_vp.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
      @Override
      public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        //页面滚动时小白点移动的距离,并通过setLayoutParams(params)不断更新其位置
        float leftMargin = mDistance * (position + positionOffset);
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mLight_dots.getLayoutParams();
        params.leftMargin = (int) leftMargin;
        mLight_dots.setLayoutParams(params);
      }

      @Override
      public void onPageSelected(int position) {
        //页面跳转时,设置小圆点的margin
        float leftMargin = mDistance * position;
        RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mLight_dots.getLayoutParams();
        params.leftMargin = (int) leftMargin;
        mLight_dots.setLayoutParams(params);
      }

      @Override
      public void onPageScrollStateChanged(int state) {

      }
    });
  }

在页面移动过程中,根据mDistance * (position + positionOffset) 可以实时更新小白点的位置

这部分内容加入了一个新的功能 点击小黑点 可以直接跳转到对应的引导页面,具体逻辑就是在小黑点的点击事件中加入如下代码:

 mIn_vp.setCurrentItem(1);

在页面选择过程中,根据mDistance * position可以实时小红点的位置

4.跳转按钮的实现

具体逻辑:到引导页到达最后一页时,跳转到主页的按钮出现。其他情况为隐藏状态
因此可以在onPageScrolled(int position, float positionOffset, int positionOffsetPixels)和onPageSelected(int position)方法中加入如下代码:

         if(position==2){
          mBtn_next.setVisibility(View.VISIBLE);
        }

当按照从第一页到最后一页,然后点击按钮跳转到首页,则以上逻辑足够。

但当用户浏览到最后一页后再回转到前面感兴趣的页面,则会出现按钮依旧出现的情况,不符合要求。因此要完善逻辑,加入新的判断,逻辑如下:

if(position!=2&&mBtn_next.getVisibility()==View.VISIBLE){
          mBtn_next.setVisibility(View.GONE);
        }

以上逻辑保证了按钮的正常显示,剩下的就可以具体操作,实现跳转到首页的逻辑。

ViewPager进阶使用——自定义炫酷动画

ViewPager自带了一个setPageTransformer用于设置切换动画~

setPageTransformer (boolean reverseDrawingOrder, PageTransformer transformer)需要传入两个参数

第一个参数:如果为true,则表明自定义的pageTransformer需要 page view从后到前的顺序绘制,反之则为false。

第二个参数:传入一个自定义的pageTransformer对象

因此实现炫酷动画的关键点就在于:自定义pageTransformer

Google官方给我们展示了两个动画例子:DepthPageTransformer和ZoomOutPageTransformer,比较炫。我们就以Google官方的例子来学习自定义pageTransformer,以此为基础,我们可以自定义各种各样的动画实现效果。

1.PageTransformer中position解析

自定义PageTransformer只需要实现一个方法,transformPage(View page, float position),而这个方法实现的关键就是对position的理解。

源码中的注释解释如下:

Apply the transformation to this page

position - Position of page relative to the current front-and-center position of the pager. 0 is front and center. 1 is one full page position to the right, and -1 is one page position to the left.

我们可以理解为:

  • 0表示当前页面,是当前页面
  • -1表示左侧的页面,是左侧页面
  • 1表示右侧的页面,是右侧页面

在用户滑动界面的时候,position是动态变化的,下面以左滑为例:

  • 选中页面 position:0->-1
  • 前一个item position:-1 -> -2
  • 后一个item position:1 -> 0

但是当ViewPager设置pageMargin,设置两个页面之间的距离(通过调用viewPager.setPageMargin()方法设置)后,情况则不同。

如果你设置了pageMargin,前后页面的position需要分别加上(或减去,前减后加)一个偏移量(偏移量的计算方式为pageMargin / pageWidth)。

同样以左滑为例:

  • 选中页面position:0->-1 - pageMargin / pageWidth
  • 前一个item position:-1 - pageMargin / pageWidth -> -2 - pageMargin / pageWidth
  • 后一个item position:1 + pageMargin / pageWidth -> 0

因此我们可以将position的值应用于setAlpha(), setTranslationX(), 或者 setScaleY()等等方法,从而实现自定义的动画效果。

2.实现transformPage(View page, float position)方法

public class DepthPageTransformer implements ViewPager.PageTransformer {
  private static final float MIN_SCALE = 0.75f;
  @Override
  public void transformPage(View page, float position) {
    int pageWidth = page.getWidth();
    if (position < -1) { // [-Infinity,-1)
      // 页面远离左侧页面
      page.setAlpha(0);
    } else if (position <= 0) { // [-1,0]
      // 页面在由中间页滑动到左侧页面 或者 由左侧页面滑动到中间页
      page.setAlpha(1);
      page.setTranslationX(0);
      page.setScaleX(1);
      page.setScaleY(1);
    } else if (position <= 1) { // (0,1]
      //页面在由中间页滑动到右侧页面 或者 由右侧页面滑动到中间页
      // 淡入淡出效果
      page.setAlpha(1 - position);
      // 反方向移动
      page.setTranslationX(pageWidth * -position);
      // 0.75-1比例之间缩放
      float scaleFactor = MIN_SCALE
          + (1 - MIN_SCALE) * (1 - Math.abs(position));
      page.setScaleX(scaleFactor);
      page.setScaleY(scaleFactor);
    } else { // (1,+Infinity]
      // 页面远离右侧页面
      page.setAlpha(0);
    }

  }
}

Github代码地址

以上是一些ViewPager做引导页做用的到一些知识点,希望和大家分享共同学习。由于水平有限,有什么不对的地方欢迎指正。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • Android开发实现的ViewPager引导页功能(动态加载指示器)详解

    本文实例讲述了Android开发实现的ViewPager引导页功能(动态加载指示器).分享给大家供大家参考,具体如下: 先看效果图咯~ 现在几乎每个App都会有引导页,是不是感觉很炫很厉害,所以就想做出来一个学习一下~让自己的App看起来更加的美观~ 现在来分析一下: 这个引导页可以分为俩部分~ 1.小红点--来提醒这是第几页了~ 2."开始体验"这个Button--可以进入主界面,但是要控制这个Button只能在最后一页出现 布局的话使用相对布局~ 那现在来看看布局吧: activi

  • Android启动引导页使用ViewPager实现

    我们在安装某个APP的时候,基本都会有一个引导页的提示,他们可以打广告,或者介绍新功能的加入和使用说明等. 一般都支持滑动并且下面有几个点,显示共有多少页和当前图片的位置,在IOS上这个实现起来比较简单,但在安卓上如何实现呢. 今天就和大家一起来学习用官方v4支持包下的ViewPager来实现这个效果. 先上图: 下面是我的实现,一个xml布局,一个GuideActivity和一个GuidePageAdapter.  先上XML. <?xml version="1.0" enco

  • Android UI设计与开发之ViewPager仿微信引导界面以及动画效果

    基于前两篇比较简单的实例做铺垫之后,这一篇我们来实现一个稍微复杂一点的引导界面的效果,当然也只是稍微复杂了一点,对于会的人来说当然还是so easy!正所谓会者不难,难者不会,大概说的就是这个意思了吧.好的,话不多说,回归正题. 这篇要实现的是一个仿微信的动画效果,虽然这种效果的实现在网上到处都有,但是我还是想站在中低端开发者的角度去告诉大家是如何实现的,当然实现的方式有很多,我也只是列出了我认为实现起来比较方便的一种方法,希望大家能够受用. 一.实现的效果图 有图才有真相,上图先: 点击按钮后

  • Android UI设计与开发之ViewPager介绍和简单实现引导界面

    做Android开发加起来差不多也有一年多的时间了,总是想写点自己在开发中的心得体会与大家一起交流分享.共同进步,刚开始写也不知该如何下手,仔细想了一下,既然是刚开始写,那就从一个软件给人最直观的感受--UI设计开始写起吧,循序渐进,娓娓道来.博主在这里和大家一起学习,希望能多多支持,话不多说,下面就开始讲解UI设计的第一篇. 在讲解如何实现引导界面的效果之前,我想先详细介绍一下ViewPager类的使用和说明,因为这是开发引导界面最重要的类,没有之一. 一.ViewPager实现的效果图 二.

  • android使用ViewPager组件实现app引导查看页面

    我们安装完app后第一次打开app,通常都会有一个翻页图片形式的app引导简介说明.下面我们来实现这个功能.ViewPager这个组件与ListView和RecyclerView在使用上有很高的相似处,所以你如果学习过以上两种列表滚动控件,可以基于它们帮助你理解ViewPager的使用. 实现步骤: 1.在左右滑动页面的界面中,通常在屏幕下方都会有一个小圆点,我们需要给这些小圆点的实现准备一些东西.在drawable目录下创建两个xml文件,一个画出未选中的圆点,一个画出选中后的圆点. 2.准备

  • Android利用ViewPager实现用户引导界面效果的方法

    本文实例讲述了Android利用ViewPager实现用户引导界面效果.分享给大家供大家参考,具体如下: 我相信有很多朋友在装完软件首次打开时,有很多软件都有一个软件功能介绍, 例如刚装完微信打开它,有很多介绍微信功能的图片,并且在屏幕下方有很多小圆点提示你当前图片的位置. 今天我就来实现这么个功能 所实现的功能: 1.可以左右滑动功能图片. 2.图片的索引 看出当前图片所在的位置. 3.可循环滑动. 4.图片的索引带有动画效果. 本次学习主要是利用ViewPager实现用户引导界面 在这里,我

  • Android UI设计与开发之使用ViewPager实现欢迎引导页面

    本系列文章都会以一个程序的实例开发为主线来进行讲解,以求达到一个循序渐进的学习效果,这样更能加深大家对于程序为什么要这样写的用意,理论加上实际的应用才能达到事半功倍的效果,不是吗? 最下方有源码的下载地址,几乎源码的每一行都有注释,写的通俗易懂,非常清晰,如有不懂的可以留言,本博主一定尽心尽力,为大家答题解惑,希望大家多多支持,好的,话不多说,让我们回归到今天的正题. 一.实现的效果图 也许是养成了这样一个习惯,每次看别人的代码前,必须要先看实现的效果图达到了一个什么样的效果,是不是跟自己想要实

  • Android开发实战之漂亮的ViewPager引导页

    目前很多软件安装时都会出现引导页面,用户体验很好. 下面就来DIY下: 因为视频上传很麻烦,所以截图了. 首先看看效果图: 点击小点可自由切换,滑动也可以自由切换,最后一个导航页添加了点击跳转. 开始实现引导页: 一.采集需要的图片放入drawable文件里 二.初始化每个导航页的视图 import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.suppo

  • Android控件ViewPager实现带有动画的引导页

    ViewPager实现带有动画的引导页,供大家参考,具体内容如下 好了,又到我们学习基础控件的时候了,其实引导页很简单,就是五张图片而已 一.ViewPager实现传统的引导页 传统的ViewPager实现引导页和ListView是一样道理的,只是把ListView的Item换成图片,把BaseAdapter换成PagerAdapter,我们先来看下传统引导页的效果图 步骤一:编写xml文件 既然用到的是ViewPager,那么xml文件就必须要有ViewPager,细心的你,可能会发现最后一页

  • Android自定义引导玩转ViewPager的方法详解

    ViewPager简介: ViewPager(android.support.v4.view.ViewPager)是android扩展包v4包中的类,这个类可以让用户左右切换当前的view,实现滑动切换的效果. 注意: ViewPager类直接继承了ViewGroup类,也就是说它和我们经常打交道的LinearLayout一样,都是一个容器,需要在里面添加我们想要显示的内容. ViewPager类需要一个PagerAdapter适配器类给它提供数据,这个和ListView类似. ViewPage

  • Android自定义View实现绘制虚线的方法详解

    前言 说实话当第一次看到这个需求的时候,第一反应就是Canvas只有drawLine方法,并没有drawDashLine方法啊!这咋整啊,难道要我自己做个遍历不断的drawLine?不到1秒,我就放弃这个想法了,因为太恶心了.方法肯定是有的,只不过我不知道而已. 绘制方法 最简单的方法是利用ShapeDrawable,比如说你想用虚线要隔开两个控件,就可以在这两个控件中加个View,然后给它个虚线背景. 嗯,理论上就是这样子的,实现上也很简单. <!-- drawable 文件 --> <

  • Android自定义指示器时间轴效果实例代码详解

    指示器时间轴在外卖.购物类的APP里会经常用到,效果大概就像下面这样,看了网上很多文章,大都是自己绘制,太麻烦,其实通过ListView就可以实现. 在Activity关联的布局文件activity_main.xml中放置一个ListView,代码如下.由于这个列表只是用于展示信息,并不需要用户去点击,所以将其clickable属性置为false:为了消除ListView点击产生的波纹效果,我们设置其listSelector属性的值为透明:我们不需要列表项之间的分割线,所以设置其divider属

  • Android自定义View中attrs.xml的实例详解

    Android自定义View中attrs.xml的实例详解 我们在自定义View的时候通常需要先完成attrs.xml文件 在values中定义一个attrs.xml 然后添加相关属性 这一篇先详细介绍一下attrs.xml的属性. <?xml version="1.0" encoding="utf-8"?> <resources> //自定义属性名,定义公共属性 <attr name="titleText" for

  • Android ListView监听滑动事件的方法(详解)

    ListView的主要有两种滑动事件监听方法,OnTouchListener和OnScrollListener 1.OnTouchListener OnTouchListener方法来自View中的监听事件,可以在监听三个Action事件发生时通过MotionEvent的getX()方法或getY()方法获取到当前触摸的坐标值,来对用户的滑动方向进行判断,并可在不同的Action状态中做出相应的处理 mListView.setOnTouchListener(new View.OnTouchLis

  • Android AsyncTask实现异步处理任务的方法详解

    Android AsyncTask实现异步处理任务的方法详解 在开发Android应用时必须遵守单线程模型的原则:Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行. Android 单线程模型概念详解:http://www.jb51.net/article/112165.htm 在单线程模型中始终要记住两条法则: 不要阻塞UI线程 确保只在UI线程中访问Android UI工具包 当一个程序第一次启动时,Android会同时启动一个对应的主线程(Main Thread),

  • Android中实现ping功能的多种方法详解

    使用java来实现ping功能. 并写入文件.为了使用java来实现ping的功能,有人推荐使用java的 Runtime.exec()方法来直接调用系统的Ping命令,也有人完成了纯Java实现Ping的程序,使用的是Java的NIO包(native io, 高效IO包).但是设备检测只是想测试一个远程主机是否可用.所以,可以使用以下三种方式来实现: 1. Jdk1.5的InetAddresss方式 自从Java 1.5,java.net包中就实现了ICMP ping的功能. 使用时应注意,如

  • Android Flutter实现GIF动画效果的方法详解

    目录 前言 交错动画机制 代码实现 Interval 介绍 总结 前言 我们之前介绍了不少有关动画的篇章.前面介绍的动画都是只有一个动画效果,那如果我们想对某个组件实现一组动效,比如下面的效果,该怎么办? staggered animation 这个时候我们需要用到组合动效, Flutter 提供了交错动画(Staggered Animation)的方式实现.对于多个 Anmation 对象,可以共用一个 AnimationController,然后在不同的时间段执行动画效果.这就有点像 GIF

  • Android中View的炸裂特效实现方法详解

    本文实例讲述了Android中View的炸裂特效实现方法.分享给大家供大家参考,具体如下: 前几天微博上被一个很优秀的 Android 开源组件刷屏了 - ExplosionField,效果非常酷炫,有点类似 MIUI 卸载 APP 时的动画,先来感受一下. ExplosionField 不但效果很拉风,代码写得也相当好,让人忍不住要拿来好好读一下. 创建 ExplosionField ExplosionField 继承自 View,在 onDraw 方法中绘制动画特效,并且它提供了一个 att

  • Android编程实现列表侧滑删除的方法详解

    本文实例讲述了Android编程实现列表侧滑删除的方法.分享给大家供大家参考,具体如下: 前言:今天突然想起来了列表的滑动删除功能,一些下拉刷新的框架也会带这个侧滑删除的功能,比如一些listview的和recycleview的刷新框架都有这个功能,我今天写这个博客的目的是如何不依赖这些框架也是实现侧滑删除,如果自己已经使用的列表框架没有侧滑删除怎么给单独加入侧滑删除功能. 概括:我今天写的这个文章就是讲的是怎么单独给列表加入侧滑删除功能,不去为了侧滑删除而依赖一个列表框架,就是说如果需要的话可

随机推荐

其他