天天看點

android HorizontalScrollView講解

前言

  本章内容是android.widget.HorizontalScrollView,譯為"橫向滾動條",版本為Android 2.3 r1,翻譯來自"Tina",感謝"Tina"為大家帶來精彩的翻譯稿 !期待你加入Android API 中文的翻譯,聯系我[email protected]。

聲明

  歡迎轉載,但請保留文章原始出處:)

    JavaEye社群:http://www.iteye.com/

    Android中文翻譯組:http://goo.gl/6vJQl

正文

  一、結構

public class HorizontalScrollView extends FrameLayout

java.lang.Object

android.view.View

         android.view.ViewGroup

                   android.widget.FrameLayout

                            android.widget.HorizontalScrollView

  二、概述

    

android HorizontalScrollView講解

  

  用于布局的容器,可以放置讓使用者使用滾動條檢視的視圖層次結構,允許視圖結構比手機的螢幕大。HorizontalScrollView是一種

FrameLayout

(架構布局),其子項被滾動檢視時是整體移動的,并且子項本身可以是一個有複雜層次結構的布局管理器。一個常見的應用是子項在水準方向中,使用者可以滾動顯示頂層水準排列的子項(items)。

  HorizontalScrollView不可以和ListView同時用,因為ListView有自己的滾動條設定。最重要的是,如果在需要顯示很大的list的情況下,兩者同時用則會使ListView在一些重要的優化上失效。出現這種失效的原因在于,HorizontalScrollView會強迫ListView用HorizontalScrollView本身提供的空間容器(infinite container)來顯示完整的清單。

   類似的情況,

TextView

也有自己的滾動條,是以不需要ScrollView。但這兩者是可以同時使用的,使用的結果會是在一個更大的容器裡顯示文本視圖。

HorizontalScrollView 隻支援水準方向的滾動顯示。

  三、公共方法

public void addView (View child)

添加一個子視圖。若這個子視圖沒有被設定布局參數,則使用ViewGroup的預設參數。

參數

child         要添加的子視圖

public void addView (View child, int index)

添加一個子視圖。若這個子視圖沒有被設定布局參數,則使用ViewGroup的預設參數。

參數

child         要添加的子視圖

index       子視圖要加入的位置

public void addView (View child, int index, ViewGroup.LayoutParams params)

添加一個帶有指定布局參數的子視圖。

參數

child         要添加的子視圖

index       子視圖要加入的位置

params  子視圖的布局參數

public void addView (View child, ViewGroup.LayoutParams params)

添加一個帶有指定布局參數的子視圖。

參數

child         要添加的子視圖

params  子視圖的布局參數

public boolean arrowScroll (int direction)

響應點選左右箭頭時對滾動條的處理。

參數

direction          The direction corresponding to the arrow key that was pressed箭頭按鍵所表示的方向

傳回值

             若此事件成功完成,則傳回true;否則傳回false。

public void computeScroll ()

被父視圖調用,用于必要時候對其子視圖的值(mScrollX和mScrollY)進行更新。典型的情況如:父視圖中某個子視圖使用一個

Scroller

對象來實作滾動操作,會使得此方法被調用。

public boolean dispatchKeyEvent (KeyEvent event)

按照可以獲得焦點的順序(從視圖樹的頂端到目前獲得焦點的視圖),分派一個按鍵事件給下一個視圖。若此視圖為焦點視圖,事件将會分派給它自己。否則它将按照順序,分派給下一個節點。此方法同時觸動所有按鍵監聽器。

參數

event       被分派的事件.

傳回值

             若事件被處理,則傳回true;否則為false

public void draw (Canvas canvas)

手動繪制視圖(及其子視圖)到指定的畫布(Canvas)。這個視圖必須在調用這個函數之前做好了整體布局。。當實作一個視圖時,不需要繼承這個方法;相反,你應該實作

onDraw(Canvas)

方法。

參數

canvas    繪制視圖的畫布

public boolean executeKeyEvent (KeyEvent event)

需要通過按鍵事件來實作滾動操作時,可以調用此方法。效果類似于由視圖樹型結構分派事件。

參數

event       需要執行的事件

傳回值

             若事件被處理,則傳回true;否則為false

public void fling (int velocityX)

滾動視圖的fling手勢。

