안 드 로 이 드 스크롤 러 비밀 폭로

22681 단어 androidscroller
Scroller 를 사용 하 는 것 을 배우 기 전에 scrollTo(),scrollBy()방법 을 알 아야 합 니 다.
1.View 의 scrollTo(),scrollBy()
scrollto,scrollBy 방법 은 View 에 있 기 때문에 모든 View 는 이 두 가지 방법 으로 이동 할 수 있 습 니 다.우선 scrollto,scrollBy 가 미 끄 러 지 는 것 은 View 자체 가 아니 라 View 의 내용(그것 도 전체 미끄럼)이라는 것 을 알 아야 한다.우리 의 미끄럼 컨트롤,예 를 들 어 SrillView 는 너비,높이,레이아웃 에 있 는 위 치 를 제한 할 수 있 지만 미끄럼 컨트롤 의 내용(또는 안의 childView)은 무한 길이,너비 일 수 있 습 니 다.우 리 는 View 의 scrollto,scrollBy 방법 을 호출 하여 미끄럼 컨트롤 의 캔버스 를 이동 한 다음 에 다시 그 리 는 것 과 같 습 니 다.화면 에 도 해당 하 는 내용 을 표시 합 니 다.다음 과 같다.

1、getScrollX()、getScrollY()
scrollto(),scrollBy()를 배우 기 전에 getScrollX(),getScrolly()방법 을 알 아 보 세 요.
getScrollX(),getScrolly()는 오프셋 을 얻 습 니 다.자신의 초기 위치 에 대한 미끄럼 오프셋 거리 입 니 다.scroll 이벤트 가 발생 했 을 때 만 이 두 가지 방법 이 값 을 가 질 수 있 습 니 다.그렇지 않 으 면 getScrollX(),getScrolly()는 모두 초기 값 0 입 니 다.이 미끄럼 컨트롤 이 어디 에 있 든 간 에.자신의 초기 위치 란 컨트롤 이 처음 표시 되 었 을 때 미 끄 러 지기 전의 위 치 를 말한다.getScrollX()를 예 로 들 면 원본 코드 는 다음 과 같 습 니 다.

 public final int getScrollX() {
 return mScrollX;
}
getScrollX()가 직접 돌아 오 는 것 을 볼 수 있 는 것 은 mScrollX 입 니 다.수평 방향의 편 이 량 을 대표 하고 getScrolly()도 유사 합 니 다.오프셋 mScrollX 의 양,음 은 미끄럼 컨트롤 의 내용 이 초기 위치 에 비해 수평 방향 으로 이동 하 는 상황 을 나타 내 고 mScrollX 는 현재 내용 이 초기 위치 에 비해 왼쪽으로 mScrollX 의 거 리 를 이동 하 는 것 을 나타 내 며 mScrollX 는 현재 내용 이 초기 위치 에 비해 오른쪽으로 mScrollX 의 거 리 를 이동 하 는 것 을 나타 낸다.
이곳 의 좌 표 는 우리 의 일반적인 인식 과 정반 대 이다.앞으로 미끄럼 과 관련 된 좌표 와 오프셋 을 더욱 편리 하 게 처리 하기 위해 오프셋,미끄럼 과 관련 된 기능 을 처리 할 때 우 리 는 좌 표를 거꾸로 볼 수 있다.다음 과 같은 그림 이다.

