有過開發經驗的程序員都知道這個效果,就是當我們第一次安裝一個軟件時有一個使用說明的圖片切換效果,他是如何實現的呢?今天我們就一起學習一下吧,難度系數1.0,就是只要你仔細分析,都可以學會。廢話不多說,下面我們開始本篇的介紹。
本篇我需要使用到ViewPager,對於ViewPager的介紹,就不再詳述,網上關於ViewPager的介紹很多,大家可以自行去了解。
再進行動畫效果制作之前我們先實現一個圖片的切換效果。
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<com.example.android_viewpager.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.example.android_viewpager.ViewPager>
</RelativeLayout>
我們的Activity:
public class MainActivity extends Activity {
private ViewPager mViewPager;//系統提供的
int [] imageIds = {R.drawable.guide_image1, R.drawable.guide_image2, R.drawable.guide_image3};
List<ImageView> listImager = new ArrayList<ImageView>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.viewPager);//調用系統提供的
mViewPager.setAdapter(new PagerAdapter() {
@Override
public void destroyItem(ViewGroup container, int position,
Object object) {
container.removeView(listImager.get(position));
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
ImageView imagerView = new ImageView(MainActivity.this);
imagerView.setImageResource(imageIds[position]);
imagerView.setScaleType(ScaleType.CENTER_CROP);//設置樣式
container.addView(imagerView);
listImager.add(imagerView);
return imagerView;
}
@Override
public boolean isViewFromObject(View arg0, Object arg1) {
return arg0 == arg1;
}
@Override
public int getCount() {
return imageIds.length;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
這樣我們最簡單的使用說明的效果已經做好了。下面我們來一起看一下如何為我們的切換效果添加一些炫酷效果呢?
首先我們想到的是谷歌有沒有為我們封裝這樣的方法,答案是肯定的,大家可以訪問谷歌Android API詳細了解其中的機制(http://developer.android.com/training/animation/screen-slide.html )。接下來就有我帶領大家先使用一下為ViewPager添加動畫效果的實現。
調用的方法:
mViewPager.setPageTransformer(true, new DepthPageTransformer());
DepthPageTransformer.java:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class DepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
@SuppressLint("NewApi")
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
view.setAlpha(0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
view.setAlpha(1);
view.setTranslationX(0);
view.setScaleX(1);
view.setScaleY(1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
view.setAlpha(1 - position);
// Counteract the default slide transition
view.setTranslationX(pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
view.setScaleX(scaleFactor);
view.setScaleY(scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
view.setAlpha(0);
}
}
}
對於這段代碼代碼大家直接把官網的拿過來就可以了。好了到這裡我們的切換效果已經實現了,大家可以測試一下了。
是不是一些同學已經發現一個問題了,自己的為什麼一點效果都沒有,是的,這不是你寫錯的原因,這是因為我們的動畫效果都是通過屬性動畫實現的,而屬性動畫又是Android3.0以後的版本才支持的,所以大家不為之困擾,換一個高版本的就可以完美呈現了,當然如果你感覺這個效果還不算理想,官網還為我們提供了一個效果,大家同樣的操作就可以了。
對於上面的提到的關於3.0以前版本不支持的問題,這裡我為大家提供一個改進方法:
我們對DepthPageTransformer.java進行優化:
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public class myDepthPageTransformer implements ViewPager.PageTransformer {
private static final float MIN_SCALE = 0.75f;
/*
* 使用ViewHelper替代系統提供的view
* (non-Javadoc)
* @see android.support.v4.view.ViewPager.PageTransformer
* #transformPage(android.view.View, float)
*/
@SuppressLint("NewApi")
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
// This page is way off-screen to the left.
// view.setAlpha(0);
ViewHelper.setAlpha(view, 0);
} else if (position <= 0) { // [-1,0]
// Use the default slide transition when moving to the left page
// view.setAlpha(1);
ViewHelper.setAlpha(view, 1);
// view.setTranslationX(0);
ViewHelper.setTranslationX(view, 0);
// view.setScaleX(1);
ViewHelper.setScaleX(view, 1);
// view.setScaleY(1);
ViewHelper.setScaleY(view, 1);
} else if (position <= 1) { // (0,1]
// Fade the page out.
// view.setAlpha(1 - position);
ViewHelper.setAlpha(view, 1 - position);
// Counteract the default slide transition
// view.setTranslationX(pageWidth * -position);
ViewHelper.setTranslationX(view, pageWidth * -position);
// Scale the page down (between MIN_SCALE and 1)
float scaleFactor = MIN_SCALE
+ (1 - MIN_SCALE) * (1 - Math.abs(position));
// view.setScaleX(scaleFactor);
ViewHelper.setScaleX(view, scaleFactor);
// view.setScaleY(scaleFactor);
ViewHelper.setScaleY(view, scaleFactor);
} else { // (1,+Infinity]
// This page is way off-screen to the right.
// view.setAlpha(0);
ViewHelper.setAlpha(view, 0);
}
}
}
這樣我們通過ViewHelper來替代我們的屬性動畫屬性,來處理我們3.0以前版主不支持屬性動畫的問題,當我們運行後發現,3.0以後的版本還是沒有效果,這是什麼原因呢?我們打開ViewPager的源代碼發現裡面有一句判斷:
if (Build.VERSION.SDK_INT >= 11) //Android版本判斷
對這個就是罪魁禍首,當我們的版本低於3.0時,我們的動畫效果代碼根本得不到執行,所以如果想要解決這個問題,我們需要從寫這個類。把裡面setPageTransformer()裡面的版本判斷進行一下注釋;
public void setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) {
//if (Build.VERSION.SDK_INT >= 11) //Android版本判斷
{
final boolean hasTransformer = transformer != null;
final boolean needsPopulate = hasTransformer != (mPageTransformer != null);
mPageTransformer = transformer;
setChildrenDrawingOrderEnabledCompat(hasTransformer);
if (hasTransformer) {
mDrawingOrder = reverseDrawingOrder ? DRAW_ORDER_REVERSE : DRAW_ORDER_FORWARD;
} else {
mDrawingOrder = DRAW_ORDER_DEFAULT;
}
if (needsPopulate) populate();
}
}
然後我們需要把裡面的布局文件進行一下更改:
<com.example.android_viewpager.ViewPagerCompate
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.example.android_viewpager.ViewPagerCompate>
然後把MainActivity進行一些更改:
mViewPager = (ViewPagerCompate) findViewById(R.id.viewPager);//修改系統提供的
這樣我們剛剛修改的效果就可以在3.0以後的版本顯示出來了,是不是感覺很神奇。最後我在為大家介紹一個效果:
public class RotateDownPagetransformer implements ViewPager.PageTransformer {
private static final float MAX_ROTATE = 20F;
private static float ROTATE = 0F;
/*
* 效果分析:
* 滑動可以分解為:A>B
* A的position:0.0 >> -1.0
* B的position:1.0 >> 0.0
* (non-Javadoc)
* @see android.support.v4.view.ViewPager.PageTransformer#
* transformPage(android.view.View, float)
*/
@Override
public void transformPage(View view, float position) {
int pageWidth = view.getWidth();
if (position < -1) { // [-Infinity,-1)
ViewHelper.setAlpha(view, 0);//設置透明度
} else if (position <= 0) { // A頁position:0.0 >> 1.0
//計算旋轉角度
ROTATE = MAX_ROTATE * position;
//設置旋轉中心
ViewHelper.setPivotX(view, pageWidth/2);
ViewHelper.setPivotY(view, view.getMeasuredHeight());
//設置選擇角度
ViewHelper.setRotation(view, ROTATE);
} else if (position <= 1) { // B頁position:1.0 >> 0.0
//計算旋轉角度
ROTATE = MAX_ROTATE * position;
//設置旋轉中心
ViewHelper.setPivotX(view, pageWidth/2);
ViewHelper.setPivotY(view, view.getMeasuredHeight());
//設置選擇角度
ViewHelper.setRotation(view, ROTATE);
} else { // (1,+Infinity]
ViewHelper.setAlpha(view, 0);
}
}
}
這是一個類似於扇形的切換效果,好了對於ViewPager的切換動畫就已經為大家介紹完畢,內容較多,大家有什麼疑問可以留言交流。