Android 는 사용자 정의 PageTransformer 를 사용 하여 개성 있 는 ViewPager 애니메이션 전환 효 과 를 구현 합 니 다.
15433 단어 androidPageTransformerViewPager
이전에 쓴 블 로그:Android 사용자 정의 ViewPager 는 변화무쌍 한 그림 전환 효 과 를 만 듭 니 다.어떤 형 제 는 ViewPager 가 setPageTransformer 를 가지 고 애니메이션 전환 을 설정 하 는 데 사 용 했 습 니 다~
이 박문 은 장군:
1.setPageTransformer 설정 을 사용 하여 애니메이션 전환 하 는 방법 을 소개 합 니 다.
2.PageTransformer 를 사용자 정의 하여 개성 있 는 전환 애니메이션 을 실현 합 니 다.
3.이 방법 은 SDK 11 이하 버 전에 서 작 동 하지 않 습 니 다.저 희 는 이 방법 을 어느 정도 수정 하여 아래로 호 환 하도록 하 겠 습 니 다.
공식 예제 주소:http://developer.android.com/training/animation/screen-slide.html 관심 있 으 면 가 봐 도 돼~~
자,다음은 코드 를 작성 하 겠 습 니 다~~
2.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 가 실현 되 었 습 니 다~~여러분 은 위 코드 에 대해 낯 설 지 않 을 것 입 니 다~실행 효과 도 스티커 를 붙 이지 않 아 도 됩 니 다.여러분 은 알 고 있 을 것 입 니 다~3、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 ;
순간 간단 하 다.
전체 코드:
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);
}
잘못 보지 않 았 습 니 다.if else 에 서 는 코드 가 같 습 니 다.이 해 를 위해 합 쳐 지지 않 았 습 니 다~~~이로써 저 희 는 setPageTransformer 에서 사용 하고 ViewPager 를 수정 하여 아래로 호 환 할 때 까지 개성 을 정의 하 는 전환 효과 가 소개 되 었 습 니 다~
여러분 은 자신의 창조력 을 발휘 하여 각종 신기 한 애니메이션 효 과 를 낼 수 있 습 니 다.ok,여기까지!
원본 클릭 다운로드
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.