미끄럼 컨트롤 의 내용 은 전체적으로 미 끄 러 지 는 동시에 자신 이 표시 할 때의 초기 위치 에 대한 오프셋 이기 때문에 View 의 내용 이 오프셋 할 때 참고 좌표 원점(내용 보기 의 좌표 원점 이지 그림 에서 말 하 는 미끄럼 컨트롤 의 원점 이 아 닙 니 다)에 대해 초기 위치 어 딘 가 를 선택 할 수 있 습 니 다.미 끄 러 질 때 전체적인 행동 이기 때 문 입 니 다.미끄럼 을 진행 할 때 이 선택의 원점 에서 분석 하면 된다.
2、scrollTo()、scrollBy()
scrollTo(int x,int y)는 View 의 내용 을 이동 합 니 다.미끄럼 컨트롤 의 내용 은 모두 전체적으로 이동 합 니 다.scrollTo(int x,int y)의 매개 변 수 는 View 의 내용 이 내용 의 초기 위치 에 비해 x 와 y 의 거 리 를 이동 하고 내용 을 거리 내 에서 초기 위치 x 와 y 의 위치 로 이동 하 는 것 을 나타 냅 니 다.앞에서 말 한 바 와 같이 오프셋,미끄럼 문 제 를 처리 할 때 좌표계 와 평소에 인지 하 는 좌표계 가 반대 이다.하나의 예 로 scrollto()를 설명 합 니 다.
설명:그림 에서 노란색 사각형 구역 은 미끄럼 가능 한 View 컨트롤 을 나타 내 고 녹색 점선 사각형 은 미끄럼 컨트롤 의 미끄럼 내용 입 니 다.이곳 의 좌 표 는 반대 입 니 다.(예 는 다음 과 같다http://blog.csdn.net/bigconvience/article/details/26697645)
(1)scrollTo(100,0)를 호출 하여 View 의 내용 을 내용 의 초기 표시 위치 에서 x=100,y=0 으로 이동 시 키 는 것 을 표시 합 니 다.효 과 는 다음 그림 과 같 습 니 다.

(2)scrollTo(0,100)효 과 를 다음 그림 과 같이 호출 합 니 다.

(3)scrollTo(100,100)효 과 를 다음 그림 과 같이 호출 합 니 다.

(4)scrollTo(-100,0)효 과 를 다음 그림 과 같이 호출 합 니 다.

위의 몇 개의 그림 을 통 해 scrollto 의 역할 과 미끄럼 좌표계 의 관 계 를 뚜렷하게 볼 수 있다.실제 사용 중,우 리 는 일반적으로 onTouchEvent()방법 에서 미끄럼 사건 을 처리 하고,MotionEvent.ACTIONMOVE 시 scrollTo(int x,int y)를 호출 하여 미 끄 러 집 니 다.scrollTo(int x,int y)를 호출 하기 전에 우 리 는 먼저 두 개의 매개 변수 값,즉 수평 과 수직 방향 이 미 끄 러 져 야 하 는 거 리 를 계산 해 야 합 니 다.다음 과 같 습 니 다.

@Override 
public boolean onTouchEvent(MotionEvent event) { 
 int y = (int) event.getY(); 
 int action = event.getAction(); 
 switch (action){ 
 case MotionEvent.ACTION_DOWN: 
 mLastY = y; 
 break; 
 case MotionEvent.ACTION_MOVE: 
 int dy = mLastY - y;//            
 int oldScrollY = getScrollY();//               
 int scrollY = oldScrollY + dy;//         =         +            
 if(scrollY < 0){ 
 scrollY = 0; 
 } 
 if(scrollY > getHeight() - mScreenHeight){ 
 scrollY = getHeight() - mScreenHeight; 
 } 
 scrollTo(getScrollX(),scrollY); 
 mLastY = y; 
 break; 
 } 
 return true; 
} 
위 에서 파 라 메 터 를 계산 할 때 세 단계 로 나 뉜 다.첫 번 째 는 int dy=mLasty-y 를 통 해이번 제스처 가 화면 에서 얼마나 미 끄 러 졌 는 지 얻 을 수 있 습 니 다.여 기 는 이 감소 순 서 를 특히 주의해 야 합 니 다.이곳 의 좌 표 는 평소 와 반대 되 기 때문에 제스처 미끄럼 거 리 는 눌 렀 을 때의 좌표 mLasty-현재 의 좌표 y 입 니 다.두 번 째 는 oldScrolly=getScrolly()를 통 해미끄럼 내용 을 얻 기 전에 초기 위치 에서 얼마나 싸 졌 습 니까?세 번 째 는 이번에 오프셋 이 필요 한 인자 int scrollY=oldScrolly+dy 를 계산 하 는 것 입 니 다.뒤에 두 개의 if 조건 을 통 해 경계 처 리 를 한 다음 scrollto 를 호출 하여 미 끄 러 집 니 다.scrollto 를 호출 한 후 새로운 오프셋 이 다시 생 겼 습 니 다.scrollto 원본 에서 볼 수 있 습 니 다:

public void scrollTo(int x, int y) { 
 if (mScrollX != x || mScrollY != y) { 
 int oldX = mScrollX; 
 int oldY = mScrollY; 
 mScrollX = x;//    x    
 mScrollY = y;//    y    
 invalidateParentCaches(); 
 onScrollChanged(mScrollX, mScrollY, oldX, oldY); 
 if (!awakenScrollBars()) { 
 postInvalidateOnAnimation(); 
 } 
 } 
 } 
scrollTo 는 초기 위치 에 비해 이동 하고 scrollBy(int x,int y)는 이전 이동 거리 에 비해 이동 합 니 다.scrollBy 는 사실 scrollto 에 의존 합 니 다.다음 소스 코드 입 니 다.

public void scrollBy(int x, int y) { 
 scrollTo(mScrollX + x, mScrollY + y); 
 } 
scroll By 를 사용 하 는 것 은 우리 가 scrollto 인 자 를 계산 할 때의 세 번 째 단 계 를 생략 한 것 임 을 알 수 있 습 니 다.scroll By 내부 에서 세 번 째 계산 을 추가 해 주 었 기 때 문 입 니 다.따라서 scrollBy 의 역할 은 지난번 의 오프셋 상황 에서 이번 의 오프셋 을 하 는 것 과 같다.
완전한 수평 방향 으로 미 끄 러 지 는 예:

public class MyViewPager extends ViewGroup { 
 private int mLastX; 
 public MyViewPager(Context context) { 
 super(context); 
 init(context); 
 } 
 public MyViewPager(Context context, AttributeSet attrs) { 
 super(context, attrs); 
 init(context); 
 } 
 public MyViewPager(Context context, AttributeSet attrs, int defStyleAttr) { 
 super(context, attrs, defStyleAttr); 
 init(context); 
 } 
 private void init(Context context) { 
 } 
 @Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 int count = getChildCount(); 
 for(int i = 0; i < count; i++){ 
 View child = getChildAt(i); 
 child.measure(widthMeasureSpec,heightMeasureSpec); 
 } 
 } 
 @Override 
 protected void onLayout(boolean changed, int l, int t, int r, int b) { 
 int count = getChildCount(); 
 Log.d("TAG","--l-->"+l+",--t-->"+t+",-->r-->"+r+",--b-->"+b); 
 for(int i = 0; i < count; i++){ 
 View child = getChildAt(i); 
 child.layout(i * getWidth(), t, (i+1) * getWidth(), b); 
 } 
 } 
 @Override 
 public boolean onTouchEvent(MotionEvent ev) { 
 int x = (int) ev.getX(); 
 switch (ev.getAction()){ 
 case MotionEvent.ACTION_DOWN: 
 mLastX = x; 
 break; 
 case MotionEvent.ACTION_MOVE: 
 int dx = mLastX - x; 
 int oldScrollX = getScrollX();//       
 int preScrollX = oldScrollX + dx;//            
 if(preScrollX > (getChildCount() - 1) * getWidth()){ 
  preScrollX = (getChildCount() - 1) * getWidth(); 
 } 
 if(preScrollX < 0){ 
  preScrollX = 0; 
 } 
 scrollTo(preScrollX,getScrollY()); 
 mLastX = x; 
 break; 
 } 
 return true; 
 } 
} 
레이아웃 파일:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical"> 

 <com.scu.lly.viewtest.view.MyViewPager 