參數

velocityX          方向的初始速率。正值表示手指/光标向螢幕右邊滑動,而内容相對向左滾動。

public boolean fullScroll (int direction)

處理按下"home/end"快捷鍵之後的滾動響應。此方法會将視圖移左或移右,同時将焦點賦予移動後可視的最左或最右的元件。如果沒有任何元件适合得到焦點,此scrollview将收回焦點。

參數

direction          滾動方向:FOCUS_LEFT表示向視圖的左邊移動,FOCUS_RIGHT表示向視圖的右邊移動

傳回值

             若此方法消耗(consumed)了按鍵事件則傳回true,否則傳回false。

public int getMaxScrollAmount ()

傳回值

             按左右箭頭時視圖可以滾動的最大值。

public boolean isFillViewport ()

表示此ScrollView的内容是否被拉伸以适應視口(viewport)的大小。

傳回值

             若内容填充了視口則傳回true,否則傳回false。

public boolean isSmoothScrollingEnabled ()

傳回值

             按箭頭方向滾動時,是否顯示滾動的平滑效果。

public boolean onInterceptTouchEvent (MotionEvent ev)

使用此方法可以攔截所有觸摸屏動作引發的事件。這意味着你可以監視分派給子項的事件,并且可以拿到任何目前手勢的所有權。

使用此方法需謹慎。因為它與View.onTouchEvent(MotionEvent)有相當複雜的互動影響。這兩者都必須同時正确地實作。事件将按以下順序來被方法接收:

   1. 接收到down事件

   2. 事件将被視圖組的一個子視圖處理,或者被傳遞給自己的onTouchEvent()方法處理;這意味着你必須實作onTouchEvent(),并且傳回true,這樣才可以接着接受到其他的手勢(而不是尋求一個父視圖來處理它)。onTouchEvent()傳回true後,你将不再接受到onInterceptTouchEvent()的任何事件,同時所有對觸摸動作的處理必須像往常一樣在onTouchEvent()中進行。

   3. 如果傳回false,則接下來的每個事件(所有的up事件,包含最後一個up)将會首先被傳遞到這裡,然後到目标對象view的onTouchEvent()。

   4. 如果傳回ture,你将不會接收到以下任何事件:目标view将會接收到相同的事件,但是帶着ACTION_CANCEL的動作。所有在此之後的事件将會被傳遞到你的onTouchEvent()方法中,并且不再在這裡出現。

參數

ev    沿着樹型結構往下分派的動作事件

         傳回值

             若将動作事件從子視圖中截獲并通過onTouchEvent()将他們分派給目前ViewGroup,則傳回true。目前目标将收到一個ACTION_CANCEL事件,并且不再會有其他消息被傳遞到這裡。

public boolean onTouchEvent (MotionEvent ev)

此方法用于處理觸摸屏的動作事件。

參數

ev    動作事件

         傳回值

             若事件被成功處理,則傳回true;否則傳回false

public boolean pageScroll (int direction)

處理按下"page up/down"快捷鍵之後的滾動響應。此方法會将視圖往左或往右滾動一個頁面的距離,同時将焦點賦予移動後可視的最左或最右的元件。如果沒有任何元件适合得到焦點,此scrollview将收回焦點。

參數

direction          滾動方向:FOCUS_LEFT表示向視圖的左邊移動一個頁面FOCUS_RIGHT表示向視圖的右邊移動一個頁面

      傳回值

            若此方法處理(consumed)了按鍵事件則傳回true,否則傳回false。

public void requestChildFocus (View child, View focused)

當父視圖的一個子視圖要獲得焦點時,調用此方法。

參數

child         要獲得焦點的子視圖。此視圖将包含焦點視圖,但其本身不必為焦點。

focused  事實上擁有焦點的子視圖的下層視圖。

public boolean requestChildRectangleOnScreen (View child, Rect rectangle, boolean immediate)

當組裡的某個子視圖需要被定位在螢幕的某個矩形範圍時,調用此方法。重載此方法的ViewGroup可确認以下幾點:

    * 子項目将是組裡的直系子項

    * 矩形将在子項目的坐标體系中

重載此方法的ViewGroup應該支援以下幾點:

    * 若矩形已經是可見的,則沒有東西會改變

    * 為使矩形區域全部可見,視圖将可以被滾動顯示

