Android 는 변화무쌍 한 ViewPager 전환 애니메이션 을 실현 합 니 다.

전에 쓴 글 이 있 습 니 다Android 사용자 정의 ViewPager 맞 춤 형 이미지 전환 효과 구현어떤 친구 가 ViewPager 가 setPageTransformer 를 가지 고 애니메이션 전환 을 설정 하 는 데 사 용 했 습 니 다~
이 글 은 다음 과 같은 내용 의 학습 을 진행 할 것 이다.
1.setPageTransformer 설정 을 사용 하여 애니메이션 전환 하 는 방법 을 소개 합 니 다.
2.PageTransformer 를 사용자 정의 하여 개성 있 는 전환 애니메이션 을 실현 합 니 다.
3.이 방법 은 SDK 11 이하 버 전에 서 작 동 하지 않 습 니 다.저 희 는 이 방법 을 어느 정도 수정 하여 아래로 호 환 하도록 하 겠 습 니 다.
공식 예시 주소:http://developer.android.com/training/animation/screen-slide.html관심 있 는 것 은 가 보 세 요~~
자,다음은 코드 를 작성 하 겠 습 니 다~~
1.setPageTransformer 의 사용
우선 전통 적 인 ViewPager 효 과 를 빠르게 실현 해 보도 록 하 겠 습 니 다.
1.레이아웃 파일

<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.support.v4.view.ViewPager 
    android:id="@+id/id_viewpager" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" /> 
 
</RelativeLayout> 
2、MainActivity

package com.zhy.demo_zhy_08_viewpageranim; 
 
import java.util.ArrayList; 
import java.util.List; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.support.v4.view.PagerAdapter; 
import android.support.v4.view.ViewPager; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.Window; 
import android.widget.ImageView; 
import android.widget.ImageView.ScaleType; 
 
public class MainActivity extends Activity 
{ 
  private ViewPager mViewPager; 
  private int[] mImgIds = new int[] { R.drawable.guide_image1, 
      R.drawable.guide_image2, R.drawable.guide_image3 }; 
  private List<ImageView> mImageViews = new ArrayList<ImageView>(); 
 
  @Override 
  protected void onCreate(Bundle savedInstanceState) 
  { 
    super.onCreate(savedInstanceState); 
 
    requestWindowFeature(Window.FEATURE_NO_TITLE); 
    setContentView(R.layout.activity_main); 
 
    initData(); 
 
    mViewPager = (ViewPager) findViewById(R.id.id_viewpager); 
 
    mViewPager.setAdapter(new PagerAdapter() 
    { 
      @Override 
      public Object instantiateItem(ViewGroup container, int position) 
      { 
 
        container.addView(mImageViews.get(position)); 
        return mImageViews.get(position); 
      } 
 
      @Override 
      public void destroyItem(ViewGroup container, int position, 
          Object object) 
      { 
 
        container.removeView(mImageViews.get(position)); 
      } 
 
      @Override 
      public boolean isViewFromObject(View view, Object object) 
      { 
        return view == object; 
      } 
 
      @Override 
      public int getCount() 
      { 
        return mImgIds.length; 
      } 
    }); 
 
  } 
 
  private void initData() 
  { 
    for (int imgId : mImgIds) 
    { 
      ImageView imageView = new ImageView(getApplicationContext()); 
      imageView.setScaleType(ScaleType.CENTER_CROP); 
      imageView.setImageResource(imgId); 
      mImageViews.add(imageView); 
    } 
  } 
 
} 
자,이렇게 전통 적 인 ViewPager 가 실현 되 었 습 니 다~여러분 들 은 위 코드 에 대해 낯 설 지 않 을 것 입 니 다~실행 효과 도 스티커 를 붙 이지 않 아 도 됩 니 다.아 실 겁 니 다.
2.PageTransformer
ViewPager 라 는 방법 이 있 습 니 다.
setPageTransformer(boolean reverseDrawingOrder,PageTransformer transformer)는 ViewPager 전환 시의 애니메이션 효 과 를 설정 하 는 데 사용 되 며,구 글 공식 은 두 가지 예 를 제시 했다.
위 코드 에서 setPageTransformer 를 호출 하면 애니메이션 전환 효 과 를 추가 할 수 있 습 니 다~구 글 의 두 개의 PageTransformer 코드 와 실행 효 과 를 보 여 줍 니 다.
1)、DepthPageTransformer