android:layout_width="match_parent" 
android:layout_height="300dp" 
> 
 <ImageView 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:scaleType="fitXY" 
android:src="@drawable/test1" /> 

 <ImageView 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:scaleType="fitXY" 
android:src="@drawable/test2" /> 

 <ImageView 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:scaleType="fitXY" 
android:src="@drawable/test3" /> 

 <ImageView 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:scaleType="fitXY" 
android:src="@drawable/test4" /> 
 </com.scu.lly.viewtest.view.MyViewPager> 
</LinearLayout> 
효과 그림:

2.Scroller 슬라이딩 보조 클래스
위의 분석 을 통 해 알 수 있 듯 이 View 의 scrollTo(),scrollBy()는 순식간에 완 성 된 것 입 니 다.우리 의 손가락 이 화면 에서 이동 할 때 내용 은 손가락 을 따라 미 끄 러 지지 만 손가락 을 들 면 미 끄 러 짐 이 멈 춥 니 다.우리 가 습관 적 인 스크롤 과정 효과 와 리 턴 효 과 를 얻 으 려 면 Scroller 보조 류 를 사용 해 야 합 니 다.
그러나 주의해 야 할 것 은 Scroller 자체 가 View 를 이동 하지 않 습 니 다.이것 은 이동 계산 보조 류 일 뿐 컨트롤 이 미 끄 러 지 는 궤적 을 추적 하 는 데 사 용 됩 니 다.스크롤 궤적 기록 도구 에 해당 하고 결국은 View 의 scrollTo,scrollBy 방법 으로 View 의 이동 을 완성 합 니 다.
Scroller 클래스 를 사용 하기 전에 중요 한 두 가지 방법 을 알 아 보 세 요.
(1)startScroll()public void startScroll(int startX, int startY, int dx, int dy, int duration)애니메이션 제 어 를 시작 합 니 다.(startX,startY)duration 시간 내 에 전진(dx,dy)단위,즉 오프셋 좌표(startX+dx,startY+dy)에 도착 합 니 다.
(2)computeScrollOffset()public boolean computeScrollOffset()미끄럼 과정 에서 현재 사라 진 시간 에 따라 현재 오프셋 된 좌표 점 을 계산 하여 mCurrX 와 mCurrY 값 에 저장 합 니 다.
위의 두 가지 방법의 소스 코드 는 다음 과 같다.