參數

child         送出請求的子視圖

rectangle         子項目坐标系内的矩形,即此子項目希望在螢幕上的定位

immediate      設為true,則禁止動畫和平滑移動滾動條

      傳回值

            進行了滾動操作的這個組(group),是否處理此操作

public void requestLayout ()

當出現使視圖布局失效的改變時,調用此方法。它将規劃一個視圖樹的布局路徑。

public void scrollTo (int x, int y)

設定視圖滾動後的位置。這将引起onScrollChanged(int,int,int,int)的調用,同時使此視圖失效。

此版本同時将滾動鎖定于子視圖的範圍。

參數

x      要滾動到的x位置

y      要滾動到的y位置

public void setFillViewport (boolean fillViewport)

設定此滾動視圖是否将内容寬度拉伸來适應視口(viewport)。

參數

fillViewport     設定為true表示将拉伸内容寬度;否則會設定為false。

public void setOverScrollMode (int mode)

為視圖設定over-scroll模式。有效的over-scroll模式有

OVER_SCROLL_ALWAYS

(預設值),

OVER_SCROLL_IF_CONTENT_SCROLLS

(隻允許當視圖内容大過容器時,進行over-scrolling)和

OVER_SCROLL_NEVER

。隻有當視圖可以滾動時,此項設定才起作用。

參數

mode       視圖的新over-scroll模式值

public void setSmoothScrollingEnabled (boolean smoothScrollingEnabled)

設定是否呈現按下箭頭後的平滑滾動效果(動畫效果)。

參數

smoothScrollingEnabled          設定是否呈現平滑滾動效果

public final void smoothScrollBy (int dx, int dy)

類似

scrollBy(int, int)

,但是呈現平滑滾動,而非瞬間滾動(譯者注:瞬間滾動——指不顯示滾動過程,直接顯示滾動後達到的位置)。

參數

dx    要滾動的X軸像素內插補點(譯者注:橫向像素內插補點)

dy    要滾動的Y軸像素內插補點(譯者注:縱向像素內插補點)

public final void smoothScrollTo (int x, int y)

類似

scrollTo(int, int)

,但是呈現平滑滾動,而不是瞬間滾動。

參數

x      滾動要到達位置的X軸值

y      滾動要到達位置的 Y 軸值  

  四、受保護方法

      protected int computeHorizontalScrollOffset ()

計算水準方向滾動條的滑塊的偏移值。此值用來計算滾動時滑塊的位置。

偏移值的範圍可以以任何機關表示,但必須與computeHorizontalScrollRange()和computeHorizontalScrollExtent()的機關一緻。

預設的偏移值為視圖滾動的偏移內插補點。

       傳回值

             滾動條滑塊在水準方向上的偏移值

protected int computeHorizontalScrollRange ()

scroll view 的可滾動水準範圍是所有子視圖的寬度總合。

        傳回值

              水準滾動條表示的全部水準滾動範圍

protected int computeScrollDeltaToGetChildRectOnScreen (Rect rect)

計算X方向滾動的總合,以便在螢幕上顯示子視圖的完整矩形(或者,若矩形寬度超過螢幕寬度,至少要填滿第一個螢幕大小)。

參數

rect          矩形

            傳回值

              滾動內插補點

protected float getLeftFadingEdgeStrength ()

傳回左漸變邊緣的強度或密集度。強度的值介于0.0(無漸變)到1.0(全漸變)之間。預設實作隻傳回0.0或1.0,而不傳回中間值。子類必須重載次方法來給滾動動作提供更平滑的漸變過程。

        傳回值

              左漸變的強度,即介于0.0f和1.0f之間的浮點值

protected float getRightFadingEdgeStrength ()

傳回右漸變邊緣的強度或密集度。強度的值介于0.0(無漸變)到1.0(全漸變)之間。預設實作隻傳回0.0或1.0,而不傳回中間值。子類必須重載此方法來給滾動動作提供更平滑的漸變過程。

                   傳回值

                       右漸變的強度,即介于0.0f和1.0f之間的浮點值

protected void measureChild (View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec)

要求子視圖測量自身,需要将視圖的MeasureSpec和其附加内容同時考慮在内。getChildMeasureSpec在其中承擔了重要角色,它計算出MeasureSpec,并傳遞給子視圖。

