View入門

來源:互聯網
上載者:User

標籤:

View概述

        對於一個view,他應該有兩個位置:一個是顯示位置(即我們人眼看到的位置),一個是點擊位置(即接收使用者點擊事件的位置)。

        在初始化完成後,兩個位置是重合的,因此“所見即所點”。但,當調用了scrollTo(),scrollBy()或者tweens動畫後,所見已經不和所點重合:所見位置發現變化,但所點還在原地。這也是屬性動畫和tweens動畫的區別,前者仍舊保持了所見即所點。

位置

        mLeft,mTop,mBottom和mRight:分別表示原始的左上方的x,y座標,右下角的x,y座標。它們都是相對於父組件而言的。如果控制項的左上方與父控制項的左上方重合,那麼mLeft,mTop都是0。可以通過getLeft(),getRight(),getTop()和getBottom()擷取相應的值。

        x,y,translationX和translationY。x,y分別表示View相對於其父控制項的當前的左上方座標,tranlationX和translationY為View在x,y軸上移動的距離。x = mLeft+translationX;y = mTop + translationY。

        在移動時,mLeft,mRight,mBottom與mTop是不變的,變化的只有x,y,translationX和translationY。

        mScrollX與mScrollY:表示顯示地區一共移動的位移,它跟mLeft以及translationX等值無關。mScrollY表示點擊地區的上邊座標減內容地區的上邊座標。由於scrollTo/scrollBy兩個方法只改變內容地區,而點擊地區並沒有變化。所以scrollBy(100,0)時,意味著內容地區的左邊緣要比現在的左邊緣少100個像素,因此映像往左移(使用者看到的永遠只是內容地區,而不是點擊地區)。

        可以將View的座標分為三類:第一類mLeft等四個屬性,表示View的原始座標,一旦顯示之後不可修改;第二類,在原始座標基礎上進行移動得到的新座標,它並不能影響原始座標,但可以改變當前位置;第三類,內容地區的座標,即不能改變原始座標也不能改變新座標,只是修改內容地區的座標。

setLeft()與LayoutParams.leftMargin的區別

        兩者都可以改變mLeft的值:即改變子View在父View中的初始位置。但setLeft()只是修改了mLeft的值,不會影響其他屬性mRight,mTop和mBottom的值。並且不會請求父組件重新測量,布局。

        但後者會同時修改mLeft,mRight等四個屬性的值,並會引起重新測量和布局。

        對於兩者來說,它們都會引起點擊地區的改變,只不過前者不影響mScrollX與mScrollY的值,後者卻會影響。通過LayoutParams進行修改,相當於對該控制項進行重建,mScrollX與mScrollY會被初始化為0。

移動

        根據View的三類座標,對View進行移動也有三種方法。

第一種,改變內容地區。有兩種方式:

        1,通過scrollTo()/scrollBy()

        2,通過補間動畫。其實質也是通過scrollTo()/scrollBy()。

第二種:改變點擊地區。有兩種方式:

        1,改變mLeft,x,y,translationX和translationY等屬性的值。

        2,使用屬性動畫。其實質仍舊是修改上述四個屬性的值。

第三種:改變初始位置。只有一種方式:

        使用LayoutParams,並修改其中的leftMargin,topMargin等幾個跟margin相關的值。

比較

        第一種方式並沒有修改點擊地區,所以如果要移動的View有點擊事件的話,需要單獨進行處理。後兩種不需要。

        如果想移動View在父View中的位置,第一種方法中沒辦法使用scrollTo/scrollBy,但可以使用動畫。

常用方法

        getTop(),getLeft(),getBottom()與getRight()擷取的該view在父組件中的相對位置。顯示位置改變後,並不會影響該值。例如ScrollView不斷滑動時,getScrollY()的值會不斷變化,但getTop()的值是固定的。在ScrollView中,即使在當前該view還沒有顯示出來,它一樣有getTop(),也就是說它的位置已經在ScrollView中擺放好了。

        scrollTo(),scrollBy():移動view的顯示位置,並不移動它的點擊位置。平移動畫也是通過這兩個方法實現的。

        getScrollX(),getScrollY():擷取該view通過scrollBy()或者scrollTo()移動的總位移(這裡是位移,而不距離)。

        setTranslationX():設定x軸平衡距離。與scrollTo()的區別在於,它將view的點擊位置和顯示位置同時移動。

        onScrollChanged():每一次調用scrollTo()後便回調該方法。例如ScrollView不斷滑動時,就會一直回調該方法,不管是手指按下還是螢幕自動滾動。它的前兩個參數指的是當前在水平和垂直方向的scroll位移——顯示位置的移動距離;後兩個參數指前一次的scroll位移。

        overScrollBy():在滾動過程中的回調,其參數非常有用(註:在魅族手機上對該方法的回調有問題,會出現亂七八糟的現象)。前兩個參數為:調用該方法時,本次滾動在x,y軸上的移動距離;第三四個參數為:到調用該方法時,在x,y軸上總的滾動距離,不包括本次的滾動距離;第五六個參數為:在x,y軸上能滾動的距離,可以理解為它的內容高度減去控制項自身的高度;第七八個參數為:在x,y軸上能額外滾動的距離,即超出範圍後仍舊能滾動的距離。最後一個參數為:調用該方法是,是因為觸摸滾動還是自動滾動。

        上面說的都是ScrollView,並不適合於ListView,因為ListView在顯示時並不會將所有的View都建立好。當然對所有的View來說,onScrollChanged及scrollBy等方法的含義是一樣的,因為這些方法在View類中。

        dispatchDraw()與onDraw():dispatchDraw()主要用於子View的繪製,而onDraw()用於自身的繪製。並且,dispatchDraw()在onDraw()之後調用。

        computeScroll():由父View調用。當子View更新了mScrollX或者mScrollY值時,可以在該方法中更改子view的位置。此方法一般在view需要根據手勢進行移動時才重寫。它在onDraw()前調用。

        onAttachedToWindow():在onDraw()前的某一時刻調用,但是也有可能在onMeasure()前調用。當view依附於window上時調用。只有該方法之後,才有可用來繪製的surfaceview(Android所有繪製的映像都是在SurfaceView上的,除了自己使用SurfaceView外)。

        onDetachedFromWindow():與onAttachedToWindow()相反,當view從window上脫落時調用。此方法之後用來繪製的SurfaceView已經不存在了。