public class DepthPageTransformer implements ViewPager.PageTransformer { 
  private static final float MIN_SCALE = 0.75f; 
 
  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); 
    } 
  } 
} 
호출 코드:
mViewPager.setPageTransformer(true, new DepthPageTransformer()); 
효과:

2)、ZoomOutPageTransformer

package com.zhy.view; 
 
import android.annotation.SuppressLint; 
import android.support.v4.view.ViewPager; 
import android.util.Log; 
import android.view.View; 
 
public class ZoomOutPageTransformer implements ViewPager.PageTransformer 
{ 
  private static final float MIN_SCALE = 0.85f; 
  private static final float MIN_ALPHA = 0.5f; 
 
  @SuppressLint("NewApi") 
  public void transformPage(View view, float position) 
  { 
    int pageWidth = view.getWidth(); 
    int pageHeight = view.getHeight(); 
 
    Log.e("TAG", view + " , " + position + ""); 
 
    if (position < -1) 
    { // [-Infinity,-1) 
      // This page is way off-screen to the left. 
      view.setAlpha(0); 
 
    } else if (position <= 1) //a    b  ; a   0.0 -1 ;b  1 ~ 0.0 
    { // [-1,1] 
      // Modify the default slide transition to shrink the page as well 
      float scaleFactor = Math.max(MIN_SCALE, 1 - Math.abs(position)); 
      float vertMargin = pageHeight * (1 - scaleFactor) / 2; 
      float horzMargin = pageWidth * (1 - scaleFactor) / 2; 
      if (position < 0) 
      { 
        view.setTranslationX(horzMargin - vertMargin / 2); 
      } else 
      { 
        view.setTranslationX(-horzMargin + vertMargin / 2); 
      } 
 
      // Scale the page down (between MIN_SCALE and 1) 
      view.setScaleX(scaleFactor); 
      view.setScaleY(scaleFactor); 
 
      // Fade the page relative to its size. 
      view.setAlpha(MIN_ALPHA + (scaleFactor - MIN_SCALE) 
          / (1 - MIN_SCALE) * (1 - MIN_ALPHA)); 
 
    } else 
    { // (1,+Infinity] 
      // This page is way off-screen to the right. 
      view.setAlpha(0); 
    } 
  } 
} 
호출 코드:
mViewPager.setPageTransformer(true, new ZoomOutPageTransformer()); 
효과:

효과 도 는 모두 구 글 홈 페이지 에 있 습 니 다.우리 의 테스트 도 는 호 환 3.0 이하 로 붙 여 집 니 다.그렇지 않 으 면 중복 됩 니 다~~
ViewPager 에 전환 코드 를 추가 하 는 것 은 매우 행복 하지 않 습 니까?안 타 깝 게 도 3.0 이하 버 전이 호 환 되 지 않 습 니 다.이 방법 에 대한 설명 은 다음 과 같 습 니 다.
setting a PageTransformer prior to Android 3.0(API 11)will have no effect 3.0 이전 버 전에 서 이 방법 을 설정 하 는 것 은 효과 가 없습니다.그러면 3.0 이하 버 전 을 호 환 하 는 방법 을 살 펴 보 겠 습 니 다.
3.버 전의 아래로 호 환
1)호 환 되 지 않 는 이유
우선 왜 호 환 되 지 않 는 지,3.0 이하?
위의 두 개의 예제 코드 를 보면 코드 에서 View 의 애니메이션 은 속성 애니메이션 을 사용 하고 속성 애니메이션 은 3.0 이 되 어서 출시 된 것 이다.그러면 이렇게 쓰 면 3.0 이하 가 호 환 되 지 않 을 것 이다.
그러면 우 리 는 먼저 나 인 올 드 안 드 로 이 드 를 도입 하여 애니메이션 이 3.0 이하 에서 뛸 수 있 도록 하 겠 습 니 다.
DepthPageTransformer 수정

package com.zhy.view; 
 
import com.nineoldandroids.view.ViewHelper; 
 
import android.annotation.SuppressLint; 
import android.support.v4.view.ViewPager; 
import android.view.View; 
 
