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的活動動畫 @Overridepublic void transformPage(View view, float position) {// TODO Auto-generated method stubint pageWidth = view.getWidth(); if (position < -1) { // [-Infinity,-1) view.setAlpha(0); }else if (position <= 0) { // [-1,0] view.setAlpha(1); view.setTranslationX(0); float x = -1.0f * (2f / 3f) * pageWidth * position;view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); } else if (position <= 1) { // (0,1] view.setAlpha(1); float x = -1.0f * (2f / 3f) * pageWidth * position;view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - 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 < -1) { // [-Infinity,-1) view.setAlpha(0); }這是負無窮到-1的區間,當然,如果你的viewpager緩存的view只有三個的話,這個就沒有作用了,因為最多只有三個view,多出來就銷毀了。
else if (position <= 0) { // [-1,0] view.setAlpha(1); view.setTranslationX(0); float x = -1.0f * (2f / 3f) * pageWidth * position;view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - Math.abs(position)); view.setScaleX(scaleFactor); view.setScaleY(scaleFactor); }這是-1到0的區間,就是左邊的view到中間或中間的view到左邊的動畫效果,這里主要是做了兩個動畫變化,一是大小,二是位置。
這兩個變化公式是根據位置的變化與動畫數值的關系,解二元一次方程求出來的(初中數學知識。。。。)
具體方式就是balbalblabalbalb。。。。。(不多說)
同理
else if (position <= 1) { // (0,1] view.setAlpha(1); float x = -1.0f * (2f / 3f) * pageWidth * position;view.setTranslationX(x); float scaleFactor = MIN_SCALE + (2 - MIN_SCALE) * (1 - 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;}@Overridepublic int getCount() {// TODO Auto-generated method stubreturn mList.size();}@Overridepublic boolean isViewFromObject(View arg0, Object arg1) {// TODO Auto-generated method stubreturn arg0 == arg1;}//當緩存view的數量超過上限時,會銷毀最先的一個 @Overridepublic 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 @Overridepublic Object instantiateItem(ViewGroup container, int position) {// TODO Auto-generated method stubcontainer.addView(mList.get(position),0);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(0);//設置選擇頁面時的動畫mViewPager.setPageTransformer(true, new HeadViewPagerTransformer());//設置緩存View的個數,默認是3個,這表示緩存了5個mViewPager.setOffscreenPageLimit(4);//頁面發生改變的監聽器mViewPager.setOnPageChangeListener(new OnPageChangeListener() {//選擇發生改變 @Overridepublic void onPageSelected(int arg0) {// TODO Auto-generated method stub changeTips(arg0);}//有滑動操作 @Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// TODO Auto-generated method stub }//滑動操作或選擇改變 @Overridepublic void onPageScrollStateChanged(int arg0) {// TODO Auto-generated method stub }});}//初始化底部導航圓點條public void buildTips(){for (int i = 0 ; i < mImageViews.size() ; i ++){ImageView imageView = new ImageView(mContext); imageView.setLayoutParams(new LayoutParams(10,10)); if(i == 0){ imageView.setBackgroundResource(tipsChoseImgId); }else{ imageView.setBackgroundResource(tipsUnchoseImgId); } LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(new ViewGroup.LayoutParams(12,12)); layoutParams.leftMargin = 5; layoutParams.rightMargin = 5; tips.add(imageView); mViewGroup.addView(imageView, layoutParams); }}//當選定的頁面發生改變時,導航條也對應改變public void changeTips(int index){for (int i = 0 ; 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;}//改變圖片隊列時,要更新整個viewPagerpublic void setmImageViews(List<MyImageView> mImageViews) {this.mImageViews = mImageViews;this.mViewPager.notify();this.mViewPager.setCurrentItem(0);}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 三张图片在同一屏幕轮播的效果的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [洛谷1390]公约数的和
- 下一篇: 使用Spring Cloud Funct