小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

android中

 點點滴滴 2012-09-14

android中-自定義View對象

已有 430 次閱讀2011-8-24 23:10 |個人分類:android 學習篇

我們知道android SDK中的UI控件都是View或ViewGroup的子類(ViewGroup也是View的子類),我們將View細分為單獨View和容器View 兩種,所以就衍生兩個視圖基類:View和ViewGroup。通過擴展這兩個基類,Android SDK提供了一系列功能強大,設計巧妙的UI控件,但是用戶的需求是千變萬化的,SDK中不可能提供所有可能用到的UI形式,所以這就需要允許用戶自定義 View對象來完成他們所需要的效果。

幸好,Android SDK有支持自定義View對象,它允許你自定義一個類,繼承android.view.View對象,然后你只需要調整它里面的一些方法即可,那到底要 重寫哪些方法呢?如果你對android.view.View本身都不是很熟悉的話,那怎么會自定義view呢,就像是還不會走路,怎么就想學跑步了,所 以我們首先要先了解一些關于View的東西。

了解android.view.View

我們在了解Activity時就有提到,只要有能看到的UI界面,就一定有Activity。這邊所說的UI界面就是指View對象,所以View 和Activity離不開關系。當Activity處于Active狀態(tài)時(Activity獲取了當前的焦點),它就發(fā)出請求要求繪制Activity 中的View對象。系統(tǒng)根據視圖的關系層次從根節(jié)點出發(fā)開始繪制直到所有的葉子節(jié)點(因為View是有層次關系的), 整個繪制過程中View和ViewGroup的實現(xiàn)形式是不一樣的,因為ViewGroup里面會有子視圖對象,所以它需要請求子視圖執(zhí)行繪制,整個視圖 樹執(zhí)行繪圖的順序是中序遍歷,從根節(jié)點先畫,最后才是子節(jié)點。如果是View那么只要確定了它的大小即可執(zhí)行繪制方法。

繪制ViewGroup時可以分為兩個步驟:measure測量過程和layout布局過程。measure是用來測量ViewGroup所占用的 尺寸,它按照中序遍歷的方式遞歸調用子視圖的measure方法,然后保存各個子視圖對應測量出來的結果。當measure測量完成后就會調用 layout過程,layout過程也是使用中序遍歷遞歸調用,它做的工作是確定每個父視圖的尺寸,因為在measure階段已經完成了所有的子視圖尺 寸,所以父視圖的尺寸也可以通過它計算出來。

當measure測量執(zhí)行完成后,你就已經知道每個視圖所需的尺寸了,所以你需要設置值,讓getMeasureWidth和 getMeasureHeight方法可以獲取測量得到的結果。measure測量的結果必須考慮父視圖設置的長度,確保測量完成后得到的結果滿足:所有 的父視圖的尺寸都能裝得下它們各自的所有子視圖。一個父視圖可能會多次調用它的子視圖的measure方法,因為視圖可以設置成最大尺寸 (fill_parent),它首先會不限制子視圖的大小,讓子視圖能盡量大,但是如果有兩個子視圖都采用最大尺寸(fill_parent),那么只能 采取折中方式。

measure測量過程用兩個類來協(xié)助確定尺寸:MeasureSpec和LayoutParams。MeasureSpec用來對父視圖描述它需要的尺寸或位置,LayoutParams用來描述它需要的寬度和高度,它可定義的尺寸分為3種模型:

  1. 確定值:直接確定它的大小
  2. FILL_PARENT:填充父視圖的空間(最大占用空間)
  3. WRAP_CONTENT:能剛好顯示出視圖內容的大小區(qū)域即可(最小占用空間)

MeasureSpec用來讓父視圖通知子視圖,子視圖所能分配的大小,它分為下面3種模型:

  1. UNSPECIFIED:讓父視圖直接按照子視圖需求的尺寸進行分配,比如一個LinearLayout在measure中就對子視圖使用UNSPECIFIED模型,它不限制大小,按照子視圖的需求進行分配。
  2. EXACTLY:強迫子視圖的尺寸必須按照父視圖分配的尺寸進行測量,如果子視圖的實際尺寸比這個尺寸大則需要縮小,如果子視圖的實際尺寸比這個尺寸小則需要擴大。
  3. AT_MOST:強迫讓子視圖使用最大的尺寸,子視圖的尺寸不得大于父視圖定義的最大尺寸,但是可以小于這個最大尺寸值(跟EXACTLY不一樣的是它可以小于這個尺寸值)。

 

創(chuàng)建自定義View對象

了解了View測量和繪制的原理后,你就可以通過繼承它,重寫特定的方法創(chuàng)建一個自定義View對象。一般創(chuàng)建自定義View的用途是:

