안 드 로 이 드 스크롤 러 비밀 폭로
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 는 주로 경계 로 미 끄 러 지 는 것 에 대한 제 어 를 추 가 했 습 니 다.예 를 들 어 리 턴 효 과 를 추가 하 는 등 기능 이 더욱 강 합 니 다.
이상 은 본 고의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.또한 저 희 를 많이 지지 해 주시 기 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.