public class DepthPageTransformer implements ViewPager.PageTransformer 
{ 
  private static final float MIN_SCALE = 0.75f; 
 
  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)// a    b  ; a   0.0 -1 ;b  1 ~ 0.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 - position); 
      // view.setScaleX(scaleFactor); 
      ViewHelper.setScaleX(view, scaleFactor); 
      // view.setScaleY(1); 
      ViewHelper.setScaleY(view, scaleFactor); 
 
    } else 
    { // (1,+Infinity] 
      // This page is way off-screen to the right. 
      // view.setAlpha(0); 
      ViewHelper.setAlpha(view, 1); 
    } 
  } 
} 
간단 합 니 다.모든 속성 애니메이션 을 ViewHelper 로 바 꾸 어 설정 하면 됩 니 다.지금 우 리 는 3.0 이하 의 기계 에 가서 운행 하 는데,여전히 효과 가 없다 는 것 을 발견 하 였 다.
왜 일 까요?
setPageTransformer 의 소스 코드 를 다시 보 러 갑 니 다.

public void setPageTransformer(boolean reverseDrawingOrder, PageTransformer transformer) { 
    if (Build.VERSION.SDK_INT >= 11) { 
      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(); 
    } 
  } 
드디어 원인 을 발 견 했 습 니 다.이 방법 은 내부 적 으로 11 이상 의 버 전이 어야 애니메이션 이 유효 하 다 고 판 단 했 습 니 다~
그럼 어 쩔 수 없어 요.호 환 하려 면 ViewPager 의 소스 코드 를 수정 해 야 해 요~~
2)、완벽 하 게 아래로 호 환
우 리 는 ViewPager 의 원본 코드 를 우리 의 프로젝트 에 복사 하고 이름 을 ViewPager Compat 로 변경 합 니 다.그리고 SDK 버 전 을 주석 을 달 아서 그 문장 을 판단 합 니 다.

public class ViewPagerCompat extends ViewGroup {
public void setPageTransformer(boolean reverseDrawingOrder, ViewPager.PageTransformer transformer) { 
//    if (Build.VERSION.SDK_INT >= 11)  
    { 
      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(); 
    } 
  } 
...
}
모든 PageTransformer 는 ViewPager.PageTransformer 를 사용 합 니 다.
그리고 우 리 는 프로젝트 중의 ViewPager 를 ViewPager Compat 로 바 꿉 니 다.레이아웃 파일 수정 및 MainActivity 의 ViewPager 를 ViewPager Compat 로 기억 하 십시오.
우 리 는 2.3.3 의 시 뮬 레이 터 에서 효 과 를 테스트 했다.

보시 다시 피 우리 의 전환 애니메이션 은 2.3.3 기기 에서 완벽 하 게 작 동 합 니 다~~so happy~~ViewPager 소스 가 없 는 어린이 신발 은 괜 찮 습 니 다.저 는 마지막 소스 다운로드 에 ViewPager 소스 코드 를 추가 하여 마음껏 테스트 할 수 있 도록 하 겠 습 니 다~~
물론 호 환 만 으로 는 우리 의 호기심 을 만족 시 킬 수 없습니다.우리 가 호 환 을 했 는 지 Google 이 준 예제 애니메이션 만 사용 할 수 있 습 니까?우리 의 강력 한 혁신 은?
4.사용자 정의 PageTransformer 개성 전환 애니메이션 실현

public interface PageTransformer { 
    /** 
    * Apply a property transformation to the given page. 
    * 
    * @param page Apply the transformation to this page 
    * @param position Position of page relative to the current front-and-center 
    *         position of the pager. 0 is front and center. 1 is one full 
    *         page position to the right, and -1 is one page position to the left. 
    */ 
    public void transformPage(View page, float position); 
  } 
이 인 터 페 이 스 를 볼 수 있 는 방법 은 딱 하나,첫 번 째 는 우리 뷰,두 번 째 는 position~~
우리 가 미 끄 러 질 때:물론 ViewPager 에 살 아 있 는 모든 View 와 그들의 position 의 변 화 를 출력 합 니 다~모든 것 에 주의 하 세 요.그 러 니 log position 만 하지 마 세 요.그렇지 않 으 면 이상 하 게 출력 할 수 있 습 니 다~~
position 의 가능성 치 는 공식 예제 의 주석 에서 알 수 있 습 니 다.
[-Infinity,-1)  이제 안 보 여요.
(1,+인 피 니 티]이제 안 보 여.
 [-1,1]