捲軸相關屬性         

        scrollbarFadeDuration:捲軸消失動畫的期間。如果把該值設定的非常大,可以間接實現捲軸一直效果的效果。

        scrollbarThumbHorizontal、scrollbarThumbVertical:捲軸中滾動的圖片。

        scrollbarTrackHorizontal、scrollbarTrackVertical:捲軸的滾動軌道(track),也即是捲軸的背景。

        fadeScrollbars:捲軸是否消失。false,捲軸一直存在;true,捲軸會在不使用時淡出。

        scrollbarStyle:主要用來決定捲軸的位置。有四個值:insideOverlay,insideInset與outsideOverlay,outsideInset。outside是說捲軸一直處在view的邊界,而inside代表捲軸會被padding影響,從而往裡移。Overlay說捲軸覆蓋在內容地區上,不增加padding的值;而inset卻是增加padding值,相當於把內容地區再往裡擠。樣本:

    <ListView        android:id="@+id/listView1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:padding="10px"        android:scrollbarStyle="insideOverlay" >    </ListView>
scrollbarStyle="insideOverlay"時


scrollbarStyle="insideInset"時

       對比上面兩圖可以發現,當為Overlay時,內容地區(即紅色地區)距離邊框(黑色)的距離是10px(ListView中設定了padding為10px);當為inset時內容地區距離邊框不止10px,但是捲軸的右邊距離邊框是10px。

scrollbarStyle="outsideOverlay"時


scrollbarStyle="outsideInset"時

 

       再對比四幅圖可以發現:outside的時候捲軸是處於view的邊緣的,而inside的時捲軸會受padding影響,從而不一定會處於邊緣。

ImageViewscaleType:

參考:http://www.cnblogs.com/carmanloneliness/archive/2012/08/06/2625489.html

        center:圖片大小為原始大小,如果圖片大小大於ImageView控制項,則截取圖片中間部分;若小於,則直接將圖片置中顯示。

   fitXY:將圖片縮放到與imageview大小相同,而且圖片的長寬縮放比例不一致。如果圖片比ImageView大,那麼圖片就會縮小到ImageView的大小;如果圖片比ImageView小,那麼圖片就會擴大到整個ImageView。

        fitStart,fitCenter與fitEnd:將圖片的長寬按同一比例進行縮放,直到使ImageView能完全包裹住圖片,並且圖片的某一邊和ImageView對應的邊長度相等。但此時並不能保證圖片與組件之間沒有空隙。片的寬要放大3倍,高要放大2倍。那麼就會放大2倍,此時高剛好充滿整個組件,但是寬卻與兩邊保留的有空隙。

        centerInside:當ImageView的大小大於圖片的大小時,圖片置中顯示,不進行任何縮放;當ImageView的大小小於圖片的大小時,那麼選取長寬縮小比例中的最大值進行縮小,然後置中顯示,此時類似於fitCenter。

        centerCrop:將圖片等比例縮放後截取圖片中間的部分顯示。如果ImageView大於圖片的大小,那麼選取長寬放大比例中的最大值進行放大;如果ImageView大於圖片的大小,那麼選取長寬放大比例中的最小值進行縮小。這樣做的目的是保證無論圖片是放大還是縮小,圖片都能將ImageView全部填滿不留空隙。

Checkbox與RadioButton

        經常需要自訂這兩種組件,也就是更換其中的圖片。在更換表徵圖之後,會發現兩個都佔有了一定的空白範圍。

結果如:


        點擊其中的紅框部分,一樣可以勾選上複選框。這是因為系統預設的為兩者帶有一個透明的背景。只需要在布局檔案中為它們的background屬性@null即可。另外:button的值也為@null。

        當然也可以採用自訂群組合控制項的方法,只不過比較麻煩。

具體style樣式為:

    <style name="MyCheckBox" parent="@android:style/Widget.CompoundButton.CheckBox">        <item name="android:background">@null</item>        <item name="android:layout_width">wrap_content</item>        <item name="android:layout_height">wrap_content</item>        <item name="android:layout_gravity">center_vertical</item>        <item name="android:button">@null</item>        <item name="android:layout_marginLeft">20dp</item>        <item name="android:drawablePadding">5dp</item>        <item name="android:drawableRight">@drawable/activity_contactor_select_selector</item>        <item name="android:textColor">#27415C</item>        <item name="android:textSize">14sp</item>        <item name="android:layout_marginTop">5dp</item>        <item name="android:layout_marginBottom">5dp</item>    </style>
其中drawableRight的值為一個選取器,也就是定義選中和未選中的兩種樣式。如下:<
    <item android:drawable="@drawable/selected" android:state_checked="true"></item>    <item android:drawable="@drawable/no_selected" android:state_checked="false"></item>    <item android:drawable="@drawable/no_selected"></item>

View入門

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.