Android 自定义viewpager 三张图片在同一屏幕轮播的效果
github:https://github.com/nickeyCode/RoundImageViewPager
说实话不知道怎么描述这个效果,在网页上见得跟多,公司要求做这个效果得时候不知道怎么用文字描述找不到对应的dome只好自己写。
先上图
大概效果就是这个。主要用的的知识点就是viewpager的自定义动画。
项目目录:
roundimg是圆形图片,继承ImageView的,上网好多可以搜索得到
viewpager主要分成三部分
一是viewpager本身,设置adapter,绑定监听器等。
二是adapter,继承PagerAdapter,用法跟listview的差不多。
三是动画类,继承PageTransformer。
首先看看最核心的动画类(能做到这个效果就是根据对应的动画变动)
HeadViewPagerTransformer.Java
public class HeadViewPagerTransformer implements PageTransformer{
private static final float MIN_SCALE = 0.75f;
//主要是设置在不同位置上的VIEW的活动动画
@Override
public void transformPage(View view, float position) {
// TODO Auto-generated method stub
int pageWidth = view.getWidth(); if (position < -) { // [-Infinity,-1)
view.setAlpha();
}
else if (position <= ) { // [-1,0]
view.setAlpha();
view.setTranslationX();
float x = -1.0f * (2f / 3f) * pageWidth * position;
view.setTranslationX(x);
float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else if (position <= ) { // (0,1]
view.setAlpha();
float x = -1.0f * (2f / 3f) * pageWidth * position;
view.setTranslationX(x);
float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor); }
} }
因为在这个类中,viewpager中view都有对应的位置编号,在正中间显示的view位置是0
在左边的view位置是-1,在右边的view位置是1.(相当于一个坐标轴)
只要viewpager发生滑动,就会调用tansFromPager();position之说以是float类型,是因为如果发生滑动,位置就会有对应的变化,而变化精确到0.0001.
在函数中使用if-else来设定在不同位置区间中的view的动画变化;
if (position < -) { // [-Infinity,-1)
view.setAlpha();
}
这是负无穷到-1的区间,当然,如果你的viewpager缓存的view只有三个的话,这个就没有作用了,因为最多只有三个view,多出来就销毁了。
else if (position <= ) { // [-1,0]
view.setAlpha();
view.setTranslationX();
float x = -1.0f * (2f / 3f) * pageWidth * position;
view.setTranslationX(x);
float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor); }
这是-1到0的区间,就是左边的view到中间或中间的view到左边的动画效果,这里主要是做了两个动画变化,一是大小,二是位置。
这两个变化公式是根据位置的变化与动画数值的关系,解二元一次方程求出来的(初中数学知识。。。。)
具体方式就是balbalblabalbalb。。。。。(不多说)
同理
else if (position <= ) { // (0,1]
view.setAlpha();
float x = -1.0f * (2f / 3f) * pageWidth * position;
view.setTranslationX(x);
float scaleFactor = MIN_SCALE + ( - MIN_SCALE) * ( - Math.abs(position)); }
0到1的区间一样。在实际动画设计的过程中,公式是需要变动的。
剩下的都是普通的viewpager使用,设置adapter (HeadViewPagerAdapter.java)
public class HeadViewPagerAdapter extends PagerAdapter { private Context mContext;
private List<MyImageView> mList; public HeadViewPagerAdapter(Context context,List<MyImageView> list){
this.mContext = context;
this.mList = list;
} @Override
public int getCount() {
// TODO Auto-generated method stub
return mList.size();
} @Override
public boolean isViewFromObject(View arg0, Object arg1) {
// TODO Auto-generated method stub
return arg0 == arg1;
}
//当缓存view的数量超过上限时,会销毁最先的一个
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
// TODO Auto-generated method stub
//Log.d("remove", mImageViews[position].hashCode() + "");
container.removeView(mList.get(position));
}
//添加View
@Override
public Object instantiateItem(ViewGroup container, int position) {
// TODO Auto-generated method stub
container.addView(mList.get(position),);
return mList.get(position);
} }
还有就是对应的绑定:HeadViewPager.java
public class HeadViewPager extends FrameLayout { private Context mContext;
private ViewPager mViewPager;
private List<Integer> mImageIds;
private List<MyImageView> mImageViews;
private ViewGroup mViewGroup;
private List<ImageView> tips;
private int tipsChoseImgId;
private int tipsUnchoseImgId; public HeadViewPager(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
creatView(context);
} public HeadViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
creatView(context);
} public HeadViewPager(Context context) {
super(context);
// TODO Auto-generated constructor stub
creatView(context);
} public HeadViewPager(Context context,List<MyImageView> imgageList) {
super(context);
// TODO Auto-generated constructor stub
creatView(context,imgageList);
} public void creatView(Context context){
this.mContext = context;
LayoutInflater.from(context).inflate(R.layout.head_view_pager, this);
mViewPager = (ViewPager)findViewById(R.id.viewpager);
mViewGroup = (ViewGroup)findViewById(R.id.viewgroup);
mImageViews = new ArrayList<MyImageView>();
mImageIds = new ArrayList<Integer>();
tips = new ArrayList<ImageView>();
tipsChoseImgId = R.drawable.img_bg_chose;
tipsUnchoseImgId = R.drawable.img_bg_unchose;
build();
} public void creatView(Context context,List<MyImageView> imgageList){
this.mContext = context;
LayoutInflater.from(context).inflate(R.layout.head_view_pager, this);
mViewPager = (ViewPager)findViewById(R.id.viewpager);
mViewGroup = (ViewGroup)findViewById(R.id.viewgroup);
mImageViews = imgageList;
mImageIds = new ArrayList<Integer>();
tips = new ArrayList<ImageView>();
tipsChoseImgId = R.drawable.img_bg_chose;
tipsUnchoseImgId = R.drawable.img_bg_unchose;
build();
} public void build(){
buildTips();
mViewPager.setAdapter(new HeadViewPagerAdapter(mContext,mImageViews));
//设置默认显示页面为第0页
mViewPager.setCurrentItem();
//设置选择页面时的动画
mViewPager.setPageTransformer(true, new HeadViewPagerTransformer());
//设置缓存View的个数,默认是3个,这表示缓存了5个
mViewPager.setOffscreenPageLimit();
//页面发生改变的监听器
mViewPager.setOnPageChangeListener(new OnPageChangeListener() {
//选择发生改变
@Override
public void onPageSelected(int arg0) {
// TODO Auto-generated method stub
changeTips(arg0);
}
//有滑动操作
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
// TODO Auto-generated method stub }
//滑动操作或选择改变
@Override
public void onPageScrollStateChanged(int arg0) {
// TODO Auto-generated method stub }
}); }
//初始化底部导航圆点条
public void buildTips(){
for (int i = ; i < mImageViews.size() ; i ++){
ImageView imageView = new ImageView(mContext);
imageView.setLayoutParams(new LayoutParams(,));
if(i == ){
imageView.setBackgroundResource(tipsChoseImgId);
}else{
imageView.setBackgroundResource(tipsUnchoseImgId);
}
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(,));
layoutParams.leftMargin = ;
layoutParams.rightMargin = ;
tips.add(imageView);
mViewGroup.addView(imageView, layoutParams);
}
}
//当选定的页面发生改变时,导航条也对应改变
public void changeTips(int index){
for (int i = ; i < tips.size() ; i ++){
if(i == index){
tips.get(i).setBackgroundResource(tipsChoseImgId);
}else{
tips.get(i).setBackgroundResource(tipsUnchoseImgId);
}
}
} public Context getmContext() {
return mContext;
} public void setmContext(Context mContext) {
this.mContext = mContext;
} public ViewPager getmViewPager() {
return mViewPager;
} public void setmViewPager(ViewPager mViewPager) {
this.mViewPager = mViewPager;
} public List<MyImageView> getmImageViews() {
return mImageViews;
}
//改变图片队列时,要更新整个viewPager
public void setmImageViews(List<MyImageView> mImageViews) {
this.mImageViews = mImageViews;
this.mViewPager.notify();
this.mViewPager.setCurrentItem(); } public ViewGroup getmViewGroup() {
return mViewGroup;
} public void setmViewGroup(ViewGroup mViewGroup) {
this.mViewGroup = mViewGroup;
} public int getTipsChoseImgId() {
return tipsChoseImgId;
} public void setTipsChoseImgId(int tipsChoseImgId) {
this.tipsChoseImgId = tipsChoseImgId;
} public int getTipsUnchoseImgId() {
return tipsUnchoseImgId;
} public void setTipsUnchoseImgId(int tipsUnchoseImgId) {
this.tipsUnchoseImgId = tipsUnchoseImgId;
}
}
样例项目资源:
http://download.csdn.NET/detail/nickey_1314/8932807
Android 自定义viewpager 三张图片在同一屏幕轮播的效果的更多相关文章
- Android 使用ViewPager 做的半吊子的图片轮播
Android 使用ViewPager 做的半吊子的图片轮播 效果图 虽然不咋样,但是最起码的功能是实现了,下面我们来一步步的实现它. 界面 下面我们来分析一下界面的构成 整体的布局: 因为我们要做出 ...
- Android项目实战(四十七):轮播图效果Viewpager
简易.常用的轮播图效果ViewPager ,老技术了,记一笔留着以后ctrl C + ctrl V 需求如下: 不定张个数的ImagView轮播,右下角显示轮播点图标,每隔固定时间切换下一张,最 ...
- Android使用ViewPager实现左右循环滑动及轮播效果
边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...
- 巧用ViewPager 打造不一样的广告轮播切换效果
一.概述 如果大家关注了我的微信公众号的话,一定知道我在5月6号的时候推送了一篇文章,文章名为Android超高仿QQ附近的人搜索展示(一),通过该文可以利用ViewPager实现单页显示多个Item ...
- Android使用ViewPager实现无限循环滑动及轮播(附源代码)
MainActivity例如以下: package cc.ww; import java.util.ArrayList; import android.app.Activity; import and ...
- Android自定义视图三:给自定义视图添加“流畅”的动画
这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...
- Android中使用开源框架android-image-indicator实现图片轮播部署
之前的博文中有介绍关于图片轮播的实现方式,分别为(含超链接): 1.<Android中使用ViewFlipper实现屏幕切换> 2.<Android中使用ViewPager实现屏幕页 ...
- Android开发工程师文集-Fragment,适配器,轮播图,ScrollView,Gallery 图片浏览器,Android常用布局样式
Android开发工程师文集-Fragment,适配器,轮播图,ScrollView,Gallery 图片浏览器,Android常用布局样式 Fragment FragmentManager frag ...
- android 自定义Viewpager实现无限循环
; i < imageUrls.length; i ++){ ADInfo info = new ADInfo(); info.setUrl(imageUrls[i]); info.setCon ...
随机推荐
- linux中sed的使用方法具体解释(对行数据的加入、删除等)
sed使用语法 [root@fwq test]# sed --help 使用方法: sed [选项]... {脚本(假设没有其它脚本)} [输入文件]... -n, --quiet, --silent ...
- poj_1952最大下降子序列,统计个数
其实不算难的一道题,但憋了我好久,嗯,很爽. #include<iostream> #include<cstdio> #include<string.h> #inc ...
- javascript系列-class6.String类型
观察淘宝网商品数据 有一个东西叫服务器>>>>js的作用重要作用之一>>>>交互>>>>人机交互(事件)>>&g ...
- 11.使用boostregex遭遇无法打开libboost_regex-vc120-mt-sgd-1_62.lib的问题
通过Boost库可以在C++项目中使用正则表达式,配置好环境后链接过程出现”无法打开libboost_regex-vc120-mt-sgd-1_62.lib”的错误. 原因是按照官方生成lib的方法 ...
- 使用xshell连接本地虚拟机中的Linux问题
xshell 连接虚拟机中Linux报错: Could not connect to '192.168.8.120' (port 22):Connection failed. 原因:虚拟机中Linux ...
- Eclipse使用struts2开发web应用快速搭建
eclipse 下载javaEE版,这里用4.5(Mars). Tomcat8解压,设置好JAVA_HOME环境变量. 下载struts2官网上的lib包,struts-2.3.24-lib.zip, ...
- java中,length,length(),size()区别
length——数组的属性: length()——String的方法: size()——集合的方法:
- WebKit.NET-0.5简单应用(2)——音量解决方案
查找WebKit.NET相关文档,没有找到音量控制解决方法.换思路进行解决,尝试用Win32 API进行解决 [DllImport("winmm.dll")] public sta ...
- 【C++】函数和指针
最近在看C++ primer plus,感觉函数与指针这一章难点比较多,记写笔记,加强理解. From C++ Primer Plus: Chapter 7 Function:C++ Programm ...
- 特斯拉正加快部署第三代Autopilot自动驾驶计算机
新浪科技讯,北京时间 4 月 10 日下午消息,据电动汽车新闻网站 Electrek 报道,特斯拉正在加快部署第三代 Autopilot 自动驾驶计算机,因为当前一代产品的计算能力即将被耗尽. 201 ...