중점적으로[-1,1]이 구간 을 보면 다른 두 개의 View 는 이미 보이 지 않 습 니 다~
현재 ViewPager 가 A 페이지 에서 B 페이지 를 미 끄 러 지고 있다 고 가정 하면:
A 페이지 의 position 변 화 는 바로(0,-1)
B 페이지 의 position 변 화 는 바로[1,0]이다.
우리 가 미 끄 러 질 때 position 의 변 화 를 알 게 되 었 습 니 다~그러면 우리 의 개성 전환 효 과 를 디자인 합 니 다.
공식 적 으로 준 예 는 변화 투명도,오프셋,크기 가 있 습 니 다.우 리 는 다른 것 을 준비 합 니 다.우 리 는 각도,즉 rotation 을 변화 시 킵 니 다.
대략적인 효 과 는 이렇다.

다음은 코드 분석:
View 의 회전 중심 을 설정 합 니 다:

ViewHelper.setPivotX(view, view.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(view, view.getMeasuredHeight());
여전히 ViewPager 는 A 쪽 에서 B 쪽 이 빠 져 나 오고 있 습 니 다.
그러면 A 페이지 는 미끄럼 과정 에서 0 도 에서 20 도 까지 의 오프셋 이 있어 야 하고 B 페이지 는 미끄럼 과정 에서+20 도 에서 0 도 까지 의 오프셋 이 있어 야 한다.
결합 하 다
A 페이지 의 position 변 화 는 바로(0,-1)
B 페이지 의 position 변 화 는 바로[1,0]이다.
그러면 회전 하 는 각 도 는:mRot=(20*position)입 니 다.A 페이지 mRot:0,~-20;B 페이지 mRot:20~0  ;
순간 간단 하 다.
전체 코드:

package com.zhy.view; 
 
import com.nineoldandroids.view.ViewHelper; 
 
import android.annotation.SuppressLint; 
import android.support.v4.view.ViewPager; 
import android.util.Log; 
import android.view.View; 
 
public class RotateDownPageTransformer implements ViewPager.PageTransformer 
{ 
   
  private static final float ROT_MAX = 20.0f; 
  private float mRot; 
   
 
   
  public void transformPage(View view, float position) 
  { 
 
    Log.e("TAG", view + " , " + position + ""); 
 
    if (position < -1) 
    { // [-Infinity,-1) 
      // This page is way off-screen to the left. 
      ViewHelper.setRotation(view, 0); 
 
    } else if (position <= 1) // a    b  ; a   0.0 ~ -1 ;b  1 ~ 0.0 
    { // [-1,1] 
      // Modify the default slide transition to shrink the page as well 
      if (position < 0) 
      { 
 
        mRot = (ROT_MAX * position); 
        ViewHelper.setPivotX(view, view.getMeasuredWidth() * 0.5f); 
        ViewHelper.setPivotY(view, view.getMeasuredHeight()); 
        ViewHelper.setRotation(view, mRot); 
      } else 
      { 
 
        mRot = (ROT_MAX * position); 
        ViewHelper.setPivotX(view, view.getMeasuredWidth() * 0.5f); 
        ViewHelper.setPivotY(view, view.getMeasuredHeight()); 
        ViewHelper.setRotation(view, mRot); 
      } 
 
      // Scale the page down (between MIN_SCALE and 1) 
 
      // Fade the page relative to its size. 
 
    } else 
    { // (1,+Infinity] 
      // This page is way off-screen to the right. 
      ViewHelper.setRotation(view, 0); 
    } 
  } 
} 
잘못 보지 않 았 습 니 다.if else 에 있 는 코드 는 같 습 니 다.이 해 를 위해 합 쳐 지지 않 았 습 니 다.
이로써 저 희 는 setPageTransformer 에서 사용 하고 ViewPager 를 수정 하여 아래로 호 환 할 때 까지 개성 을 정의 하 는 전환 효과 가 소개 되 었 습 니 다.여러분 은 자신의 창조력 을 발휘 하여 각종 신기 한 애니메이션 효 과 를 낼 수 있 습 니 다.ok,여기까지!
사용자 정의 ViewPager 를 원한 다 면 이동 하 십시오Android 사용자 정의 ViewPager 맞 춤 형 이미지 전환 효과 구현
원본 다운로드:ViewPager 애니메이션 전환
이상 은 본 고의 모든 내용 입 니 다.여러분 이 안 드 로 이 드 소프트웨어 프로 그래 밍 을 배 우 는 데 도움 이 되 기 를 바 랍 니 다.

좋은 웹페이지 즐겨찾기