日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android中实现Launcher功能之四---滑屏初探 scrollTo 以及 scrollBy方法使用说明

發布時間:2025/3/14 Android 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android中实现Launcher功能之四---滑屏初探 scrollTo 以及 scrollBy方法使用说明 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?本文原創 ,轉載必須注明出處?:http://blog.csdn.net/qinjuning

???????????????????????????????????

?

????? ? ?今天給大家介紹下Android中滑屏功能的一個基本實現過程以及原理初探,最后給大家重點講解View視圖中scrollTo 與

?? scrollBy這兩個函數的區別 。

??

????????首先 ,我們必須明白在Android View視圖是沒有邊界的,Canvas是沒有邊界的,只不過我們通過繪制特定的View時對

???Canvas對象進行了一定的操作,例如 : translate(平移)、clipRect(剪切)等,以便達到我們的對該Canvas對象繪制的要求 ,

???我們可以將這種無邊界的視圖稱為“視圖坐標”-----它不受物理屏幕限制。通常我們所理解的一個Layout布局文件只是該視

???圖的顯示區域,超過了這個顯示區域將不能顯示到父視圖的區域中 ,對應的,我們可以將這種有邊界的視圖稱為“布局坐標

????------ 父視圖給子視圖分配的布局(layout)大小。而且, 一個視圖的在屏幕的起始坐標位于視圖坐標起始處,如下圖所示。

?

???????? 這么來說吧 ,世界本是無邊無界的,可是我們的眼睛我們的心約束了我們所看到的“世界” 。

?

??? ?? 如下所示:

?????????????

??????????????

????????????? 黑色框框表示該子視圖的布局坐標, 褐色框框表示該子視圖的視圖坐標--該坐標是無限的,超過了父視圖給子視圖

?????? 規定的區域后,不再顯示該超出內容。

?

??? ?? ? ?那么下面的問題就是:如何將我們的視圖的任意坐標能顯示到該視圖的中心坐標上呢? 由于該布局位置是只能顯示特定的

? 一塊視圖內容 ,因此我們需要通過scrollTo()或者scrollBy()方法將我們期望的視圖“滾動”至布局坐標上。

?

????? 在View.java中提供了了如下兩個變量以及相應的屬性方法去讀取滾動值 ,如下: View.java類中???

