ViewPagerWithImageDemo【ViewPager如何判断滑动到第一页和最后一页以及弹出对话框功能】
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
记录viewpager滑动的时候弹出对话框的功能(关键功能是滑动弹出对话框后,隐藏对话框的时候当前页可以还原到原位置),顺便判断首页和最后一页。
效果图

代码分析
实现滑动后弹出对话框,然后对话框隐藏后当前页面还原到原位置的功能,关键代码如下:
/**ViewPage切换的事件监听
* http://blog.csdn.net/zhengxiaoyao0716/article/details/48805703*/
public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener
{
private boolean isNormalChange = false;//标明是否普通的上翻页和下翻页【默认为false,标明需要判断然后弹出对话框】
private int resetXPoint = 0;//获取弹出对话框,还原的scrollTo的X坐标值,默认是0.打开的是第几页,比如,如果是第二页,那么第二页的X坐标是0 + (2-1)*viwepager的宽度 /* 这个方法在手指操作屏幕的时候发生变化。有三个值:0(END),1(PRESS) , 2(UP) 。
* arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。
*/
@Override
public void onPageScrollStateChanged(int state) {
if(state == 1){
isNormalChange = false;
}
} /* 用户一次滑动,这个方法会持续调用N多次,直至某个View充满视图并且稳定住!(但具体调用次数也不确定,尤其在首末位置向边界滑动,如果Log一下,会看到出现调用不确定次数的打印,且positionOffset都为0.
* position 当前页面,及你点击滑动的页面【position为当前屏幕上所露出的所有View的Item取下限。比如,当前Item为3,轻轻向右滑动一下,2露出了一点点,那么position就是2;而如果向左滑动,露出的4比3大,那么只要3没完全隐匿,那么position就一直按照3算。】
* positionOffset 当前页面偏移的百分比【positionOffset是当前Item较大的那个View占视图的百分比,0-1,没有负数!当滑动结束时,onPageScrolled();最后一次调用,positionOffset为0。】
* positionOffsetPixels 当前页面偏移的像素位置
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //这里获取第一个值,用来判断是左滑还是右滑(如果viewpager的宽度 - positionOffsetPixels <= viewpager的宽度的一半,则代表往左滑动(上一页),反之右滑(下一页))
/*int positionOffsetPixelsTemp = - positionOffsetPixels;//获取需要偏移的数值(默认获取的是往右滑(下一页)的情况下的偏移值)
int viewPagerWidth = mViewPager.getWidth();
if(viewPagerWidth - positionOffsetPixels <= viewPagerWidth / 2){
positionOffsetPixelsTemp = viewPagerWidth - positionOffsetPixels;
}*/ /*
* 当第一页上翻页时:position = 0;currentItemIndex=0;positionOffset=0.0;positionOffsetPixels=0
* 普通上翻页时:position = 0;currentItemIndex=1-->0;positionOffset==0.99224806-->0.0;positionOffsetPixels=1024-->0
* 当最后一页下翻页时:position = 10;currentItemIndex=10;positionOffset=0.0;positionOffsetPixels=0
* 普通下翻页时:position = 9;currentItemIndex=9-->10;positionOffset=0.041666985-->0.9-->0.0;positionOffsetPixels=43-->1024-->0
* */ if(! isNormalChange){ if(position == mPictureBeanList.size() - 1 && position ==currentItemIndex && positionOffset == 0.0 && positionOffsetPixels == 0){
//在最后一页进行滑动
}else if(position == 0 && position ==currentItemIndex && positionOffset == 0.0 && positionOffsetPixels == 0){
//在第一页进行滑动
}else {
//判断是否数据(例如,标题)发生了改变,如果发生了改变,那么弹出对话框
PictureBean picBean = mPictureBeanList.get(currentItemIndex);
String oldPicTitle = picBean.getPicTitle();//旧的图片标题
String newPicTitle = mPicTitleEdt.getText().toString();//新的图片标题 boolean changed = newPicTitle.equals(oldPicTitle); if (changed) {
isNormalChange = true;//【如果数据没有发生改变,则代表是正常滑动】
}else{
mViewPager.setIsCanScroll(false);//禁止滑动
//弹出提示对话框
// 创建构建器
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
// 设置参数
builder.setTitle("提示")
.setMessage("标题发生了改变,是否保存?")
.setPositiveButton("保存", new DialogInterface.OnClickListener() {// 积极
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
mViewPager.setIsCanScroll(true);//允许滑动
mViewPager.scrollTo(resetXPoint,0);
uploadImgTitle();
}
}).setNegativeButton("不保存", new DialogInterface.OnClickListener() {// 消极
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
mViewPager.setIsCanScroll(true);//允许滑动
mViewPager.scrollTo(resetXPoint,0);
//还原标题
PictureBean pictureBean = mPictureBeanList.get(currentItemIndex);
mPicTitleEdt.setText(pictureBean.getPicTitle());
}
}).setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
mViewPager.setIsCanScroll(true);//允许滑动
mViewPager.scrollTo(resetXPoint,0);
}
});
builder.create().show();
}
}
}
} /* 这个方法有一个参数position,代表哪个页面被选中。
* 当用手指滑动翻页的时候,如果翻动成功了(滑动的距离够长),手指抬起来就会立即执行这个方法
* position就是当前滑动到的页面。
* 如果直接setCurrentItem翻页,那position就和setCurrentItem的参数一致,这种情况在onPageScrolled执行方法前就会立即执行。
*/
@Override
public void onPageSelected(int position) {
Log.w("why", "{MyOnPageChangeListener}{onPageSelected}position="+position);
Log.w("why", "{MyOnPageChangeListener}{onPageSelected}currentItemIndex="+currentItemIndex);
resetXPoint = resetXPoint + (position - currentItemIndex) * mViewPager.getWidth();
currentItemIndex = position;
showPageNum();//设置页码
}
}
使用步骤
一、项目组织结构图


