本文主要介绍Android自定义ViewPager实现个性化的图片切换效果,有一定的参考价值,感兴趣的朋友可以参考一下。
第一次看到control ViewPager,就爱不释手。做东西的主界面都是ViewPager,ImageSwitch被抛弃了,我就开始让ViewPager做了。时间长了,ViewPager的切换效果感觉很枯燥,形成审美疲劳~ ~我们需要改变。今天就教大家如何改变ViewPager的切换效果,实现个性化的图片切换。
看看这个效果的画面切换:
是不是比传统效果个性很多?呵呵~ ~其实很简单。学完这篇文章,可以自定义切换效果,做出各种效果。
1、制作前的分析
看效果图,实际改变的是切换时的动画。就是这么简单,只需要用户在切换时获取当前视图和下一个视图,然后添加动画。
第一步,用户切换时获取当前视图和目的视图。
现在就来看看吧。如果当前视图和目标视图改变了,我们需要慢慢地改变动画。最好根据用户的手势滑动。比如上面的效果,当用户滑动时,目标图片出现,并根据用户的滑动距离缓慢增长。
第二步,设计动画的渐变。
经过分析,我们总结了两步。让我们从一步一步开始,创造出千变万化的画面切换效果。
2、获取用户切换时当前View和切换至的目的View。ViewPager还需要监视用户的手势,因此必须提供一些方法。所以在查看ViewPager的方法时,我发现了一个名为on page scrolled (int position,float position offset,int position offset pixels)的方法~ ~
没错,就是这个方法:页面滚动时调用~
下面仔细研究下这几个参数:
直接说测试结果:
当不是第一页和最后一页时,滑动到下一页,位置为当前页面位置;滑动到上一页:位置是当前页-1。
PositionOffset滑动到下一页,并在[0,1]区间内变化;滑动到上一页:(1,0)间隔的变化
PositionOffsetPixels这和positionOffset很像:滑动到下一页,以[0,width]的间隔变化;滑动到上一页:(宽度,0)改变音程。
第一页上:滑动到上一页位置=0,其他基本都是0;最后一页滑到下一页。position是当前页面位置,另外两个参数是0。
突然发现我们需要的步骤第二步就解决了,positionOffset非常适合作为渐变和缩放的控制参数;PositionOffsetPixels可用作平移的控制参数。
那么,如何获得当前视图和目标视图呢:
分享几个我的歧途:
1、【错误】我得到两个视图;滑动通过getChildAt(位置)、getChildAt(位置1)和getChildAt(位置-1)时的左右;第一眼真的觉得挺好的~ ~代码写出来后效果一看就不出来了~ ~错误原因:我们忽略了一个特别大的东西,ViewPager的机制,滑动时动态加载和删除视图。ViewPager实际上只维持2或3个视图,而位置的范围基本上是无限的~ ~
2、【错误】我通过getCurrentItem得到了当前位置,然后1,-1得到了下一个或者上一个~ ~我暗喜。赶紧改代码,效果不对。乱七八糟~ ~仔细看日志。这个getCurrentItem在用户手指离开屏幕页面还动画的时候就变了~ ~难怪~整个滑动过程都不固定~
3、【错误】位置在整个滑动过程中不变,ViewPager会保存2或3个视图;所以我想,如果是第一页或者最后一页,那么我就取getChildAt(0)和getChildAt(1),如果是其他页,就是GET CHILD AT (0)和GET CHILD AT (2),然后经过一系列的修改~我觉得这样总是对的,所以就遇到了第一个问题。第一页左右位置都是0,尼玛,这
说了这么多错误,可以绕过这些弯路,从中看到一些东西~
下面说正确的,其实查看寻呼机在添加一个视角或者销毁一个视角时,是我们自己的页面适配器中控制的,于是我们可以在查看寻呼机里面维系一个HashMapPosition,视图,然后滑动的时候,通过获得(位置)取出,比如上述效果,始终是右边的视角变化,要么从小到大,要么从大到小
那么滑倒下一页:左边的View:map.get(位置),右边的View : map.get(位置1)。
那么滑倒上一页:左边的View : map.get(位置),右边的View : map.get(位置1),一样的,因为滑到上一页,位置为当前页-1
好了,至此,我们分析了且解决了所有步骤。
3、代码
主要活动
包com。举例。zhy _ jazzyview分页器;
导入安卓。app。活动;
导入安卓。OS。捆绑;
导入安卓。支持。v4。查看。寻呼机适配器;
导入安卓。查看。菜单;
导入安卓。查看。查看;
导入安卓。查看。查看组;
导入安卓。小部件。imageview
导入安卓。小部件。imageview。规模类型;
公共类主要活动扩展活动
{
受保护的静态最终字符串TAG="主要活动";
private int[]mim GID;
私有myjazzyview分页器mview分页器;
@覆盖
受保护的void onCreate(绑定保存的实例状态)
{
超级棒。oncreate(savedInstanceState);
setContentView(r . layout。活动_主);
mImgIds=new int[] { R.drawable.a,R.drawable.b,R.drawable.c,
r。可画的。d };
mview pager=(myjazzyview pager)findViewById(r . id。id _查看寻呼机);
mViewPager.setAdapter(新的页面适配器()
{
@覆盖
公共布尔值isViewFromObject(视图arg0,对象arg1)
{
返回arg0==arg1
}
@覆盖
公共无效销毁项目(视图组容器,int位置,
对象对象)
{
container.removeView(视图)对象);
}
@覆盖
公共对象实例化项(视图组容器,int位置)
{
ImageView ImageView=新的ImageView(主活动。这个);
imageview。设置图像资源(mim GIDs[position]);
imageview。setscaletype(刻度类型.CENTER _ CROP);
集装箱。addview(imageView);
mview寻呼机。setobjectforposition(imageView,position);
返回图像视图
}
@覆盖
public int getCount()
{
返回mImgIds.length
}
});
}
}
这个很常见的代码,就是初始化ViewPager~~就没啥可说的了~~有一点需要注意:在实例化项目方法,我们多调用了一个mview寻呼机。setobjectforposition(imageView,position);其实就是为了给我们的地图存值
主要看自定义的查看寻呼机
包com。举例。zhy _ jazzyview分页器;
导入Java。util。hashmap
导入Java。util。链接的散列表;
导入安卓。内容。语境;
导入安卓。支持。v4。查看。查看寻呼机;
导入安卓。util。attributeset
导入安卓。util。日志;
导入安卓。查看。查看;
导入com。九个机器人。查看。查看帮助者;
公共类MyJazzyViewPager扩展查看寻呼机
{
私有浮动交易;
私有浮动mScale
/**
* 最大的缩小比例
*/
私有静态最终浮点SCALE _ MAX=0.5f
private static final String TAG=' myjazzyview pager ';
/**
* 保存位置与对于的视角
*/
private HashMapInteger,View mChildrenViews=new LinkedHashMapInteger,View();
/**
* 滑动时左边的元素
*/
私人视图mLeft
/**
* 滑动时右边的元素
*/
私观好的
公共myjazzyviewparager(上下文上下文、属性集属性)
{
超级(上下文,attrs);
}
@覆盖
public void onpagesrolled(int位置,float位置Offset,
int positionOffsetPixels)
{
//Log.e(TAG,' position=' position ',positionOffset=' positionOffset ',positionOffsetPixels=' positionOffsetPixels ',current pos=' getCurrentItem());
//滑动特别小的距离时,我们认为没有动,可有可无的判断
浮点效果偏移=小(位置偏移)?0:位置偏移;
//获取左边的视角
ml eft=findViewFromObject(position);
//获取右边的视角
mRight=findViewFromObject(位置1);
//添加切换动画效果
animateStack(mLeft,mRight,effectOffset,positionOffsetPixels);
超级棒。onpagesrolled(position,positionOffset,positionOffsetPixels);
}
public void setObjectForPosition(View View,int position)
{
mChildrenViews.put(位置,视图);
}
/**
* 通过过位置获得对应的视角
*
* @param位置
* @返回
*/
公共视图findViewFromObject(int位置)
{
返回mchildrenviews。get(位置);
}
私有布尔值isSmall(浮点位置偏移量)
{
返回数学。ABS(位置偏移)0.0001;
}
受保护的空动画堆栈(左视图,右视图,浮动效果偏移量,
int positionOffsetPixels)
{
如果(对!=空)
{
/**
* 缩小比例如果手指从右到左的滑动(切换到后一个):0.0~1.0,即从一半到最大
* 如果手指从左到右的滑动(切换到前一个):1.0~0,即从最大到一半
*/
mScale=(1-SCALE _ MAX)*效果偏移SCALE _ MAX;
/**
* x偏移量:如果手指从右到左的滑动(切换到后一个):0-720 如果手指从左到右的滑动(切换到前一个):720-0
*/
m trans=-getWidth()-getpage margin()positionOffsetPixels;
ViewHelper.setScaleX(右,m刻度);
ViewHelper.setScaleY(右,m刻度);
ViewHelper.setTranslationX(右,m trans);
}
如果(左!=空)
{
向左。bringtofront();
}
}
}
可以看到,核心代码都是onPageScrolled,我们通过findViewFromObject(position);findViewFromObject(位置1);分别获取了左右两边的查看,然后添加动画效果;当前这个例子添加了两个动画,一个是从0.5放大到1.0或者1.0缩小到0.5,没错由我们的位置偏移提供梯度的变化~~还有个平移的动画:下一页直接移动到当前屏幕(默认是在右边,可以注释这个效果,怎么运行看看),然后不断的通过位置偏移量像素抵消原来默认移动时的位移,让用户感觉它就在原地放大缩小~~
好了,这样就实现了~~你可以随便写自己喜欢的动画效果,比如在默认上面加个淡入淡出或者神马,随便~~是不是很随意~~
我们的布局文件:
相对布局xmlns:Android=' http://模式。安卓。' com/apk/RES/Android '
xmlns:tools=' http://模式。安卓。' com/tools '
Android:layout _ width=' match _ parent '
Android:layout _ height=' match _ parent '
com.example.zhy_jazzyviewpager .MyJazzyViewPager
Android:layout _ width=' wrap _ content '
Android:layout _ height=' wrap _ content '
android:id='@ id/id_viewPager' /
/RelativeLayout
4、JazzyViewPager的使用
其实上面的实现就是开源代码库上JazzyViewPager的源码,用法不用说了,就是我们的主要活动,它内置了大概10来种效果,我们可以通过代码或者布局上面设置动画效果~~我们上面的例子效果,它叫做堆栈;
使用JazzViewPager的代码:其实基本一样~~最后也会贴上JazzyViewPager的源码的下载
主要活动
包com。JF爱因斯坦。jazzyview寻呼机;
导入com。JF爱因斯坦。jazzyview寻呼机。jazzyview寻呼机。过渡效应;
导入安卓。app。活动;
导入安卓。OS。捆绑;
导入安卓。支持。v4。查看。寻呼机适配器;
导入安卓。查看。查看;
导入安卓。查看。查看组;
导入安卓。小部件。imageview
导入安卓。小部件。imageview。规模类型;
公共类主要活动扩展活动
{
受保护的静态最终字符串TAG="主要活动";
private int[]mim GID;
私有jazzyview寻呼机mview寻呼机;
@覆盖
受保护的void onCreate(绑定保存的实例状态)
{
超级棒。oncreate(savedInstanceState);
setContentView(r . layout。活动_主);
mImgIds=new int[] { R.drawable.a,R.drawable.b,R.drawable.c,
r。可画的。d };
mview pager=(jazzyview pager)findViewById(r . id。id _查看寻呼机);
//设置切换效果
mview寻呼机。settransitioneffect(TransitionEffect .栈);
mViewPager.setAdapter(新的页面适配器()
{
@覆盖
公共布尔值isViewFromObject(视图arg0,对象arg1)
{
返回arg0==arg1
}
@覆盖
公共无效销毁项目(视图组容器,int位置,
对象对象)
{
container.removeView(视图)对象);
}
@覆盖
公共对象实例化项(视图组容器,int位置)
{
ImageView ImageView=新的ImageView(主活动。这个);
imageview。设置图像资源(mim GIDs[position]);
imageview。setscaletype(刻度类型.CENTER _ CROP);
集装箱。addview(imageView);
mview寻呼机。setobjectforposition(imageView,position);
返回图像视图
}
@覆盖
public int getCount()
{
返回mImgIds.length
}
});
}
}
与我们的代码唯一区别就是:
//设置切换效果
mview寻呼机。settransitioneffect(TransitionEffect .栈);
它有12种可选的切换效果,其实就是写了12个切换的动画~~~
好了,最后附上一个我比较喜欢的效果:平板电脑
源码下载:查看页面图片切换
以上就是本文的全部内容,希望对大家学习机器人软件编程有所帮助。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。