Android 사용자 정의 ViewPager 맞 춤 형 이미지 전환 효과 구현
이러한 효과 의 그림 전환 을 보십시오:
전통 적 인 효과 보다 개성 이 많 지 않 습 니까?헤헤~~사실 간단 합 니 다.이 글 을 배우 고 나 면 전환 효 과 를 사용자 정의 하여 다양한 효 과 를 낼 수 있 습 니 다.
1.제작 전 분석
효과 도 를 살 펴 보면 실제 적 으로 바 뀐 것 은 전환 할 때의 애니메이션 입 니 다.그러면 간단 합 니 다.사용자 가 전환 할 때 현재 의 View 와 다음 View 를 받 은 다음 에 애니메이션 을 추가 하면 됩 니 다.
첫 번 째 단 계 는 사용자 가 전환 할 때의 현재 View 와 전환 할 목적 View 를 가 져 옵 니 다.
현재 View 와 목적 View 가 있 거나 애니메이션 에 대해 느 린 변화 가 필요 하 다 면 사용자 의 손짓 에 따라 미 끄 러 지 는 것 이 좋 습 니 다.예 를 들 어 상기 효과,사용자 가 미 끄 러 질 때 목적 사진 은 사용자 의 미끄럼 거리 에 따라 천천히 나타 나 고 점점 커진다.
두 번 째 단 계 는 애니메이션 의 경사도 변 화 를 디자인 한다.
분석 을 통 해 우 리 는 두 가지 절 차 를 정리 했다.다음은 우리 가 한 걸음 한 걸음 변화 하 는 이미지 전환 효 과 를 만 들 기 시작 했다.
2.사용자 전환 시 현재 View 와 전환 한 목적 View 를 가 져 옵 니 다.ViewPager 도 사용자 의 손짓 을 감청 해 야 하기 때문에 틀림없이 어떤 방법 을 제 공 했 을 것 이다.그래서 ViewPager 의 방법 을 살 펴 보면 onPageScrolled(int position,float position Offset,int position Offset Pixels)라 는 방법 을 발 견 했 습 니 다~~
맞아요.바로 이 방법 이에 요.페이지 가 굴 러 갈 때 호출~
다음은 이 몇 가지 매개 변 수 를 자세히 연구 해 보 겠 습 니 다.
테스트 결 과 를 직접 말 하 다.
첫 페이지 와 마지막 페이지 가 아 닐 때 다음 페이지 로 미 끄 러 지고 position 는 현재 페이지 의 위치 입 니 다.이전 페이지 로 미 끄 러 짐:position 는 현재 페이지-1
position Offset 이 다음 페이지 로 미 끄 러 지고[0,1)구간 이 변 합 니 다.이전 페이지 로 미 끄 러 짐:(1,0)구간 변화
position Offset Pixels 이것 은 position Offset 과 비슷 합 니 다.다음 페이지 로 미 끄 러 지고[0,너비)구간 에서 변화 합 니 다.이전 페이지 로 미 끄 러 짐:(너비,0)구간 변화
첫 페이지 시:이전 페이지 position=0 으로 미 끄 러 지 며,기타 기본 은 0 입 니 다.마지막 페이지 가 다음 페이지 position 로 미 끄 러 지 는 것 은 현재 페이지 의 위치 이 고 다른 두 매개 변 수 는 0 입 니 다.
우리 가 필요 로 하 는 절차 의 두 번 째 단계 가 해결 되 었 다 는 것 을 알 게 되 었 습 니 다.position Offset 는'그 라 데 이 션,확대 제어 파라미터'로 적합 합 니 다.position Offset Pixels 는 평이 등의 제어 매개 변수 로 사용 할 수 있 습 니 다.
그러면 현재 View 와 목적 View 를 어떻게 얻 습 니까?
나의 잘못된 길 을 몇 개 나 누 기:
1.【오 류】저 는 getChildAt(position),getChildAt(position+1),getChildAt(position-1)을 통 해 미 끄 러 질 때 좌우 두 개의 View 를 얻 습 니 다.언뜻 보기 에는 정말 괜 찮 은 것 같 습 니 다~~코드 에 쓰 면 언뜻 효과 가 나 오지 않 습 니 다~~오류 원인:우 리 는 아주 큰 것 을 무시 합 니 다.ViewPager 의 메커니즘 은 미 끄 러 질 때 동적 으로 View 를 불 러 오고 삭제 합 니 다.ViewPager 는 사실 2~3 개의 View 만 유지 하고 position 의 범 위 는 거의 무한 합 니 다~
2.【오 류】저 는 getCurrent Item 을 통 해 현재 위 치 를 얻 었 습 니 다.그리고+1,-1 획득 후 하나 또는 이전~~기 쁘 게 하고 있 습 니 다.코드 를 빨리 고치 고 있 습 니 다.효과 가 아무리 좋 지 않 아 도 엉망 입 니 다.로 그 를 자세히 살 펴 보 세 요.이 getCurrent Item 은 사용자 가 손가락 으로 떠 난 화면,Page 가 애니메이션 에서 실 행 될 때,바 뀌 었 어~어쩐지~전체 미끄럼 과정 이 고정 되 어 있 지 않 더 라~~에이,가슴 이 찢 어 졌어~
3.[오류]position 는 전체 미끄럼 과정 에서 변 하지 않 으 며 ViewPager 는 2 개 또는 3 개의 View 를 저장 합 니 다.그러면 저 는 첫 페이지 나 마지막 페이지 라면 getChildAt(0)과 getChildAt(1)을 선택 하고 다른 페이지 에 서 는 getChildAt(0),getChildAt(2)을 선택 한 다음 에 일련의 변 화 를 거 쳐 야 한다 고 생각 합 니 다.그래서 제 가 첫 번 째 문 제 를 만 났 을 때 좌우 position 가 0,니 마,이 중 어느 것 이 왼쪽 View 이 고 어느 것 이 오른쪽 View 입 니까?
이렇게 많은 잘못 을 말 했 으 니,여러분 은 이 커 브 길 을 돌아 갈 수도 있 고,이 커 브 길 안에서 무언 가 를 볼 수도 있 습 니 다~
다음은 정확 합 니 다.사실 ViewPager 는 View 를 추가 하거나 View 를 없 앨 때 우리 자신의 PageAdapter 에서 제어 할 수 있 습 니 다.그래서 우 리 는 ViewPager 에서 HashMap
그러면 다음 페이지 로 넘 어 집 니 다:왼쪽 View:map.get(position),오른쪽 View:map.get(position+1).
그러면 이전 페이지 로 미 끄 러 집 니 다:왼쪽 View:map.get(position),오른쪽 View:map.get(position+1),같은 것 입 니 다.이전 페이지 로 미 끄 러 지기 때문에 position 는 현재 페이지-1 입 니 다.
자,이제 우 리 는 모든 절 차 를 분석 하고 해결 했다.
3.코드
MainActivity
package com.example.zhy_jazzyviewpager;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
public class MainActivity extends Activity
{
protected static final String TAG = "MainActivity";
private int[] mImgIds;
private MyJazzyViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImgIds = new int[] { R.drawable.a, R.drawable.b, R.drawable.c,
R.drawable.d };
mViewPager = (MyJazzyViewPager) findViewById(R.id.id_viewPager);
mViewPager.setAdapter(new PagerAdapter()
{
@Override
public boolean isViewFromObject(View arg0, Object arg1)
{
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position,
Object object)
{
container.removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position)
{
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(mImgIds[position]);
imageView.setScaleType(ScaleType.CENTER_CROP);
container.addView(imageView);
mViewPager.setObjectForPosition(imageView, position);
return imageView;
}
@Override
public int getCount()
{
return mImgIds.length;
}
});
}
}
이 흔 한 코드 는 ViewPager 를 초기 화 하 는 것 입 니 다~~더 이상 할 말 이 없습니다~~주의 할 점 이 있 습 니 다.인 스 턴 트 Item 방법 에서 mViewPager.setObject ForPosition(imageView,position)을 하나 더 호출 했 습 니 다.사실 저희 맵 에 저 장 된 값 을 주기 위해 서 였 어 요.사용자 정의 ViewPager 를 주로 봅 니 다.
package com.example.zhy_jazzyviewpager;
import java.util.HashMap;
import java.util.LinkedHashMap;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import com.nineoldandroids.view.ViewHelper;
public class MyJazzyViewPager extends ViewPager
{
private float mTrans;
private float mScale;
/**
*
*/
private static final float SCALE_MAX = 0.5f;
private static final String TAG = "MyJazzyViewPager";
/**
* position View
*/
private HashMap<Integer, View> mChildrenViews = new LinkedHashMap<Integer, View>();
/**
*
*/
private View mLeft;
/**
*
*/
private View mRight;
public MyJazzyViewPager(Context context, AttributeSet attrs)
{
super(context, attrs);
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels)
{
// Log.e(TAG, "position=" + position+", positionOffset = "+positionOffset+" ,positionOffsetPixels = " + positionOffsetPixels+" , currentPos = " + getCurrentItem());
// , ,
float effectOffset = isSmall(positionOffset) ? 0 : positionOffset;
// View
mLeft = findViewFromObject(position);
// View
mRight = findViewFromObject(position + 1);
//
animateStack(mLeft, mRight, effectOffset, positionOffsetPixels);
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
public void setObjectForPosition(View view, int position)
{
mChildrenViews.put(position, view);
}
/**
* View
*
* @param position
* @return
*/
public View findViewFromObject(int position)
{
return mChildrenViews.get(position);
}
private boolean isSmall(float positionOffset)
{
return Math.abs(positionOffset) < 0.0001;
}
protected void animateStack(View left, View right, float effectOffset,
int positionOffsetPixels)
{
if (right != null)
{
/**
* ( ):0.0~1.0,
* ( ):1.0~0,
*/
mScale = (1 - SCALE_MAX) * effectOffset + SCALE_MAX;
/**
* x : ( ):0-720 ( ):720-0
*/
mTrans = -getWidth() - getPageMargin() + positionOffsetPixels;
ViewHelper.setScaleX(right, mScale);
ViewHelper.setScaleY(right, mScale);
ViewHelper.setTranslationX(right, mTrans);
}
if (left != null)
{
left.bringToFront();
}
}
}
핵심 코드 는 모두 onPageScrolled 입 니 다.findViewFromObject(position)를 통 해 알 수 있 습 니 다.findViewFromObject(position + 1);좌우 양쪽 의 View 를 각각 가 져 온 다음 에 애니메이션 효 과 를 추가 합 니 다.현재 이 예 에 두 개의 애니메이션 이 추가 되 었 습 니 다.하 나 는 0.5 에서 1.0 또는 1.0 으로 0.5 로 축소 되 었 습 니 다.맞습니다.우리 의 position Offset 에서 경사도 변 화 를 제공 합 니 다~그리고 이동 하 는 애니메이션 도 있 습 니 다.다음 페이지 는 현재 화면 으로 직접 이동 합 니 다(기본 값 은 오른쪽 입 니 다.이 효 과 를 설명 할 수 있 습 니 다.어떻게 실행 하 는 지 보 세 요).그리고 position Offset Pixels 를 통 해 기본 이동 시의 위 치 를 계속 상쇄 하여 사용자 로 하여 금 제자리 에서 확대 하고 축소 하 는 것 을 느끼 게 합 니 다~자,이렇게 실현 되 었 습 니 다~~당신 은 자신 이 좋아 하 는 애니메이션 효 과 를 마음대로 쓸 수 있 습 니 다.예 를 들 어 기본 값 에 페이드아웃 이나 신 마 를 추가 하여 마음대로~~편 하지 않 습 니까?
우리 의 레이아웃 파일:
<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"
>
<com.example.zhy_jazzyviewpager.MyJazzyViewPager
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/id_viewPager" />
</RelativeLayout>
4,JazzyViewPager 의 사용사실 위의 실현 은 바로 github 에서 Jazzy ViewPager 의 소스 코드 입 니 다.용법 은 말 할 필요 도 없 이 우리 의 MainActivity 입 니 다.약 10 가지 효과 가 내장 되 어 있 습 니 다.우 리 는 코드 나 레이아웃 을 통 해 애니메이션 효 과 를 설정 할 수 있 습 니 다~우리 위의 예 효 과 는 Stack 이 라 고 합 니 다.
JazzViewPager 코드 사용 하기:사실 거의 똑 같 아 요~마지막 에 JazzyViewPager 의 원본 코드 를 붙 여 다운로드 합 니 다
MainActivity
package com.jfeinstein.jazzyviewpager;
import com.jfeinstein.jazzyviewpager.JazzyViewPager.TransitionEffect;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.view.PagerAdapter;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
public class MainActivity extends Activity
{
protected static final String TAG = "MainActivity";
private int[] mImgIds;
private JazzyViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImgIds = new int[] { R.drawable.a, R.drawable.b, R.drawable.c,
R.drawable.d };
mViewPager = (JazzyViewPager) findViewById(R.id.id_viewPager);
//
mViewPager.setTransitionEffect(TransitionEffect.Stack);
mViewPager.setAdapter(new PagerAdapter()
{
@Override
public boolean isViewFromObject(View arg0, Object arg1)
{
return arg0 == arg1;
}
@Override
public void destroyItem(ViewGroup container, int position,
Object object)
{
container.removeView((View) object);
}
@Override
public Object instantiateItem(ViewGroup container, int position)
{
ImageView imageView = new ImageView(MainActivity.this);
imageView.setImageResource(mImgIds[position]);
imageView.setScaleType(ScaleType.CENTER_CROP);
container.addView(imageView);
mViewPager.setObjectForPosition(imageView, position);
return imageView;
}
@Override
public int getCount()
{
return mImgIds.length;
}
});
}
}
우리 코드 와 유일한 차이 점 은://전환 효과 설정
mViewPager.setTransitionEffect(TransitionEffect.Stack);
12 가지 선택 가능 한 전환 효과 가 있 습 니 다.사실은 12 개의 전환 애니메이션 을 썼 습 니 다~~
자,마지막 으로 제 가 좋아 하 는 효과:Tablet
원본 다운로드:ViewPager 그림 전환
이상 은 본 고의 모든 내용 입 니 다.여러분 이 안 드 로 이 드 소프트웨어 프로 그래 밍 을 배 우 는 데 도움 이 되 기 를 바 랍 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.