注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
(1)实现ViewpAger基础框架搭建
1、将MyCustomViewPager复制到项目中
package com.why.project.viewpagerwithimagedemo.viewpager; import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View; /**
* Created by HaiyuKing
* Used 自定义的viewpager
* https://www.cnblogs.com/tangs/articles/5933233.html
* 解决切换需要经过中间页的问题;
* 实现控制viewpager是否可滑动;
* 解决视频播放器和viewpager滑动冲突问题【可扩展到任何view】;
*/ public class MyCustomViewPager extends ViewPager { /**是否可以滑动:默认可以滑动*/
private boolean isCanScroll = true; public MyCustomViewPager(Context context) {
super(context);
} public MyCustomViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
} /**
* 解决切换需要经过中间页
*/
@Override
public void setCurrentItem(int item) {
//super.setCurrentItem(item);源码
super.setCurrentItem(item,false);//smoothScroll false表示切换的时候,不经过两个页面的中间页
} /**
* 让ViewPager不能左右滑动
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
if(isCanScroll){
return super.onTouchEvent(ev);
}else{
return false;
}
} @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if(isCanScroll){
return super.onInterceptTouchEvent(ev);
}else{
return false;
}
} /**
* 暴露出去的方法,屏蔽ViewPager的滑动,默认不可滑动
* @param isCanScroll 为true可以左右滑动,为false不可滑动
*/
public void setIsCanScroll(boolean isCanScroll){
this.isCanScroll = isCanScroll;
} @Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) { /*if (v instanceof IjkVideoView) {//解决视频播放器和viewpager滑动冲突问题
return true;
}*/
return super.canScroll(v, checkV, dx, x, y);
}
}
MyCustomViewPager.java
2、在activity布局文件中引用MyCustomViewPager【注意,MyCustomViewPager的完整路径需要根据实际情况修改】
<?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"
android:padding="8dp"> <!-- viewpager区域 -->
<com.why.project.viewpagerwithimagedemo.viewpager.MyCustomViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="0.0dp"
android:layout_weight="1"
android:clipChildren="false"
android:background="#ffffff"
android:layout_marginBottom="8dp"/> <EditText
android:id="@+id/edt_title"
android:layout_width="match_parent"
android:layout_height="48dp"/> <TextView
android:id="@+id/tv_page"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:layout_gravity="center"/> </LinearLayout>
3、编写viewpager内部的布局view_pager_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/img_pic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/app_name"
android:gravity="center"
android:src="@drawable/img_default"
android:scaleType="fitCenter"
android:background="#343434"
/>