1.  自定義視圖對象,創(chuàng)建一個SDK沒提供的布局形式,如Accordion。

2. 將多個View對象組合起來封裝成一個新的自定義View對象,如Combox就是由一個下拉列表和一個輸入框和輸入框右邊一個按鈕組成的。

3. 改寫EditText對象,Android SDK中的記事本例子就使用了擴展EditText的視圖,它在每行文字的下面畫一條藍色的線。

4. 創(chuàng)建一個游戲面板,捕捉一些鍵盤或觸摸事件做出一些特定的處理。

 

如何創(chuàng)建自定義View對象

主要有下面幾個步驟:

1. 創(chuàng)建一個自定義類,繼承android.view.View。

2. 重寫父類構造方法,你可以在構造方法中獲取在xml布局文件里設置的屬性,你可以從這里讀取一些自定義的屬性配置View對象。

3. 重寫父類(View)的方法,這邊可以根據需要修改的程度有選擇的重寫,這些重寫的方法都是on開頭的方法如:onDraw、onMeasure或 onKeyDown(這些跟Activity生命周期中的onCreate,onPause…一樣也算繪制過程的生命周期)。如果你沒有重寫onDraw 默認它不做任何事,所以你會看到一片空白區(qū)域,onMeasure默認會創(chuàng)建一個100 * 100的區(qū)域

4.  使用這個對象

一般我們如果沒有在xml布局文件中使用一些自定義的配置屬性可以不用重寫構造方法,這時候我們只需要重寫onMeasure和onDraw方法。 onMeasure方法被調用時有兩個參數(shù):widthMeasureSpec和heightMeasureSpec這個參數(shù)是int型,用來表示寬度和 高度的尺寸,在onMeasure中必須根據這兩個參數(shù)確定View的寬度和高度值,然后調用setMeasureDimension(int width,int height)方法設置視圖的顯示區(qū)域范圍,否則將會拋出異常。在onDraw方法中,會有一個調用參數(shù):Canvas,你可以使用它進行繪制View的 操作。

下面我們使用一個簡單的例子演示下如何自定義一個View對象,我們先講述下這個例子實現(xiàn)的效果:例子將展現(xiàn)一個藍色背景的面板,當你點擊面板中的 某點時會以這個點擊點為中心隨機產生一個 半徑是1-10的紅色實心圓。我們首先自定義一個View對象,CustomView.java:

package com.android777.demo.uicontroller.view;
  
import java.util.ArrayList;
import java.util.List;
  
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
  
public class CustomView extends View {
  
    Paint paint;
    List<Dot> dots;
  
    public CustomView(Context context) {
        super(context);
        init();
    }
  
    public CustomView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
  
    public void init(){
  
        paint = new Paint();
        //設置繪制的顏色是紅色
        paint.setColor(Color.RED);
        paint.setAntiAlias(true);
  
        //視圖對象背景色是藍色
        setBackgroundColor(Color.BLUE);
  
        //初始化時里面沒有顯示任何的紅點
        dots = new ArrayList<CustomView.Dot>();
    }
  
    @Override
    public boolean onTouchEvent(MotionEvent event) {
  
        //獲取隨機點擊位置的坐標值
        float x = event.getX();
        float y = event.getY();
        //生成一個隨機半徑值范圍是1 - 10
        float radius = (float) (1 + Math.random() * 9);
  
        //將點擊的坐標和隨機生成的半徑值構造成Dot對象存放到視圖里
        dots.add(new Dot(x,y,radius));
  
        //掉用這個方法 重新繪制視圖, 這樣就能把上面剛添加的點顯示出來
        invalidate();
  
        return super.onTouchEvent(event);
    }
  
    @Override
    protected void onDraw(Canvas canvas) {
  
        //繪制所有視圖對象里保存的Dot點信息
        for(Dot dot : dots){
            canvas.drawCircle(dot.x, dot.y, dot.radius, paint);
        }
  
    }
  
    /**
     *
     * 這個靜態(tài)內部類用來封裝一個紅色圓點的位置和半徑
     *
     */
    static class Dot {
  
        public float x;
        public float y;
        public float radius;
  
        public Dot(float x,float y,float radius){
  
            this.x = x;
            this.y = y;
            this.radius = radius;
        }
  
    }
  
}

然后我們編寫一個Activity,在里面使用上面自定義的視圖,CustomViewActivity.java:

package com.android777.demo.uicontroller.view;
  
import android.app.Activity;
import android.os.Bundle;
  
public class CustomViewActivity extends Activity {
  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
  
        setContentView(new CustomView(this));
  
    }
  
}
運行后,點擊屏幕中的某點就會產生一個隨機半徑范圍是1-10的紅色小實心圓:

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多