[java]?view plaincopyprint?
  • /**?
  • ?????*?The?offset,?in?pixels,?by?which?the?content?of?this?view?is?scrolled?
  • ?????*?horizontally.?
  • ?????*?{@hide}?
  • ?????*/??
  • ????protected?int?mScrollX;???//該視圖內容相當于視圖起始坐標的偏移量???,?X軸?方向??
  • ????/**?
  • ?????*?The?offset,?in?pixels,?by?which?the?content?of?this?view?is?scrolled?
  • ?????*?vertically.?
  • ?????*?{@hide}?
  • ?????*/??
  • ????protected?int?mScrollY;???//該視圖內容相當于視圖起始坐標的偏移量???,?Y軸方向??
  • ??
  • ????/**?
  • ?????*?Return?the?scrolled?left?position?of?this?view.?This?is?the?left?edge?of?
  • ?????*?the?displayed?part?of?your?view.?You?do?not?need?to?draw?any?pixels?
  • ?????*?farther?left,?since?those?are?outside?of?the?frame?of?your?view?on?
  • ?????*?screen.?
  • ?????*?
  • ?????*?@return?The?left?edge?of?the?displayed?part?of?your?view,?in?pixels.?
  • ?????*/??
  • ????public?final?int?getScrollX()?{??
  • ????????return?mScrollX;??
  • ????}??
  • ??
  • ????/**?
  • ?????*?Return?the?scrolled?top?position?of?this?view.?This?is?the?top?edge?of?
  • ?????*?the?displayed?part?of?your?view.?You?do?not?need?to?draw?any?pixels?above?
  • ?????*?it,?since?those?are?outside?of?the?frame?of?your?view?on?screen.?
  • ?????*?
  • ?????*?@return?The?top?edge?of?the?displayed?part?of?your?view,?in?pixels.?
  • ?????*/??
  • ????public?final?int?getScrollY()?{??
  • ????????return?mScrollY;??
  • ????}??

  • ?

    ??????注意,所謂的“by which the content of this view is scrolled”表示該偏移量只針對于該View中onDraw()方法里的

    ??具體內容實現,而不針對繪制背景圖片等 。具體原因可參考<Android中View繪制流程以及invalidate()等相關方法分析>

    ?

    ?????提示:下文中提到的當前視圖內容是在繪制在布局坐標處的內容。

    ?

    ?????public void?scrollTo(int x, int y)

    ????????????? 說明:在當前視圖內容偏移至(x , y)坐標處,即顯示(可視)區域位于(x , y)坐標處。

    ??????? 方法原型為: View.java類中

    [java]?view plaincopyprint?
  • /**?
  • ?*?Set?the?scrolled?position?of?your?view.?This?will?cause?a?call?to?
  • ?*?{@link?#onScrollChanged(int,?int,?int,?int)}?and?the?view?will?be?
  • ?*?invalidated.?
  • ?*?@param?x?the?x?position?to?scroll?to?
  • ?*?@param?y?the?y?position?to?scroll?to?
  • ?*/??
  • public?void?scrollTo(int?x,?int?y)?{??
  • ????//偏移位置發生了改變??
  • ????if?(mScrollX?!=?x?||?mScrollY?!=?y)?{??
  • ????????int?oldX?=?mScrollX;??
  • ????????int?oldY?=?mScrollY;??
  • ????????mScrollX?=?x;??//賦新值,保存當前便宜量??
  • ????????mScrollY?=?y;??
  • ????????//回調onScrollChanged方法??
  • ????????onScrollChanged(mScrollX,?mScrollY,?oldX,?oldY);??
  • ????????if?(!awakenScrollBars())?{??
  • ????????????invalidate();??//一般都引起重繪??
  • ????????}??
  • ????}??
  • }??
  • ?

    ?????public void?scrollBy(int x, int y)? ??

    ??????????? 說明:在當前視圖內容繼續偏移(x , y)個單位,顯示(可視)區域也跟著偏移(x,y)個單位。

    ??????? 方法原型為: View.java類中

    [java]?view plaincopyprint?
  • /**?
  • ???*?Move?the?scrolled?position?of?your?view.?This?will?cause?a?call?to?
  • ???*?{@link?#onScrollChanged(int,?int,?int,?int)}?and?the?view?will?be?
  • ???*?invalidated.?
  • ???*?@param?x?the?amount?of?pixels?to?scroll?by?horizontally?
  • ???*?@param?y?the?amount?of?pixels?to?scroll?by?vertically?
  • ???*/??
  • ??//?看出原因了吧?。。?mScrollX?與?mScrollY?代表我們當前偏移的位置?,?在當前位置繼續偏移(x?,y)個單位??
  • ??public?void?scrollBy(int?x,?int?y)?{??
  • ??????scrollTo(mScrollX?+?x,?mScrollY?+?y);??
  • ??}??

  • ????????

    ?????????????

    ?????? 第一個小Demo非常簡單 ,大家重點理解與掌握scrollTo() 與 scrollBy()函數的用法和區別。

    ?

    ????? ?第二個小Demo則有了Launcher的模樣,能夠左右切換屏幕 。實現功能如下: 采用了一個自定義ViewGroup,該ViewGroup

    ?? 對象包含了3個LinearLayout子視圖,并且以一定的布局坐標(由layout()方法指定)顯示在ViewGroup上。 接下來,即可調用該

    ???ViewGroup對象的scrollTo或者scrollBy()方法切換指定視圖內容了,即切換屏幕。 呵呵 ,挺好玩的吧 。

    ?

    ?????? 如果對View繪制流程不懂的,可以參考我的這篇博客<Android中View繪制流程以及invalidate()等相關方法分析> 。

    ?????? 截圖如下:

    ????????????????????????????

    ?????? 自定義ViewGroup如下:

    ?

    [java]?view plaincopyprint?
  • //自定義ViewGroup?,?包含了三個LinearLayout控件,存放在不同的布局位置,通過scrollBy或者scrollTo方法切換??
  • public?class?MultiViewGroup?extends?ViewGroup?{??
  • ??
  • ????private?Context?mContext;??
  • ??
  • ????private?static?String?TAG?=?"MultiViewGroup";??
  • ??
  • ????public?MultiViewGroup(Context?context)?{??
  • ????????super(context);??
  • ????????mContext?=?context;??
  • ????????init();??
  • ????}??
  • ??
  • ????public?MultiViewGroup(Context?context,?AttributeSet?attrs)?{??
  • ????????super(context,?attrs);??
  • ????????mContext?=?context;??
  • ????????init();??
  • ????}??
  • ??
  • ????private?void?init()?{??
  • ????????//?初始化3個?LinearLayout控件??
  • ????????LinearLayout?oneLL?=?new?LinearLayout(mContext);??
  • ????????oneLL.setBackgroundColor(Color.RED);??
  • ????????addView(oneLL);??
  • ??????????
  • ????????LinearLayout?twoLL?=?new?LinearLayout(mContext);??
  • ????????twoLL.setBackgroundColor(Color.YELLOW);??
  • ????????addView(twoLL);??
  • ??????????
  • ????????LinearLayout?threeLL?=?new?LinearLayout(mContext);??
  • ????????threeLL.setBackgroundColor(Color.BLUE);??
  • ????????addView(threeLL);??
  • ????}??
  • ??
  • ????//?measure過程??
  • ????@Override??
  • ????protected?void?onMeasure(int?widthMeasureSpec,?int?heightMeasureSpec)?{??
  • ??
  • ????????Log.i(TAG,?"---?start?onMeasure?--");??
  • ??
  • ????????//?設置該ViewGroup的大小??
  • ????????int?width?=?MeasureSpec.getSize(widthMeasureSpec);??
  • ????????int?height?=?MeasureSpec.getSize(heightMeasureSpec);??
  • ????????setMeasuredDimension(width,?height);??
  • ??
  • ????????int?childCount?=?getChildCount();??
  • ????????Log.i(TAG,?"---?onMeasure?childCount?is?-->"?+?childCount);??
  • ????????for?(int?i?=?0;?i?<?childCount;?i++)?{??
  • ????????????View?child?=?getChildAt(i);??
  • ????????????//?設置每個子視圖的大小?,?即全屏??
  • ????????????child.measure(MultiScreenActivity.screenWidth,?MultiScreenActivity.scrrenHeight);??
  • ????????}??
  • ????}??
  • ??
  • ????//?layout過程??
  • ????@Override??
  • ????protected?void?onLayout(boolean?changed,?int?l,?int?t,?int?r,?int?b)?{??
  • ????????//?TODO?Auto-generated?method?stub??
  • ????????Log.i(TAG,?"---?start?onLayout?--");??
  • ????????int?startLeft?=?0;?//?每個子視圖的起始布局坐標??
  • ????????int?startTop?=?10;?//?間距設置為10px?相當于?android:marginTop=?"10px"??
  • ????????int?childCount?=?getChildCount();??
  • ????????Log.i(TAG,?"---?onLayout?childCount?is?-->"?+?childCount);??
  • ????????for?(int?i?=?0;?i?<?childCount;?i++)?{??
  • ????????????View?child?=?getChildAt(i);??
  • ????????????child.layout(startLeft,?startTop,???
  • ????????????????????startLeft?+?MultiScreenActivity.screenWidth,???
  • ????????????????????startTop?+?MultiScreenActivity.scrrenHeight);??
  • ????????????startLeft?=?startLeft?+?MultiScreenActivity.screenWidth?;?//校準每個子View的起始布局位置??
  • ????????????//三個子視圖的在屏幕中的分布如下?[0?,?320]?/?[320,640]?/?[640,960]??
  • ????????}??
  • ????}??
  • ??
  • }??

  • ?

    ????????? PS? :大家可以分別給這幾個LinearLayout試著添加幾個子View,例如TextView, Button等。

    ?

    ????? ? 至于Launcher上滑屏功能的實現,我嘗試著去掌握,可能天資愚鈍吧,對Scoller類很是感冒,現今還沒有掌握好,不過在此

    ?? 給大家推薦幾個不錯的學習資源 。?以后有需要的話,還是采用拿來主義吧。 囧

    ?

    ??????? 1、 Scoller類介紹:android 中文 api (64) —— Scroller

    ??????? 2、相關資源匯總:http://blog.csdn.net/dellheng/article/details/7164275?

    ??????? 3,launcher修改--左右滑動屏幕切換源碼追蹤

    ?

    ???????? 示例源代碼位于:?http://download.csdn.net/detail/qinjuning/4054840

    ?

    ?

    ?

    ?

    ? ? ? ? ??? 補充(收回上面一段話,- -):關于如何實現觸摸滑屏---- 仿Launcher滑屏以及Scoller類的使用,請參閱我的

    ? ?另外一篇博文:??Android中滑屏實現----手把手教你如何實現觸摸滑屏以及Scroller類詳解》

    轉載于:https://www.cnblogs.com/MMLoveMeMM/articles/4212240.html

    總結

    以上是生活随笔為你收集整理的Android中实现Launcher功能之四---滑屏初探 scrollTo 以及 scrollBy方法使用说明的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。