public class Scroller {
private int mStartX;//    ,          
private int mStartY;//    ,          
private int mFinalX;//          ,    
private int mFinalY;//          ,    
private int mCurrX;//     ,                    ,    
private int mCurrY;//     ,                    ,    
private int mDuration; //         
private float mDeltaX;//     ,   mFinalX         ,    
private float mDeltaY;//     ,   mFinalX         ,    
public void startScroll(int startX, int startY, int dx, int dy) {
 startScroll(startX, startY, dx, dy, DEFAULT_DURATION);
}
/**
 *         , (startX , startY) duration     (dx,dy)   ,        (startX+dx , startY+dy) 
*/
public void startScroll(int startX, int startY, int dx, int dy, int duration) {
 mMode = SCROLL_MODE;
 mFinished = false;
 mDuration = duration;
 mStartTime = AnimationUtils.currentAnimationTimeMillis();
 mStartX = startX;
 mStartY = startY;
 mFinalX = startX + dx;//              
 mFinalY = startY + dy;
 mDeltaX = dx;
 mDeltaY = dy;
 mDurationReciprocal = 1.0f / (float) mDuration;
}
/**
 *      ,                     ,   mCurrX mCurrY  
 * @return
*/
public boolean computeScrollOffset() {
 if (mFinished) {//           ,     false
 return false;
 }
 int timePassed = (int)(AnimationUtils.currentAnimationTimeMillis() - mStartTime);
 if (timePassed < mDuration) {
 switch (mMode) {
 case SCROLL_MODE:
 final float x = mInterpolator.getInterpolation(timePassed * mDurationReciprocal);
 mCurrX = mStartX + Math.round(x * mDeltaX);//            ,x 
 mCurrY = mStartY + Math.round(x * mDeltaY);//            ,y 
 break;
 ...
 }
 }else {
 mCurrX = mFinalX;
 mCurrY = mFinalY;
 mFinished = true;
 }
 return true;
 }
 ...
}
Scroller 류 에서 가장 중요 한 두 가지 방법 은 startScroll()과 coptute Scroll Offset()입 니 다.그러나 Scroller 류 는 미끄럼 계산 보조 류 일 뿐 이 며,startScroll()과 coptute Scroll Offset()방법 에서 도 일부 궤적 매개 변 수 를 설정 하고 계산 할 뿐 입 니 다.진정 으로 미끄럼 을 하려 면 View 의 scrollTo(),scrollBy()방법 을 통 해 해 해 해 야 합 니 다.이 를 위해 View 에 서 는 이 미끄럼 절 차 를 제어 하기 위해 coptute Scroll()방법 을 제공 합 니 다.컴퓨터 스크롤()방법 은 하위 보 기 를 그 릴 때 호출 됩 니 다.그 소스 코드 는 다음 과 같다.

