在这里只粘贴部分代码

在第一课中,只有View滑动完毕,才触发动画效果,令滑块移动,在第二课中,将实现滑块与View同步运行。

SecondActivity.java

package com.android3;

import android.annotation.SuppressLint;
import android.content.Intent;
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.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View; import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import java.util.ArrayList;
import java.util.List; public class SecondActivity extends AppCompatActivity implements View.OnClickListener, ViewPager.OnPageChangeListener {
private ArrayList<View> viewList;
private ImageView cursor;
private float offset = 0;
private float screenW = 0;
private float eCurrentX = 0;
private Matrix matrix;
private float fScreenW = 0;
private int currentIndex = 0;
private int temp = 1;
private float sCurrentX;
private int len; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
initToolbar();
initViewPager();
} /**
* ViewPager 保证 缓存中存在三个视图,即 左边 右边 和中间 隔一个的灰被destroy,
*/
@SuppressLint("InflateParams")
private void initViewPager() {
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
LinearLayout titleBar = (LinearLayout) findViewById(R.id.titleBar);
LayoutInflater inflater = getLayoutInflater();
//创建四个View
View view1 = inflater.inflate(R.layout.viewpage_01, null);
View view2 = inflater.inflate(R.layout.viewpage_02, null);
View view3 = inflater.inflate(R.layout.viewpage_03, null);
View view4 = inflater.inflate(R.layout.viewpage_04, null); viewList = new ArrayList<>();// 将要分页显示的View装入数组中
viewList.add(view1);
viewList.add(view2);
viewList.add(view3);
viewList.add(view4);
len = viewList.size();
MyPagerAdapter adapter = new MyPagerAdapter(viewList);
List<String> titleList = new ArrayList<>();
titleList.add("第一页面");
titleList.add("第二页面");
titleList.add("第三页面");
titleList.add("第四页面");
for (int i = 0; i < titleList.size(); i++) {
TextView textView = new TextView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
params.weight = 1;
params.setMargins(5, 3, 5, 3);
textView.setLayoutParams(params);
textView.setText(titleList.get(i));
textView.setTextSize(15);
textView.setGravity(Gravity.CENTER);
titleBar.addView(textView);
} initCursorPos(); //初始化指示器位置 viewPager.setAdapter(adapter);//绑定适配器
viewPager.addOnPageChangeListener(this); //注 : setOnPageChangeListener 过时
} /**
* 单位px
*/
public void initCursorPos() {
// 初始化动画
cursor = (ImageView) findViewById(R.id.cursor);
float cursorW = BitmapFactory.decodeResource(getResources(), R.mipmap.cursor).getWidth();
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
screenW = dm.widthPixels;// 获取分辨率宽度
fScreenW = screenW / viewList.size();
offset = (fScreenW - cursorW) / 2;// 计算偏移量
matrix = new Matrix();
matrix.postTranslate(offset, 0);
cursor.setImageMatrix(matrix);// 设置动画初始位置 ###原始位置
} private void initToolbar() {
Toolbar mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setTitle("");
mToolbar.setNavigationIcon(R.mipmap.back);
setSupportActionBar(mToolbar);
mToolbar.setNavigationOnClickListener(this);
} @Override
public void onClick(View view) {
switch (view.getId()) {
case -1:
finish();
break;
}
} @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
sCurrentX = positionOffset * fScreenW;
if(position!=currentIndex){
temp=1;
currentIndex=position;
return;
}
if (temp == 0) {
matrix.postTranslate((sCurrentX - eCurrentX), 0);
cursor.setImageMatrix(matrix);
eCurrentX = sCurrentX; } else {
if (positionOffset > 0.5) {
eCurrentX = fScreenW;
} else {
eCurrentX = 0;
}
temp--;
}
currentIndex=position; } @Override
public void onPageSelected(int position) {
} @Override
public void onPageScrollStateChanged(int state) { }
}

下面详细介绍ViewPager.OnPageChangeListener监听器的三个重写方法:

当从手指按下,到页面滑动停止的过程:

首先系统调用onPageScrollStateChanged(int state)方法,其中state=1,表示开始滑动;

然后系统调用onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法,

position是当前页面的编号,positionOffset滑动百分比,取值范围[0,1],positionOffsetPixels滑动长度,取值[0,手机宽度(px)]

/*********************************************************************************/

在滑动过程中有这几个因素需要强调:

1、从左向右滑动   positionOffset和positionOffsetPixels初始值为0,并根据滑动距离增大;

2、从右向左滑动   positionOffset初始值为1,并根据滑动距离减小,positionOffsetPixels初始值为手机宽度,并根据滑动距离减小;

3、当position=0时,从右向左滑动,positionOffset和positionOffsetPixels始终为0;

4、当(position=页面总数-1)时,从左向右滑动,positionOffset和positionOffsetPixels始终为0;

/*********************************************************************************/
  可能在滑动过程中手指离开屏幕,这时系统再次调用onPageScrollStateChanged(int state)方法 state=2,当滑动肯定能到下一个页面时,

positionOffset和positionOffsetPixels都到达最大值,然后再次调用onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法,

这时position为新页面的编号,positionOffset和positionOffsetPixels置零;

最后再调用onPageScrollStateChanged(int state)方法 state=0;表示滑动停止;

所以onPageScrolled()方法中代码就解释的通了,

 sCurrentX = positionOffset * fScreenW;

fScreenW是滑块从一个标题滑向另一个标题的距离,sCurrentX是滑动页面时,滑块相对走的距离,

成员变量temp是区分滑动页面时是否是第一次调用onPageScrolled();并在第一次调用该方法时,判断是向左滑动还是向右滑动:

               if (positionOffset > 0.5) {
eCurrentX = fScreenW;
} else {
eCurrentX = 0;
}