4、添加集合item的bean类PictureBean
package com.why.project.viewpagerwithimagedemo.bean; /**
* Created by HaiyuKing
* Used
*/ public class PictureBean {
//图片ID值
private String picId = "";
//图片的res id值【这里模拟的是图片的url地址,所以使用的res id值进行代替】
private int picResId = 0;
//图片标题
private String picTitle = ""; public String getPicId() {
return picId;
} public void setPicId(String picId) {
this.picId = picId;
} public int getPicResId() {
return picResId;
} public void setPicResId(int picResId) {
this.picResId = picResId;
} public String getPicTitle() {
return picTitle;
} public void setPicTitle(String picTitle) {
this.picTitle = picTitle;
}
}
PictureBean.java
将演示用的图片资源复制到项目中

5、在activity中初始化viewpager并关联布局文件和集合数据【这只是一个基础的框架,后续还需要继续完善】
package com.why.project.viewpagerwithimagedemo; import android.content.Context;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView; import com.why.project.viewpagerwithimagedemo.bean.PictureBean;
import com.why.project.viewpagerwithimagedemo.viewpager.MyCustomViewPager; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private Context mContext; private EditText mPicTitleEdt;
private TextView mPageTv; /**中间viewpager区域*/
private MyCustomViewPager mViewPager;
/**ViewPager适配器*/
private MyViewPagerAdapter mViewPageAdapter;
//viewpager的数据集合
private ArrayList<PictureBean> mPictureBeanList;
/**viewpager中当前页面的下标值*/
private int currentItemIndex = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mContext = this; //初始化控件以及设置
initView();
//初始化数据
initData();
//初始化控件的点击事件
initEvent();
} @Override
public void onDestroy() {
mViewPager.removeAllViews();//防止内存泄漏
System.gc();//回收 super.onDestroy();
} private void initView() {
mPicTitleEdt = findViewById(R.id.edt_title);
mPageTv = findViewById(R.id.tv_page); mViewPager = (MyCustomViewPager) findViewById(R.id.view_pager);
mViewPager.setOffscreenPageLimit(3);//设置预加载的页数,之前是3【这个值指的是,当前view的左右两边的预加载的页面的个数。也就是说,如果这个值mOffscreenPageLimit = 3,那么任何一个页面的左边可以预加载3个页面,右边也可以加载3页面。】
} private void initData() {
//初始化数据
mPictureBeanList = new ArrayList<PictureBean>();
PictureBean bean0 = new PictureBean();
bean0.setPicId("pic0");
bean0.setPicTitle("图片1");
bean0.setPicResId(R.drawable.pic_0);
mPictureBeanList.add(bean0);
//
PictureBean bean1 = new PictureBean();
bean1.setPicId("pic1");
bean1.setPicTitle("图片2");
bean1.setPicResId(R.drawable.pic_1);
mPictureBeanList.add(bean1);
//
PictureBean bean2 = new PictureBean();
bean2.setPicId("pic0");
bean2.setPicTitle("图片3");
bean2.setPicResId(R.drawable.pic_2);
mPictureBeanList.add(bean2);
//
PictureBean bean3 = new PictureBean();
bean3.setPicId("pic3");
bean3.setPicTitle("图片4");
bean3.setPicResId(R.drawable.pic_3);
mPictureBeanList.add(bean3); //设置页码
if(mPictureBeanList.size() > 0){
showPageNum();
}
//填充viewpager数据
initViewPage();
} private void initEvent() { } //设置页码和标题输入框
private void showPageNum() {
mPageTv.setText((currentItemIndex+1) + "/" + mPictureBeanList.size()); String picTitle = mPictureBeanList.get(currentItemIndex).getPicTitle();
mPicTitleEdt.setText(picTitle);
} /**初始化viewpager配置*/
private void initViewPage(){
if(mViewPageAdapter == null){
mViewPageAdapter = new MyViewPagerAdapter();
mViewPager.setAdapter(mViewPageAdapter); mViewPager.addOnPageChangeListener(new MyOnPageChangeListener());//设置页面切换监听事件
mViewPager.setIsCanScroll(true);//允许滑动
}else{
mViewPageAdapter.notifyDataSetChanged();
}
mViewPager.setCurrentItem(currentItemIndex);
} /**ViewPager适配器*/
public class MyViewPagerAdapter extends PagerAdapter
{
/**这个方法,是从ViewGroup中移出当前View*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(((View)object));
} /**这个方法,是获取viewpager的界面数*/
@Override
public int getCount() {
return mPictureBeanList.size();
} public int getItemPosition(Object object) {
return POSITION_NONE;//-2
} /**这个方法,return一个对象,这个对象表明了PagerAdapter将选择将这个对象填充到在当前ViewPager里*/
@Override
public Object instantiateItem(ViewGroup container, int position){
View layout = LayoutInflater.from(mContext).inflate(R.layout.view_pager_layout, null);//将布局文件view添加到viewpager中
container.addView((View)layout); ImageView mPicImgView = layout.findViewById(R.id.img_pic);
mPicImgView.setImageResource(mPictureBeanList.get(position).getPicResId()); return layout;
} /**这个方法,在帮助文档中原文是could be implemented as return view == object,也就是用于判断是否由对象生成界面*/
@Override
public boolean isViewFromObject(View view, Object object) {
// TODO Auto-generated method stub
return view == object ? true : false;//官方提示这样写
}
@Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
} /**ViewPage切换的事件监听
* http://blog.csdn.net/zhengxiaoyao0716/article/details/48805703*/
public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener
{
/* 这个方法在手指操作屏幕的时候发生变化。有三个值:0(END),1(PRESS) , 2(UP) 。
* arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。
*/
@Override
public void onPageScrollStateChanged(int state) {
} /* 用户一次滑动,这个方法会持续调用N多次,直至某个View充满视图并且稳定住!(但具体调用次数也不确定,尤其在首末位置向边界滑动,如果Log一下,会看到出现调用不确定次数的打印,且positionOffset都为0.
* position 当前页面,及你点击滑动的页面【position为当前屏幕上所露出的所有View的Item取下限。比如,当前Item为3,轻轻向右滑动一下,2露出了一点点,那么position就是2;而如果向左滑动,露出的4比3大,那么只要3没完全隐匿,那么position就一直按照3算。】
* positionOffset 当前页面偏移的百分比【positionOffset是当前Item较大的那个View占视图的百分比,0-1,没有负数!当滑动结束时,onPageScrolled();最后一次调用,positionOffset为0。】
* positionOffsetPixels 当前页面偏移的像素位置
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
} /* 这个方法有一个参数position,代表哪个页面被选中。
* 当用手指滑动翻页的时候,如果翻动成功了(滑动的距离够长),手指抬起来就会立即执行这个方法
* position就是当前滑动到的页面。
* 如果直接setCurrentItem翻页,那position就和setCurrentItem的参数一致,这种情况在onPageScrolled执行方法前就会立即执行。
*/
@Override
public void onPageSelected(int position) {
currentItemIndex = position;
showPageNum();//设置页码
}
}
}
(2)实现滑动弹出对话框功能
package com.why.project.viewpagerwithimagedemo; import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView; import com.why.project.viewpagerwithimagedemo.bean.PictureBean;
import com.why.project.viewpagerwithimagedemo.viewpager.MyCustomViewPager; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { private Context mContext; private EditText mPicTitleEdt;
private TextView mPageTv; /**中间viewpager区域*/
private MyCustomViewPager mViewPager;
/**ViewPager适配器*/
private MyViewPagerAdapter mViewPageAdapter;
//viewpager的数据集合
private ArrayList<PictureBean> mPictureBeanList;
/**viewpager中当前页面的下标值*/
private int currentItemIndex = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mContext = this; //初始化控件以及设置
initView();
//初始化数据
initData();
//初始化控件的点击事件
initEvent();
} @Override
public void onDestroy() {
mViewPager.removeAllViews();//防止内存泄漏
System.gc();//回收 super.onDestroy();
} private void initView() {
mPicTitleEdt = findViewById(R.id.edt_title);
mPageTv = findViewById(R.id.tv_page); mViewPager = (MyCustomViewPager) findViewById(R.id.view_pager);
mViewPager.setOffscreenPageLimit(3);//设置预加载的页数,之前是3【这个值指的是,当前view的左右两边的预加载的页面的个数。也就是说,如果这个值mOffscreenPageLimit = 3,那么任何一个页面的左边可以预加载3个页面,右边也可以加载3页面。】
} private void initData() {
//初始化数据
mPictureBeanList = new ArrayList<PictureBean>();
PictureBean bean0 = new PictureBean();
bean0.setPicId("pic0");
bean0.setPicTitle("图片1");
bean0.setPicResId(R.drawable.pic_0);
mPictureBeanList.add(bean0);
//
PictureBean bean1 = new PictureBean();
bean1.setPicId("pic1");
bean1.setPicTitle("图片2");
bean1.setPicResId(R.drawable.pic_1);
mPictureBeanList.add(bean1);
//
PictureBean bean2 = new PictureBean();
bean2.setPicId("pic0");
bean2.setPicTitle("图片3");
bean2.setPicResId(R.drawable.pic_2);
mPictureBeanList.add(bean2);
//
PictureBean bean3 = new PictureBean();
bean3.setPicId("pic3");
bean3.setPicTitle("图片4");
bean3.setPicResId(R.drawable.pic_3);
mPictureBeanList.add(bean3); //设置页码
if(mPictureBeanList.size() > 0){
showPageNum();
}
//填充viewpager数据
initViewPage();
} private void initEvent() { } //设置页码和标题输入框
private void showPageNum() {
mPageTv.setText((currentItemIndex+1) + "/" + mPictureBeanList.size()); String picTitle = mPictureBeanList.get(currentItemIndex).getPicTitle();
mPicTitleEdt.setText(picTitle);
} /**初始化viewpager配置*/
private void initViewPage(){
if(mViewPageAdapter == null){
mViewPageAdapter = new MyViewPagerAdapter();
mViewPager.setAdapter(mViewPageAdapter); mViewPager.addOnPageChangeListener(new MyOnPageChangeListener());//设置页面切换监听事件
mViewPager.setIsCanScroll(true);//允许滑动
}else{
mViewPageAdapter.notifyDataSetChanged();
}
mViewPager.setCurrentItem(currentItemIndex);
} /**ViewPager适配器*/
public class MyViewPagerAdapter extends PagerAdapter
{
/**这个方法,是从ViewGroup中移出当前View*/
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView(((View)object));
} /**这个方法,是获取viewpager的界面数*/
@Override
public int getCount() {
return mPictureBeanList.size();
} public int getItemPosition(Object object) {
return POSITION_NONE;//-2
} /**这个方法,return一个对象,这个对象表明了PagerAdapter将选择将这个对象填充到在当前ViewPager里*/
@Override
public Object instantiateItem(ViewGroup container, int position){
View layout = LayoutInflater.from(mContext).inflate(R.layout.view_pager_layout, null);//将布局文件view添加到viewpager中
container.addView((View)layout); ImageView mPicImgView = layout.findViewById(R.id.img_pic);
mPicImgView.setImageResource(mPictureBeanList.get(position).getPicResId()); return layout;
} /**这个方法,在帮助文档中原文是could be implemented as return view == object,也就是用于判断是否由对象生成界面*/
@Override
public boolean isViewFromObject(View view, Object object) {
// TODO Auto-generated method stub
return view == object ? true : false;//官方提示这样写
}
@Override
public void notifyDataSetChanged()
{
super.notifyDataSetChanged();
}
} /**ViewPage切换的事件监听
* http://blog.csdn.net/zhengxiaoyao0716/article/details/48805703*/
public class MyOnPageChangeListener implements ViewPager.OnPageChangeListener
{
private boolean isNormalChange = false;//标明是否普通的上翻页和下翻页【默认为false,标明需要判断然后弹出对话框】
private int resetXPoint = 0;//获取弹出对话框,还原的scrollTo的X坐标值,默认是0.打开的是第几页,比如,如果是第二页,那么第二页的X坐标是0 + (2-1)*viwepager的宽度 /* 这个方法在手指操作屏幕的时候发生变化。有三个值:0(END),1(PRESS) , 2(UP) 。
* arg0 ==1的时辰默示正在滑动,arg0==2的时辰默示滑动完毕了,arg0==0的时辰默示什么都没做。
*/
@Override
public void onPageScrollStateChanged(int state) {
if(state == 1){
isNormalChange = false;
}
} /* 用户一次滑动,这个方法会持续调用N多次,直至某个View充满视图并且稳定住!(但具体调用次数也不确定,尤其在首末位置向边界滑动,如果Log一下,会看到出现调用不确定次数的打印,且positionOffset都为0.
* position 当前页面,及你点击滑动的页面【position为当前屏幕上所露出的所有View的Item取下限。比如,当前Item为3,轻轻向右滑动一下,2露出了一点点,那么position就是2;而如果向左滑动,露出的4比3大,那么只要3没完全隐匿,那么position就一直按照3算。】
* positionOffset 当前页面偏移的百分比【positionOffset是当前Item较大的那个View占视图的百分比,0-1,没有负数!当滑动结束时,onPageScrolled();最后一次调用,positionOffset为0。】
* positionOffsetPixels 当前页面偏移的像素位置
*/
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { //这里获取第一个值,用来判断是左滑还是右滑(如果viewpager的宽度 - positionOffsetPixels <= viewpager的宽度的一半,则代表往左滑动(上一页),反之右滑(下一页))
/*int positionOffsetPixelsTemp = - positionOffsetPixels;//获取需要偏移的数值(默认获取的是往右滑(下一页)的情况下的偏移值)
int viewPagerWidth = mViewPager.getWidth();
if(viewPagerWidth - positionOffsetPixels <= viewPagerWidth / 2){
positionOffsetPixelsTemp = viewPagerWidth - positionOffsetPixels;
}*/ /*
* 当第一页上翻页时:position = 0;currentItemIndex=0;positionOffset=0.0;positionOffsetPixels=0
* 普通上翻页时:position = 0;currentItemIndex=1-->0;positionOffset==0.99224806-->0.0;positionOffsetPixels=1024-->0
* 当最后一页下翻页时:position = 10;currentItemIndex=10;positionOffset=0.0;positionOffsetPixels=0
* 普通下翻页时:position = 9;currentItemIndex=9-->10;positionOffset=0.041666985-->0.9-->0.0;positionOffsetPixels=43-->1024-->0
* */ if(! isNormalChange){ if(position == mPictureBeanList.size() - 1 && position ==currentItemIndex && positionOffset == 0.0 && positionOffsetPixels == 0){
//在最后一页进行滑动
}else if(position == 0 && position ==currentItemIndex && positionOffset == 0.0 && positionOffsetPixels == 0){
//在第一页进行滑动
}else {
//判断是否数据(例如,标题)发生了改变,如果发生了改变,那么弹出对话框
PictureBean picBean = mPictureBeanList.get(currentItemIndex);
String oldPicTitle = picBean.getPicTitle();//旧的图片标题
String newPicTitle = mPicTitleEdt.getText().toString();//新的图片标题 boolean changed = newPicTitle.equals(oldPicTitle); if (changed) {
isNormalChange = true;//【如果数据没有发生改变,则代表是正常滑动】
}else{
mViewPager.setIsCanScroll(false);//禁止滑动
//弹出提示对话框
// 创建构建器
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
// 设置参数
builder.setTitle("提示")
.setMessage("标题发生了改变,是否保存?")
.setPositiveButton("保存", new DialogInterface.OnClickListener() {// 积极
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
mViewPager.setIsCanScroll(true);//允许滑动
mViewPager.scrollTo(resetXPoint,0);
uploadImgTitle();
}
}).setNegativeButton("不保存", new DialogInterface.OnClickListener() {// 消极
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
mViewPager.setIsCanScroll(true);//允许滑动
mViewPager.scrollTo(resetXPoint,0);
//还原标题
PictureBean pictureBean = mPictureBeanList.get(currentItemIndex);
mPicTitleEdt.setText(pictureBean.getPicTitle());
}
}).setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
mViewPager.setIsCanScroll(true);//允许滑动
mViewPager.scrollTo(resetXPoint,0);
}
});
builder.create().show();
}
}
}
} /* 这个方法有一个参数position,代表哪个页面被选中。
* 当用手指滑动翻页的时候,如果翻动成功了(滑动的距离够长),手指抬起来就会立即执行这个方法
* position就是当前滑动到的页面。
* 如果直接setCurrentItem翻页,那position就和setCurrentItem的参数一致,这种情况在onPageScrolled执行方法前就会立即执行。
*/
@Override
public void onPageSelected(int position) {
Log.w("why", "{MyOnPageChangeListener}{onPageSelected}position="+position);
Log.w("why", "{MyOnPageChangeListener}{onPageSelected}currentItemIndex="+currentItemIndex);
resetXPoint = resetXPoint + (position - currentItemIndex) * mViewPager.getWidth();
currentItemIndex = position;
showPageNum();//设置页码
}
} //更新图片标题
private void uploadImgTitle(){
PictureBean picBean = mPictureBeanList.get(currentItemIndex);
picBean.setPicTitle(mPicTitleEdt.getText().toString());
}
}
混淆配置
无
参考资料
暂时空缺
项目demo下载地址
https://github.com/haiyuKing/ViewPagerWithImageDemo
ViewPagerWithImageDemo【ViewPager如何判断滑动到第一页和最后一页以及弹出对话框功能】的更多相关文章
- 剑指offer21:第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。(注意:这两个序列的长度是相等的)
1 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是 ...
- JS 判断 Radio 单选按钮是否为选中状态 并弹出 值信息
今天项目中所解决的问题:JS 判断 Radio 单选按钮是否为选中状态 并弹出 值信息,一开始总是获取不到 radio 的值,后来发现逻辑存在些问题,特此共享该代码留笔记 和 分享给遇到 这类问题的 ...
- JavaScript判断 Radio 单选按钮是否为选中状态 并弹出 值信息
今天在百度前端任务中遇到了一个以前没怎么注意的知识点,所以就准备记下来 <script type="text/javascript"> //判断个函数 以上 5 个Ra ...
- Android Viewpager+Fragment实现滑动标签页
ViewPager 结合Fragment实现一个Activity里包含多个可滑动的标签页,每个标签页可以有独立的布局及响应. 主页布局 <?xml version="1.0" ...
- ViewPager 可左右滑动和缩放的图片浏览
最近因为要做一个项目,需要使用到图片的浏览.我就自己在网上找了些资料,然后加以修改整理后出来一个demo,希望可以帮助到需要的人.同时这也是我第一个技术博客. 在做之前首先需要了解一下什么是ViewP ...
- 【Android Developers Training】 70. 使用ViewPager实现屏幕滑动
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- Android:使用ViewPager实现左右滑动切换图片(图上有点点)
在以下实例的基础上加上点点 Android:使用ViewPager实现左右滑动切换图片 (简单版) 效果预览: 因为要把点点放图片上,所以修改布局为相对布局: <?xml version=&qu ...
- Android 中 DrawerLayout + ViewPager 怎么解决滑动冲突?
DrawerLayout 是 Android 官方的侧滑菜单控件,而 ViewPager 相信大家都很熟悉了.今天这里就讲一下当在 DrawerLayout 中嵌套 ViewPager 时,要如何解决 ...
- [Android]使用ViewPager实现图片滑动展示
在淘宝等电商的APP首页经常能看到大幅的广告位,通常有多幅经常更新的图片用于展示促销信息,如下图所示: 通常会自动滚动,也可以根据手势滑动.我没有研究过人家的APP是通过什么实现的,可能有第三方已经封 ...
随机推荐
- go语言nsq源码解读八 http.go、http_server.go
这篇讲另两个文件http.go.http_server.go,这两个文件和第六讲go语言nsq源码解读六 tcp.go.tcp_server.go里的两个文件是相对应的.那两个文件用于处理tcp请求, ...
- BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay
BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...
- 转载iOS开发中常见的警告及错误
iOS警告收录及科学快速的消除方法 前言:现在你维护的项目有多少警告?看着几百条警告觉得心里烦么?你真的觉得警告又不是错误可以完全不管么? 如果你也被这些问题困惑,可以和我一起进行下面的操作. ...
- Arrays.asList 为什么不能 add 或者 remove 而 ArrayList 可以
分析如下例子: 1 import java.util.Arrays; 2 import java.util.List; 3 4 5 public class Test { 6 public stati ...
- javascript的键盘事件大全
javascript的键盘事件大全 ------------------------------------------------------------------- 使用event对象的keyC ...
- Scala 编码习惯
1. 不用var.var是可以被不断修改的,而val是不能被修改的.使用val而不是var能让你的程序更强壮,bug更少,更好调试,更容易测试,在并发条件下,更容易调优而获得更好的性能.数学证明我们不 ...
- Docker 堆栈
1. Stack stack(译:堆叠,堆栈)是一组相互关联的服务,它们共享依赖关系,并且可以一起编排和伸缩. 在上一篇<Docker 服务>中我们知道可以通过创建一个docker-co ...
- 《前端之路》之 JavaScript 高级技巧、高阶函数(一)
目录 一.高级函数 1-1 安全的类型检测 1-2 作用域安全的构造函数 1-3 惰性载入函数 1-4 函数绑定 1-5 函数柯里化 1-6 反函数柯里化 一.高级函数 1-1 安全的类型检测 想到类 ...
- kube-proxy的功能
Kube-proxy的功能 我们知道POD的IP是动态分配的而且经常会变,所以为了可以通过一个不太容易变化的IP访问POD就会使用一个叫做service的东西,通过标签选择器和POD进行关联. Ser ...
- Unity导航 (寻路系统Nav Mesh Agent)
第一种 简单寻路 地面接触到的.到达目标点不用跳跃能够一直走路到达.场景视图中简单搭设几个物体.胶囊体为寻路者,黄球为目标点 红地板,绿色障碍物.现将地板以及障碍物选中 在检视面板设置静态为Navig ...