/** 
 * Called by a parent to request that a child update its values for mScrollX 
 * and mScrollY if necessary. This will typically be done if the child is 
 * animating a scroll using a {@link android.widget.Scroller Scroller} 
 * object. 
 *                    mScrollX,mScrollY     
 */ 
public void computeScroll() { //    ,        ViewGroup        
 
} 
따라서 Scroller 류 의 기본 사용 절 차 는 다음 과 같다.
(1)먼저 Scroller 류 의 startScroll()을 통 해 미끄럼 애니메이션 제 어 를 시 작 했 고 그 안에서 궤적 파라미터 의 설정 과 계산 을 실시 했다.
(2)startScroll()을 호출 한 후에 invalidate()를 호출 합 니 다.보기 의 다시 그리 기 동작 을 일 으 켜 ViewGroup 의 coptute Scroll()이 호출 되 었 습 니 다.
(3)coptute Scroll()방법 에 서 는 Scroller 류 의 coptute ScrollOffset()방법 을 먼저 호출 합 니 다.그 안에 현재 소 모 된 시간 에 따라 궤적 좌 표를 계산 한 다음 에 계 산 된 현재 미 끄 러 지 는 오프셋 좌 표를 얻 고 View 의 scrollTo()방법 으로 미끄럼 제 어 를 합 니 다.마지막 으로 invalidate()를 호출 해 야 합 니 다.다시 그리다.
다음 과 같은 간단 한 코드 예제:  

@Override 
 public boolean onTouchEvent(MotionEvent ev) { 
 initVelocityTrackerIfNotExists(); 
 mVelocityTracker.addMovement(ev); 
 int x = (int) ev.getX(); 
 switch (ev.getAction()){ 
 case MotionEvent.ACTION_DOWN: 
 if(!mScroller.isFinished()){ 
  mScroller.abortAnimation(); 
 } 
 mLastX = x; 
 break; 
 case MotionEvent.ACTION_MOVE: 
 int dx = mLastX - x; 
 int oldScrollX = getScrollX();//       
 int preScrollX = oldScrollX + dx;//            
 if(preScrollX > (getChildCount() - 1) * getWidth()){ 
  preScrollX = (getChildCount() - 1) * getWidth(); 
 } 
 if(preScrollX < 0){ 
  preScrollX = 0; 
 } 
 //       
 mScroller.startScroll(mScroller.getFinalX(),mScroller.getFinalY(),dx,0);//    
 //  ,     invalidate    ,  computeScroll()  ,     startScroll()   Scroller ,       ,           
 invalidate(); 
 mLastX = x; 
 break; 
 } 
 return true; 
 } 
 @Override 
 public void computeScroll() { 
 super.computeScroll(); 
 if(mScroller.computeScrollOffset()){//    
 scrollTo(mScroller.getCurrX(),mScroller.getCurrY());//    
 invalidate(); 
 } 
 } 
다음은 완전한 예 입 니 다.ViewPager 와 유사 한 Demo 입 니 다.효과 도 는 다음 과 같 습 니 다.

코드 는 다음 과 같 습 니 다:

public class MyViewPager3 extends ViewGroup { 

 private int mLastX; 

