viewpager setpagechangelistener解释与应用到如微信的页面转换的渐变效果

来源:互联网 发布:澄海网店美工培训 编辑:程序博客网 时间:2024/04/29 22:57

也不知道从什么时间开始,微信的页面在滑动转换时有了渐变的效果,效果如下所示:


图是用360截的,颜色和实际有比较大的不同,但不影响,知道怎样的效果就行了。我这里用是是viewpager的setonpagechangelistener和里面控件的setalpha透明度来实现,同时顺便说明一下那几个方法与其参数的含义。

public void onPageSelected(int arg0)
public void onPageScrolled(int arg0, float arg1, int arg2) 
public void onPageScrollStateChanged(int arg0)

有时它就是这么讨厌,写参数都是arg0,1,2....,看名字完全看不出是什么玩意,所以这里也顺道解释一下,也更好理解下面的过程

onPageSelected(int arg0) 这个方法是在页面被选择时调用的方法,参数arg0是当前选择的页面(第一页这参数为0)

onPageScrolled(int arg0, float arg1, int arg2) 是页面滑动时调用的方法,arg0参数代表将要偏移(移动)的页面,那不禁会问,一般滑动都两个页面都滑动的吖,到底是哪一个啊,这里无论向哪个方向滑动,arg0都是左边那个页面,arg1代表参数arg0的那个页面的偏移量(是百分比,一个页面大小为1),如手向右滑(就是当前页为1时,左边的滑动的页面0将可见,这时arg0为0,这个页面这时还不可见,所以偏移量为1),当滑动过程中,arg1将越来越小,当当前页面变为页面0时,偏移量变为0,第三个参数arg2代表当前页面偏移的像素位置 。

onPageScrollStateChanged(int arg0)是滑动状态改变时调用的方法,怎么样为状态改变呢,比如一开始手指右滑(改变了),滑到一半又不滑了,页面将回到滑动前的页面(又改变),再回到原来页面时滑动停了(又改变一次),而上面的例子也将arg0的三种状态表现了,状态为1时表示从没滑动开始滑动,2表示滑着就不滑了(滑到一半或完成页面改变都算),0表示又回到没有滑动的状态(滑动完成页面改变或没完成回到原来页面)。

我看了看网上其它的说明,都只是翻译了说明,并没有很清楚的举例说明,有时理解还是会有偏差,所以这里用了比较长的篇幅来说明,让大家更了解其含义。

好了,说明了它们的含义,就要进入主题了,怎样做如微信的那个效果,我这里是用两个一模一样的布局,只是两个的颜色不一样,一个是全是绿色选中的资源,一个是没选中的灰色资源,然后用一个FrameLayout将它们装在一起重叠起来,然后对各自设置透明度就可以了(微信不知道是不是这样方法实现的,我只是说我的实现方法,还是那个话,教人掌握原理和方法而不是代码)。


由于代码很长,这里就不贴了,说明一下,这里其它是两个重叠的布局,看都看得出来吧,一个绿色一个银灰色的。然后在Activity里监听,由于大家做这类的做了几十万次了,如何设置adapter和如何findview就不写了,直接看监听事件