參數

child         要測量的子視圖

parentWidthMeasureSpec     此視圖的寬度要求

parentHeightMeasureSpec    此視圖的高度要求

protected void measureChildWithMargins (View child, int parentWidthMeasureSpec, int widthUsed, int parentHeightMeasureSpec, int heightUsed)

要求子視圖測量自身,需要将視圖的MeasureSpec、附加内容和邊緣部分同時考慮在内。子項必須有MarginLayoutParams(邊緣布局參數)。getChildMeasureSpec在其中承擔了重要角色,它計算出MeasureSpec,并傳遞給子視圖。

參數

child         要測量的子視圖

parentWidthMeasureSpec     此視圖的寬度要求

widthUsed      被父視圖(也可能是其他子視圖)占用的橫向額外空間

parentHeightMeasureSpec    此視圖的高度要求

heightUsed     被父視圖(也可能是其他子視圖)占用的縱向額外空間

protected void onLayout (boolean changed, int l, int t, int r, int b)

當此視圖要給每個子視圖指派大小和位置時,layout會調用此方法。子項的派生類應當重載此方法,并且調用各個子項的layout。

參數

changed           此視圖有新的大小或位置

l       左邊界位置,相對于父視圖

t      上邊界位置,相對于父視圖

r      右邊界位置,相對于父視圖

b      下邊界位置,相對于父視圖

protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)

調用此方法來确定本身和所包含内容的大小(寬度和高度)。此方法被measure(int,int)喚起,而且必須被子類重載以得到所包含内容的确切大小。

         注意:當重載此方法時,必須調用setMeasureDimension(int,int)來儲存View的大小。如果沒有做到,将會引發一個measure(int,int)抛出的IllegalStateException(非法狀态錯誤)。超類onMeasure(int,int)可以被調用。

         編寫基類的确認大小的方法,預設情況下是根據其背景大小來确認,除非MeasureSepc允許有更大的高度或寬度。子類必須重載onMeasure(int,int)以得到對其内容大小的更準确的測量。

         若此方法被重載,它的子類需要確定其高度和寬度至少達到View所規定的最小值(可通過getSuggestedMinimumHeight()和getSuggestedMinimumWidth()得到)。

參數

widthMeasureSpec         受上一層大小影響下的對水準空間的要求。可參看View.MeasureSpec。

heightMeasureSpec        受上一層大小影響下的對垂直空間的要求。可參看View.MeasureSpec。

protected void onOverScrolled (int scrollX, int scrollY, boolean clampedX, boolean clampedY)

overScrollBy(int, int, int, int, int, int, int, int, boolean)

調用,來對一個over-scroll操作的結果進行響應。

參數

scrollX     新的X滾動像素值

scrollY     新的Y滾動像素值

clampedX        當scrollX被over-scroll的邊界限制時,值為true

clampedY        當scrollY被over-scroll的邊界限制時,值為true

protected boolean onRequestFocusInDescendants (int direction, Rect previouslyFocusedRect)

當在某個scroll view的子視圖中尋找焦點時,需要小心不能讓螢幕之外的元件得到焦點。這比預設ViewGroup的實作代價更高,否則此行為被設為預設。

參數

direction          值可以為FOCUS_UP,FOCUS_DOWN,FOCUS_LEFT或 FOCUS_RIGHT

previouslyFocusedRect 能夠給出一個較好的提示的矩形(目前視圖的坐标系統)表示焦點從哪裡得來。如果沒有提示則為null。

傳回值

             是否取到了焦點。

protected void onSizeChanged (int w, int h, int oldw, int oldh)

當View的大小改變時此方法被調用。如果View是剛剛被加入,則視之前的值為0。

參數

w     View的目前寬度

h      View的目前高度

oldw        View大小改變之前的寬度

oldh         View大小改變之前的高度

  五、補充

    文章精選

      Android HorizontalScrollview Example