 private Scroller mScroller; 
 private VelocityTracker mVelocityTracker; 
 private int mTouchSlop; 
 private int mMaxVelocity; 
 /** 
 *             
 */ 
 private int mCurrentPage = 0; 

 public MyViewPager3(Context context) { 
 super(context); 
 init(context); 
 } 

 public MyViewPager3(Context context, AttributeSet attrs) { 
 super(context, attrs); 
 init(context); 
 } 

 public MyViewPager3(Context context, AttributeSet attrs, int defStyleAttr) { 
 super(context, attrs, defStyleAttr); 
 init(context); 
 } 

 private void init(Context context) { 
 mScroller = new Scroller(context); 
 ViewConfiguration config = ViewConfiguration.get(context); 
 mTouchSlop = config.getScaledPagingTouchSlop(); 
 mMaxVelocity = config.getScaledMinimumFlingVelocity(); 
 } 

 @Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 int count = getChildCount(); 
 for(int i = 0; i < count; i++){ 
 View child = getChildAt(i); 
 child.measure(widthMeasureSpec, heightMeasureSpec); 
 } 
 } 

 @Override 
 protected void onLayout(boolean changed, int l, int t, int r, int b) { 
 int count = getChildCount(); 
 Log.d("TAG","--l-->"+l+",--t-->"+t+",-->r-->"+r+",--b-->"+b); 
 for(int i = 0; i < count; i++){ 
 View child = getChildAt(i); 
 child.layout(i * getWidth(), t, (i + 1) * getWidth(), b); 
 } 
 } 

 @Override 
 public boolean onTouchEvent(MotionEvent ev) { 
 initVelocityTrackerIfNotExists(); 
 mVelocityTracker.addMovement(ev); 
 int x = (int) ev.getX(); 
 switch (ev.getAction()){ 
 case MotionEvent.ACTION_DOWN: 
 if(!mScroller.isFinished()){ 
  mScroller.abortAnimation(); 
 } 
 mLastX = x; 
 break; 
 case MotionEvent.ACTION_MOVE: 
 int dx = mLastX - x; 
 /*         startScroll()       
 int oldScrollX = getScrollX();//       
 int preScrollX = oldScrollX + dx;//            
 if (preScrollX > (getChildCount() - 1) * getWidth()) { 
  preScrollX = (getChildCount() - 1) * getWidth(); 
  dx = preScrollX - oldScrollX; 
 } 
 if (preScrollX < 0) { 
  preScrollX = 0; 
  dx = preScrollX - oldScrollX; 
 } 
 mScroller.startScroll(mScroller.getFinalX(), mScroller.getFinalY(), dx, 0); 
 //  ,  startScroll       invalidate    ,  computeScroll()  ,     startScroll()   Scroller ,       ,           
 invalidate(); 
 */ 
 //     ACTION_MOVE       scrollTo  scrollBy     
 scrollBy(dx,0); 
 mLastX = x; 
 break; 
 case MotionEvent.ACTION_UP: 
 final VelocityTracker velocityTracker = mVelocityTracker; 
 velocityTracker.computeCurrentVelocity(1000); 
 int initVelocity = (int) velocityTracker.getXVelocity(); 
 if(initVelocity > mMaxVelocity && mCurrentPage > 0){//         ,           
  Log.d("TAG","----------------      --------------------"); 
  scrollToPage(mCurrentPage - 1); 
 }else if(initVelocity < -mMaxVelocity && mCurrentPage < (getChildCount() - 1)){//         ,           
  Log.d("TAG","----------------      --------------------"); 
  scrollToPage(mCurrentPage + 1); 
 }else{//         ,           
  Log.d("TAG","----------------     --------------------"); 
  slowScrollToPage(); 
 } 
 recycleVelocityTracker(); 
 break; 
 } 
 return true; 
 } 

 /** 
 *            ,         Page    、     
 */ 
 private void slowScrollToPage() { 
 //        
 int scrollX = getScrollX(); 
 int scrollY = getScrollY(); 
 //       Page      page         page   
 int whichPage = (getScrollX() + getWidth() / 2 ) / getWidth() ; 
 scrollToPage(whichPage); 
 } 

 /** 
 *         
 * @param indexPage 
 */ 
 private void scrollToPage(int indexPage) { 
 mCurrentPage = indexPage; 
 if(mCurrentPage > getChildCount() - 1){ 
 mCurrentPage = getChildCount() - 1; 
 } 
 //       Page         
 int dx = mCurrentPage * getWidth() - getScrollX(); 
 mScroller.startScroll(getScrollX(),0,dx,0,Math.abs(dx) * 2);//       Math.abs(dx) * 2 ms 
 //  ,  Scroller     invalidate 
 invalidate(); 
 } 

 @Override 
 public void computeScroll() { 
 Log.d("TAG", "---------computeScrollcomputeScrollcomputeScroll--------------"); 
 super.computeScroll(); 
 if(mScroller.computeScrollOffset()){ 
 scrollTo(mScroller.getCurrX(),mScroller.getCurrY()); 
 invalidate(); 
 } 
 } 

 private void recycleVelocityTracker() { 
 if (mVelocityTracker != null) { 
 mVelocityTracker.recycle(); 
 mVelocityTracker = null; 
 } 
 } 

 private void initVelocityTrackerIfNotExists() { 
 if(mVelocityTracker == null){ 
 mVelocityTracker = VelocityTracker.obtain(); 
 } 
 } 
} 
레이아웃 파일 은 다음 과 같 습 니 다:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical">

 <com.lusheep.viewtest.view.MyViewPager3
 android:layout_width="match_parent"
 android:layout_height="200dp"
 android:background="#999" >
 <ImageView
 android:layout_width="300dp"
 android:layout_height="match_parent"
 android:scaleType="fitXY"
 android:src="@drawable/test1" />

 <ImageView
 android:layout_width="300dp"
 android:layout_height="match_parent"
 android:scaleType="fitXY"
 android:src="@drawable/test2" />

 <ImageView
 android:layout_width="300dp"
 android:layout_height="match_parent"
 android:scaleType="fitXY"
 android:src="@drawable/test3" />

 <ImageView
 android:layout_width="300dp"
 android:layout_height="match_parent"
 android:scaleType="fitXY"
 android:src="@drawable/test4" />
 </com.lusheep.viewtest.view.MyViewPager3>
