自定義框架(一)

  • 基礎知識
  • 自定義屬性

基礎知識

public class TestView extends View {

    public TestView(Context context) {
        super(context);
        Log.d("mDebug", "TestView context");
    }



    public TestView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        Log.d("mDebug", "TestView context,attrs,defStyle attrs="+attrs.getAttributeValue(0));
    }



    public TestView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Log.d("mDebug", "TestView context, attrs="+attrs.getAttributeValue(0));
    }



    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);
        Log.d("mDebug", "onDraw");
    }

    @Override
    protected void onFinishInflate() {
        // TODO Auto-generated method stub
        super.onFinishInflate();
        Log.d("mDebug", "onFinishInflate");
    }



    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        // TODO Auto-generated method stub
        super.onSizeChanged(w, h, oldw, oldh);
        Log.d("mDebug", "onSizeChanged,w="+w+",h="+h+",oldw="+oldw+",oldh="+oldh);
    }

}
10-16 16:32:24.241 31212-31212/com.hp.myframework D/mDebug: TestView context, attrs=100.0dip
10-16 16:32:24.241 31212-31212/com.hp.myframework D/mDebug: onFinishInflate
10-16 16:32:24.319 31212-31212/com.hp.myframework D/mDebug: onMeasure:1073742124    1073742124
10-16 16:32:24.343 31212-31212/com.hp.myframework D/mDebug: onSizeChanged,w=300,h=300,oldw=0,oldh=0
10-16 16:32:24.368 31212-31212/com.hp.myframework D/mDebug: onDraw
10-16 16:32:24.503 31212-31212/com.hp.myframework D/mDebug: onMeasure:1073742124    1073742124
10-16 16:32:24.504 31212-31212/com.hp.myframework D/mDebug: onDraw

構造方法->onFinishInflate()->onMeasure->onSizeChanged->onDraw

自定義 View的常用方法:
onFinishInflate() 當View中所有的子控件 均被映射成xml後觸發
onMeasure(int, int) 確定所有子元素的大小
onLayout(boolean, int, int, int, int) 當View分配所有的子元素的大小和位置時觸發
onSizeChanged(int, int, int, int) 當view的大小發生變化時觸發
onDraw(Canvas) view渲染內容的細節
onKeyDown(int, KeyEvent) 有按鍵按下後觸發
onKeyUp(int, KeyEvent) 有按鍵按下後彈起時觸發
onTrackballEvent(MotionEvent) 軌跡球事件
onTouchEvent(MotionEvent) 觸屏事件
onFocusChanged(boolean, int, Rect) 當View獲取 或失去焦點時觸發
onWindowFocusChanged(boolean) 當窗口包含的view獲取或失去焦點時觸發
onAttachedToWindow() 當view被附着到一個窗口時觸發
onDetachedFromWindow() 當view離開附着的窗口時觸發,提示該方法和 onAttachedToWindow() 是相反的。
onWindowVisibilityChanged(int) 當窗口中包含的可見的view發生變化時觸發

如何自定義屬性

1.在res/values中的attrs.xml中自定義屬性。

<resources>
    <!--  ===================自定義屬性==========================          -->
    <declare-styleable name="MyTextView">
        <attr name="text_color" format="boolean"/>
    </declare-styleable>

</resources>

2.在xml佈局中引用

    <com.hp.myframework.MyView.MyTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="顯示的內容"
        app:text_color="true"
        android:gravity="center_horizontal"
        />

3.在自定義的view裏面獲取xml中使用的屬性

  public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        // 拿到我自定義的屬性
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyTextView);
        mcolor = a.getBoolean(R.styleable.MyTextView_text_color, false);
        a.recycle();
    }

4.解析屬性並作出效果

@Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mcolor) {
            mPaint = getPaint();
            mViewWidth = getMeasuredWidth();
            /**
             * LinearGradient也稱作線性渲染,LinearGradient的作用是實現某一區域內顏色的線性漸變效果
             * public LinearGradient(float x0, float y0, float x1, float y1, int color0, int color1, Shader.TileMode tile)
             * x0:表示漸變的起始點x座標
             * y0:表示漸變的起始點y座標
             * x1:表示漸變的終點x座標
             * y1:表示漸變的終點y座標
             * color0:表示漸變開始顏色
             * color1:表示漸變結束顏色
             * tile:表示平鋪方式;
             *      CLAMP的作用是如果渲染器超出原始邊界範圍,則會複製邊緣顏色對超出範圍的區域進行着色
             *      REPEAT的作用是在橫向和縱向上以平鋪的形式重複渲染位圖
             *      MIRROR的作用是在橫向和縱向上以鏡像的方式重複渲染位圖
             *
             * public LinearGradient (float x0, float y0, float x1, float y1, int[] colors, float[] positions, Shader.TileMode tile);
             * colors:表示漸變的顏色數組
             * positions:用來指定顏色數組的相對位置;通常,參數positions設爲null,表示顏色數組以斜坡線的形式均勻分佈
             */
            mLinearGradient = new LinearGradient(
                    0,
                    0,
                    mViewWidth,
                    0,
                    new int[]{Color.BLUE, 0xffffffff, Color.BLUE},
                    null, Shader.TileMode.CLAMP
            );
            mPaint.setShader(mLinearGradient);
            mGradientMatrix = new Matrix();
        }


    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mGradientMatrix != null) {
            mTranslate += mViewWidth / 5;
            if (mTranslate > 2 * mViewWidth) {
                mTranslate = -mViewWidth;
            }
            mGradientMatrix.setTranslate(mTranslate, 0);
            mLinearGradient.setLocalMatrix(mGradientMatrix);
            postInvalidateDelayed(100);//在非UI線程中刷新UI界面
        }

    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章