結束

  這是"Tina"翻譯的第二篇較長的譯稿,上一篇為ListView,再次感謝她!!

  由于移動裝置實體顯示空間一般有限,不可能一次性的把所有要顯示的内容都顯示在螢幕上。是以各大平台一般會提供一些可滾動的視圖來向使用者展示資料。Android平台架構中為我們提供了諸如ListView、GirdView、ScrollView等滾動視圖控件,這幾個視圖控件也是我們平常使用最多的。我下面介紹一下HorizontalScrollView的使用和需要注意的點

     HorizontalScrollView是一個 FrameLayout  , 這意味着你隻能在它下面放置一個子控件,這個子控件可以包含很多資料内容。有可能這個子控件本身就是一個布局控件,可以包含非常多的其他用來展示資料的控件。這個布局控件一般使用的是一個水準布局的

LinearLayout

  。TextView也是一個可滾動的視圖控件,是以一般不需要HorizontalScrollView

     下面介紹一個HorizontalScrollView中包含許多圖檔,并且可以滾動浏覽的示例 [java] view plain copy

  1.  @Override  
  2.  protected void onCreate(Bundle savedInstanceState) {  
  3.        super.onCreate(savedInstanceState);  
  4.       setContentView(R.layout. activity_main);  
  5.        mLinearLayout = (LinearLayout) findViewById(R.id.mygallery);  
  6.       File externalDir = Environment. getExternalStorageDirectory();  
  7.       String photosPath = externalDir.getAbsolutePath() + "/test/";  
  8.       File photosFile = new File(photosPath);  
  9.        for (File photoFile : photosFile.listFiles()) {  
  10.               mLinearLayout.addView(getImageView(photoFile.getAbsolutePath()));  
  11.       }  
  12. }  
  13.  private View getImageView(String absolutePath) {  
  14.       Bitmap bitmap = decodeBitmapFromFile(absolutePath, 200, 200);  
  15.     LinearLayout layout = new LinearLayout(getApplicationContext());  
  16.     layout.setLayoutParams( new LayoutParams(250, 250));  
  17.     layout.setGravity(Gravity. CENTER);  
  18.       ImageView imageView = new ImageView(this);  
  19.       imageView.setLayoutParams( new LayoutParams(200,200));  
  20.       imageView.setScaleType(ImageView.ScaleType. CENTER_CROP);  
  21.       imageView.setImageBitmap(bitmap);  
  22.       layout.addView(imageView);  
  23.        return layout;  
  24. }  
  25.  private Bitmap decodeBitmapFromFile(String absolutePath, int reqWidth, int reqHeight) {  
  26.     Bitmap bm = null;  
  27.      // First decode with inJustDecodeBounds=true to check dimensions  
  28.      final BitmapFactory.Options options = new BitmapFactory.Options();  
  29.      options. inJustDecodeBounds = true ;  
  30.      BitmapFactory. decodeFile(absolutePath, options);  
  31.      // Calculate inSampleSize  
  32.      options. inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);  
  33.      // Decode bitmap with inSampleSize set  
  34.      options. inJustDecodeBounds = false ;  
  35.      bm = BitmapFactory. decodeFile(absolutePath, options);  
  36.      return bm;   
  37. }  
  38.  private int calculateInSampleSize(Options options, int reqWidth,  
  39.               int reqHeight) {  
  40.      // Raw height and width of image  
  41.      final int height = options.outHeight;  
  42.      final int width = options.outWidth;  
  43.      int inSampleSize = 1;  
  44.      if (height > reqHeight || width > reqWidth) {  
  45.       if (width > height) {  
  46.        inSampleSize = Math. round((float)height / ( float)reqHeight);    
  47.       } else {  
  48.        inSampleSize = Math. round((float)width / ( float)reqWidth);    
  49.       }    
  50.      }  
  51.      return inSampleSize;   
  52. }  

     要顯示的圖檔放在外置SDCard中test目錄下,上面的示例程式隻是顯示了一張張大圖檔的縮略版本,對這方面不懂的可以參看http://blog.csdn.net/tibib/article/details/8726486       HorizontalScrollView還可以設定滾動到一個指定的位置(x,0),它的子控件也會跟随着滾動。 [java] view plain copy

  1. new Handler().postDelayed(new Runnable() {  
  2.     @Override  
  3.     public void run() {  
  4.         // 水準直接滾動800px,如果想效果更平滑可以使用smoothScrollTo(int x, int y)  
  5.         hsv.scrollTo(800, 0);  
  6.     }  
  7. }, 2000);