滑动停止时,重置temp为1;

游标滑动采用 matrix.postTranslate((sCurrentX - eCurrentX), 0); cursor.setImageMatrix(matrix); 这两句代码,相对位移。

谢谢

可能在滑动过程中手指离开屏幕,这时系统再次调用onPageScrollStateChanged(int state)方法 state=2,

当滑动肯定能到下一个页面时,positionOffset和positionOffsetPixels都到达最大值,

然后再次调用onPageScrolled(int position, float positionOffset, int positionOffsetPixels)方法,

这时position为新页面的编号,positionOffset和positionOffsetPixels置零;

代码下载    http://download.csdn.net/detail/qq_25059501/9664066

作者: 小淘气儿

出处: http://www.cnblogs.com/xiaotaoqi/p/5998845.html/>

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出.

Android之ViewPager 第二课的更多相关文章

  1. Android OpenGL教程-第二课【转】

    第二课 你的第一个多边形: 在第一个教程的基础上,我们添加了一个三角形和一个四边形.也许你认为这很简单,但你已经迈出了一大步,要知道任何在OpenGL中绘制的模型都会被分解为这两种简单的图形. 读完了 ...

  2. Android之ViewPager 第一课

    想要了解Android新版本的的新特性,从头开始吧,这是Android3.0新加入的widget,以前也接触过,但是没有好好的研究过,今天写了一个小程序,研究一下ViewPager. 这个程序是支持左 ...

  3. Android内存泄漏第二课--------(集合中对象没清理造成的内存泄漏 )

    一.我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大.如果这个集合是static的话,那情况就更严重 ...

  4. android从放弃到坚持放弃第二课(下)

    续第二课( 下) 续第二课 下 活动的生命周期 返回栈 活动状态 活动的生存期 体验活动的生命周期 活动被回收怎么办 活动的启动模式 standard singleTop singleTask sin ...

  5. [转]Android开源项目第二篇——工具库篇

    本文为那些不错的Android开源项目第二篇--开发工具库篇,主要介绍常用的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容.多 ...

  6. Android中ViewPager+Fragment取消(禁止)预加载延迟加载(懒加载)问题解决方案

    转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53205878本文出自[DylanAndroid的博客] Android中Vie ...

  7. 【第二课】深入理解Handler

    简要讲解Handler是做什么的 我们知道,在Android中,app启动会启动一个进程一个线程——UI线程,UI线程是主线程,并且不允许这个线程阻塞超过5秒,一旦超过5秒就会ANR. 所以较为耗时的 ...

  8. Android开源项目第二篇——工具库篇

    本文为那些不错的Android开源项目第二篇——开发工具库篇,**主要介绍常用的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容 ...

  9. Kotlin入门第二课:集合操作

    测试项目Github地址: KotlinForJava 前文传送: Kotlin入门第一课:从对比Java开始 初次尝试用Kotlin实现Android项目 1. 介绍 作为Kotlin入门的第二课, ...

随机推荐

  1. 两台电脑在不同情况下ping的情况

    两台计算机(交叉连接) 同一网段 ,可以ping通.不同网段,不可以 两台计算机通过一台交换机连接 同一网段 ,可以ping通.不同网段,不可以.同一网段,同一Vlan,不可以. 综上:跨网段通信,必 ...

  2. 嵌入式:UCOSIII的使用(17.01.24补充)

    0.一些移植.系统相关 OS_CFG_APP.H /* --------------------- MISCELLANEOUS ------------------ */ #define OS_CFG ...

  3. 不再手写import - VSCode自动引入Vue组件和Js模块

    :first-child{margin-top:0!important}.markdown-body>:last-child{margin-bottom:0!important}.markdow ...

  4. 第13届景驰-埃森哲杯广东工业大学ACM程序设计大赛--K-密码

    链接:https://www.nowcoder.com/acm/contest/90/K 来源:牛客网 - 1.题目描述 ZiZi登录各种账号的时候,总是会忘记密码,所以他把密码都记录在一个记事本上. ...

  5. HTTP缓存初探

    缓存的作用 用户访问一个web页面的频率远高于web页面更新的频率,因此多数时候用户从服务器获取的html.js.css以及图片等内容都是相同的,如果每次访问都从服务器获取这些静态内容即降低了页面加载 ...

  6. javascript--select标签的添加删除功能的使用

    在网页开发中,常常遇见这种问题,给定两个框,A和B,和几个图片按钮,A中存在几个操作,点击图片按钮,填加至B中,或者从B中移除等,这种效果如何实现,本文加以总结. 几种效果图如下: 原始图:      ...

  7. vue组件的基本知识点

    1. 组件中 is 的特性: 有些 HTML 元素,诸如 <ul>.<ol>.<table> 和 <select>,对于哪些元素可以出现在其内部是有严格 ...

  8. css表格

    今天写某个平台的前端数据展示 主要使用表格展示 正好复习总结一下css的表格 首先说说thead.tbody.tfoot <thead></thead> <tbody&g ...

  9. .Net Core On Liunx 环境搭建之安装Mysql8

    上一篇文章安装了MongoDB紧接上一篇随笔,来进行MySql数据库的安装 服务器环境:阿里云云服务器,操作系统CentOS.7-x64 注:文章的图片是我从我的CSDN博客中直接粘贴过来的,不是扒的 ...

  10. JDK8新垃圾回收机制--G1垃圾回收机制

    G1全称是Garbage First Garbage Collector,使用G1的目的是简化性能优化的复杂性.例如,G1的主要输入参数是初始化和最大Java堆大小.最大GC中断时间. G1 GC由Y ...