Android墨跡3.0特性介紹效果實現——做一個滾動的Layout

來源:互聯網
上載者:User

墨跡天氣新版的開機介紹很漂亮,上下滾動翻頁,翻頁結束後元素會有動畫效果,分析一下動畫元素都是基本的Animation,沒有用到最新的屬性動畫;上下翻頁滾動的控制項android沒有提供,只有橫向的Viewpager,這裡有一種實現->點擊開啟連結,用到了開源的控制項ViewPager-Android,我們這裡試著手動實現一個上下滾動的翻頁控制項。

前期準備

首先我們用apktool把墨跡天氣的安裝包解壓出來,取出其中的圖片資源和布局檔案,一共4個布局


翻頁控制項實現

要實現自訂布局,需要繼承ViewGroup,然後實現onMeasure、onLayout方法<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+PC9wPgo8cHJlIGNsYXNzPQ=="brush:java;">@Overrideprotected void onLayout(boolean changed, int l, int t, int r, int b) {int count = getChildCount();int height = getMeasuredHeight();int top = 0;for (int i = 0; i < count; ++i) {View childView = getChildAt(i);if (childView.getVisibility() != View.GONE) {childView.layout(l, top, r, top + height);top += height;}}mTotalHeight = height * (count - 1);mTolerance = height / 2;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int count = getChildCount();for (int i = 0; i < count; ++i) {View childView = getChildAt(i);measureChild(childView, widthMeasureSpec, heightMeasureSpec);}}
這裡在onLayout方法中將頁面排下來,每頁內容都充滿控制項,垂直排列。

這時候在如果在activity中將View inflate出來再通過addview添加到控制項中就會看到第一頁的內容,但此時還不能滑動。下面我們就來實現上下滑動翻頁。

要響應控制項上的手勢操作需要實現onTouchEvent方法:

@Overridepublic boolean onTouchEvent(MotionEvent event) {if (mVelocityTracker == null) {mVelocityTracker = VelocityTracker.obtain();}mVelocityTracker.addMovement(event);switch (event.getAction()) {case MotionEvent.ACTION_DOWN:if (!mScroller.isFinished()) {mScroller.abortAnimation();}mLastY = (int) event.getY();mStartYPosition = getScrollY();break;case MotionEvent.ACTION_MOVE:int y = (int) event.getY();int distance = mLastY - y;int scrollY = getScrollY();// 邊界檢查if (distance < 0 && scrollY + distance < 0) {distance = 0 - scrollY;} else if (distance > 0 && scrollY + distance > mTotalHeight) {distance = mTotalHeight - scrollY;}scrollBy(0, distance);mLastY = y;break;case MotionEvent.ACTION_UP:mEndYPosition = getScrollY();int posDiff = mEndYPosition - mStartYPosition;mVelocityTracker.computeCurrentVelocity(1000);int velocityY = (int) mVelocityTracker.getYVelocity();mVelocityTracker.recycle();mVelocityTracker = null;if (Math.abs(velocityY) >= 600 || Math.abs(posDiff) > mTolerance) {int dis = 0;if (posDiff > 0) {dis = getMeasuredHeight() - posDiff;} else if (posDiff < 0) {dis = -(getMeasuredHeight() + posDiff);}mScroller.startScroll(0, 0, 0, dis);} else {mScroller.startScroll(0, 0, 0, -posDiff);}postInvalidate();break;default:break;}return true;}

上面的這些操作包括了滾動、邊界檢查(避免滑出邊界)和完成翻頁的功能,最開始其實是這樣的

@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mLastY = (int) event.getY();break;case MotionEvent.ACTION_MOVE:int y = (int) event.getY();int distance = mLastY - y;scrollBy(0, distance);mLastY = y;break;case MotionEvent.ACTION_UP:break;default:break;}return true;}

頁面可以隨著手指上下滾動,但是會超出邊界,再添加上邊界檢查,就是修改一下ACTION_MOVE,

case MotionEvent.ACTION_MOVE:int y = (int) event.getY();int distance = mLastY - y;int scrollY = getScrollY();// 邊界檢查if (distance < 0 && scrollY + distance < 0) {distance = 0 - scrollY;} else if (distance > 0 && scrollY + distance > mTotalHeight) {distance = mTotalHeight - scrollY;}scrollBy(0, distance);mLastY = y;break;

這時候再滾動的時候就會發現到達邊界的時候就無法再滑動了,下面再添加滑動半屏後自動完成翻頁的功能,就是最上面的那個完整的代碼,裡面用到了scroller,在抬起手指的時候計算滾動剩餘距離,然後開始滾動,scroller只負責完成滾動過程位置的計算,真正控制頁面的是在computeScroll()方法裡:

@Overridepublic void computeScroll() {if (mScroller.computeScrollOffset()) {int scroll = mScroller.getCurrY();if (scroll > 0 && mEndYPosition + scroll > mTotalHeight) {scroll = mTotalHeight - mEndYPosition;} else if (scroll < 0 && mEndYPosition + scroll < 0) {scroll = -mEndYPosition;}scrollTo(0, mEndYPosition + scroll);mIsScrolling = true;postInvalidate();} else if (mIsScrolling) {if (mPageScrollListener != null) {int position = getScrollY() / getMeasuredHeight();if (position != mCurrentPage) {mCurrentPage = position;mPageScrollListener.onPageChanged(mCurrentPage);}}mIsScrolling = false;}}

每次頁面重繪都會調用computeScroll方法,然後通過scroller得到此時的滾動值,再次重繪,直到滾動結束,這裡也做了下邊界檢測,防止滾過頭了。

滾動結束後要通知控制項的使用者翻頁已完成,所以定義一個翻頁完成的介面

public void setOnPageScrollListener(OnPageScrollListener listener) {mPageScrollListener = listener;}public interface OnPageScrollListener {public void onPageChanged(int position);}

在computeScroll()中發現翻頁完成了就調用這個介面。

剩下的就是在activity中載入動畫了,每當翻頁結束就播放相應頁面的動畫並清除上一頁的動畫效果

class MyPageScrollListener implements OnPageScrollListener {@Overridepublic void onPageChanged(int position) {switch (position) {case 0:layout1AnimStart();break;case 1:layout2AnimStart();break;case 2:layout3AnimStart();break;case 3:layout4AnimStart();break;}}}

示範效果


代碼在這裡->http://download.csdn.net/detail/xu_fu/7185403

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.