private void setPageChangeListener() {
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
float oldArg1 = 0f;//初始化透明度
Boolean flag = true;//用来做是否第一次调用 onPageScrolled的标记,可有可无
Boolean changePage = false;//滑动状态是否改变,这个很重要,等下会说明为什么
@Override
public void onPageSelected(int arg0) {
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
Log.e("onPageScrolled", arg0+"");
if (arg1>oldArg1&&arg1!=0.0&&arg1!=1.0){//向左划,这里由于arg1是由0-1的偏移百分比,所以可以直接当控件的透明度用,当前偏移量大于旧的记录的偏移量,证明是手是向左滑动的
if (changePage) {
if (arg1>oldArg1) {//继续左划
greenImageViews[arg0].setAlpha(1-arg1);
greenTextViews[arg0].setAlpha(1-arg1);
imageViews[arg0].setAlpha(arg1);
textViews[arg0].setAlpha(arg1);
imageViews[arg0+1].setAlpha(1-arg1);
textViews[arg0+1].setAlpha(1-arg1);
greenImageViews[arg0+1].setAlpha(arg1);
greenTextViews[arg0+1].setAlpha(arg1);
}else if(arg1<oldArg1){//向右时的回划
greenImageViews[arg0+1].setAlpha(1-arg1);
greenTextViews[arg0+1].setAlpha(1-arg1);
imageViews[arg0+1].setAlpha(arg1);
textViews[arg0+1].setAlpha(arg1);
imageViews[arg0].setAlpha(1-arg1);
textViews[arg0].setAlpha(1-arg1);
greenImageViews[arg0].setAlpha(arg1);
greenTextViews[arg0].setAlpha(arg1);
}
}else {
greenImageViews[arg0].setAlpha(1-arg1);
greenTextViews[arg0].setAlpha(1-arg1);
imageViews[arg0].setAlpha(arg1);
textViews[arg0].setAlpha(arg1);
imageViews[arg0+1].setAlpha(1-arg1);
textViews[arg0+1].setAlpha(1-arg1);
greenImageViews[arg0+1].setAlpha(arg1);
greenTextViews[arg0+1].setAlpha(arg1);
}
}else if (arg1<oldArg1&&arg1!=1.0&&arg1!=0) {//右划
if (changePage) {
if (arg1<oldArg1) {//继续右划
greenImageViews[arg0+1].setAlpha(arg1);
greenTextViews[arg0+1].setAlpha(arg1);
imageViews[arg0+1].setAlpha(1-arg1);
textViews[arg0+1].setAlpha(1-arg1);
imageViews[arg0].setAlpha(arg1);
textViews[arg0].setAlpha(arg1);
greenImageViews[arg0].setAlpha(1-arg1);
greenTextViews[arg0].setAlpha(1-arg1);
}else if(arg1>oldArg1){//向左时的回划
greenImageViews[arg0].setAlpha(1-arg1);
greenTextViews[arg0].setAlpha(1-arg1);
imageViews[arg0].setAlpha(arg1);
textViews[arg0].setAlpha(arg1);
imageViews[arg0+1].setAlpha(1-arg1);
textViews[arg0+1].setAlpha(1-arg1);
greenImageViews[arg0+1].setAlpha(arg1);
greenTextViews[arg0+1].setAlpha(arg1);
}
}else {
greenImageViews[arg0+1].setAlpha(arg1);
greenTextViews[arg0+1].setAlpha(arg1);
imageViews[arg0+1].setAlpha(1-arg1);
textViews[arg0+1].setAlpha(1-arg1);
imageViews[arg0].setAlpha(arg1);
textViews[arg0].setAlpha(arg1);
greenImageViews[arg0].setAlpha(1-arg1);
greenTextViews[arg0].setAlpha(1-arg1);
}
}
oldArg1 = arg1;
flag = true;
Log.e("arg1", arg1+"");
}
@Override
public void onPageScrollStateChanged(int arg0) {
Log.e("onPageScrollStateChanged", arg0+"");
if (arg0==2) {
changePage = true;
}
if (arg0==0) {
changePage = false;
}
}
});
}

以上的几个数组控件就是要改变的那几个控件,前面带green的是绿色控件,数组里索引为0-3,分别是图中从左到右的四个控件,其中为什么要有changePage来判断有没状态改变呢,原因是当滑动到一半不再滑动时,页面将回划,这时onpagesrcolled方法继续执行,但这时arg0是同一个,但滑动的方向不一样了,也就是arg1-oldalpha的正负值都不一样了,如果还调原来的方法来设置透明度就会出错,所有滑动就算同方向也要判断是否有滑动状态的改变。从上面的方法看,滑动完成控件的透明度永远不会为1和0,那个大家会问,为什么不在onpageselected方法里再将透明度设为零,可以,但这你们大家去试试吧,因为如果滑动很快的时候,onPageScrolled方法还在调用中,而onPageSelected方法已经调用,如果在onPageSelected设置,后来onPageScrolled还在调用又会改变状态,所以前面的设置就不会起作用。但解决方法还是有的,就是在onPageScrollStateChanged里看有没状态的改变再进行处理,由于这里只是结合来说明setonpagechangelistener方法与其参数的含义而已,其它有想研究的大家可以再去探究。

由于代码有点长,我就没有全部贴上来,有些不那么理解的看起来可以较吃力,有不懂的或有什么有问题的,可以提出来大家交流,这就说到这,再次可能会讲解下popupwindow的用法。

0 0
原创粉丝点击