自定義viewpager 三張圖片在同一屏幕輪播的效果

ps:剛開始寫文章,有點亂,慢慢改進。

最下方項目源碼下載

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 < -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;
	}
	
	@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),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() {
			//選擇發生改變
			@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 = 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;
	}
	//改變圖片隊列時,要更新整個viewPager
	public 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

點擊打開鏈接




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章