</LinearLayout>
다운로드
간단 한 요약:
(1)Scroller 류 는 손가락 을 들 어 올 린 후의 관성 미끄럼 기능 과 같은 고급 미끄럼 기능 을 실현 하 는 데 도움 을 줄 수 있다.사용 절 차 는 먼저 Scroller 류 의 startScroll()+invalidate()를 통 해 View 의 coptute Scroll()을 터치 하고,coptute Scroll()에서 Scroller 류 로 하여 금 최신 좌표 정 보 를 계산 하 게 하고,최신 좌표 오프셋 정 보 를 받 은 후에 도 View 의 scrollTo 를 호출 하여 미끄럼 을 실현 하도록 합 니 다.이 를 통 해 알 수 있 듯 이 Scroller 를 사용 하 는 전체 절 차 는 비교적 간단 하 다.관건 은 미끄럼 을 제어 하 는 논리 적 계산 이다.예 를 들 어 상기 예 에서 계산 한 것 이 언제 어느 페이지 로 미 끄 러 져 야 하 는 지...
(2)Android 뒤에 OverScroller 클래스 가 출시 되 었 고 OverScroller 는 전체 기능 에서 Scroller 와 유사 하 며 사용 도 같 습 니 다.OverScroller 클래스 는 Scroller 를 완전히 대체 할 수 있 습 니 다.Scroller 에 비해 OverScroller 는 주로 경계 로 미 끄 러 지 는 것 에 대한 제 어 를 추 가 했 습 니 다.예 를 들 어 리 턴 효 과 를 추가 하 는 등 기능 이 더욱 강 합 니 다.
이상 은 본 고의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.또한 저 희 를 많이 지지 해 주시 기 바 랍 니 다!

좋은 웹페이지 즐겨찾기