Android之ViewPager 第二课

在这里只粘贴部分代码

在第一课中,只有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://www.cnblogs.com/xiaotaoqi/p/5998845.html/>

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

时间: 2024-07-28 23:53:15

Android之ViewPager 第二课的相关文章

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

续第二课( 下) 续第二课 下 活动的生命周期 返回栈 活动状态 活动的生存期 体验活动的生命周期 活动被回收怎么办 活动的启动模式 standard singleTop singleTask singleInstance 实践出真知 知晓当前是哪一个活动 随时随地退出程序 启动活动的最佳写法 问题 写app必须掌握活动的生命周期. [活动的生命周期] [返回栈] android每次启动的活动会覆盖在原活动之上,然后点击Back键会销毁最上层的活动.是使用Task来管理活动,一个任务就是一组存放

【Android开发学习】【第二课】Activity学习(1)

什么是Activity,就是我们所看到的 需要理解以下四句话: 1.一个Activity就是一个类,并且这个类需要集成Activity: 2.需要重写OnCreat方法 3.每个Activity都需要在AndroidManifest.xml中进行配置 xml中加入了<intent-filter>说明应用程序启动时先运行这个Activity 4.为Activity添加必要的控件,就可以生成我们想要的界面 在res的layout下的xml就是布局文件 例如这样的: 代码: 效果: [Android

Android:ViewPager扩展详解——带有导航的ViewPagerIndicator(附带图片缓存,异步加载图片)

大家都用过viewpager了, github上有对viewpager进行扩展,导航风格更加丰富,这个开源项目是ViewPagerIndicator,很好用,但是例子比较简单,实际用起来要进行很多扩展,比如在fragment里进行图片缓存和图片异步加载. 下面是ViewPagerIndicator源码运行后的效果,大家也都看过了,我多此一举截几张图: 下载源码请点击这里 ===========================================华丽的分割线==============

Android高手速成--第二部分 工具库

主要包括那些不错的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容.多媒体相关及其他. 一.依赖注入DI 通过依赖注入减少View.服务.资源简化初始化,事件绑定等重复繁琐工作 AndroidAnnotations(Code Diet)android快速开发框架项目地址:https://github.com/excilys/androidannotations文档介绍:https://github.com/excilys/a

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

本文为那些不错的Android开源项目第二篇——开发工具库篇,主要介绍常用的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容.多媒体相关及其他. Android开源项目系列汇总已完成,包括: Android开源项目第一篇——个性化控件(View)篇 Android开源项目第二篇——工具库篇 Android开源项目第三篇——优秀项目篇 Android开源项目第四篇——开发及测试工具篇 Android开源项目第五篇——优秀个人和

IOS学习第二课 UIAlertView和UIActionSheet

1    UIAlertView 类似于Android中的Dialog,简单用法如下: UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Title" message:@"Messate" delegate:nil cancelButtonTitle:@"Cancle" otherButtonTitles:nil, nil]; [alertView show]; 2   U

安卓学习第二课——短信发送器

package com.example.message; import android.app.Activity; import android.os.Bundle; import android.telephony.SmsManager; import android.text.TextUtils; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;

【第二课】深入理解Handler

简要讲解Handler是做什么的 我们知道,在Android中,app启动会启动一个进程一个线程——UI线程,UI线程是主线程,并且不允许这个线程阻塞超过5秒,一旦超过5秒就会ANR. 所以较为耗时的工作(网络请求.文件读写)一般都是开一个线程来处理的,但其他的工作线程不可以直接操作Android的UI,UI只能在UI线程操作.所以就需要一个进程间通信机制来让工作线程的消息传递到UI线程,从而在UI线程改变UI. 这个通信机制就是Handler,普遍的做法就是通过重载Handler的handle

android的ViewPager和Animation的一些使用(一)

android的ViewPager是一个可以支持手势来切换View的控件,很适合来做用户引导的页面: 如果有4张图,那么我们这样来写Layout: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/whats_ne