我套路的自定義View 基礎篇 (一)

自定義view 很牛逼,實現起來超級簡單!!!跟着個人套路走。android

 

下面代碼實現了什麼功能也沒有的自定義view。重寫了onLayout,onMeasure,onSizeChanged。canvas

 
 
 
public class MyView extends View{
private String TAG = "MyView";
public MyView(Context context) {
super(context);
initView();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}

public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}

public void initView(){
Log.d(TAG, "onCreat");
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
Log.d(TAG, "onLayout");
super.onLayout(changed, left, top, right, bottom);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.d(TAG, "onMeasure");
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
Log.d(TAG, "onSizeChanged");
super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {
Log.d(TAG, "onDraw");
super.onDraw(canvas);
}
}
 

 

將MyView添加到佈局文件中:ide

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:id="@+id/activity_main"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="jaelyn.eventbus.MainActivity">

    <jaelyn.eventbus.MyView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>

 

運行後打印的結果爲:佈局

在不一樣的手機運行的打印結果不盡相同,可是大致的順序是:動畫

onCreat -> onMeasure -> onSizeChange -> onLayout-> onMeasure->onLayout -> onDrawspa

onCreate

  能夠在這裏面初始化常量如:paint;code

  也能夠獲取佈局文件中設置的屬性。(經過AttributeSet attrs, int defStyleAttr);xml

onMeasure

  計算view的寬高,咱們能夠在這裏根據須要修改view的寬高。blog

onLayout

  view放置的位置。view相對於父控件的位置。如傳入的值是(8 ,9 ,100, 100),則view距離父控件的左上角位置(8,9),右下角(100, 100)的範圍內顯示。(我通常在自定義容器view 的時候會重寫這個方法來計算自定義view的子view的位置)。utf-8

 

onSizeChanged

  view大小改變的時候會掉用這個方法。我都是用這個方法來獲取view的長寬、以及初始化一些位置常量。

onDraw

  經過這個方法的canvas,你就能夠向屏幕畫任何的東西了。

 

其中對於onMeasure、onLayout 在網上有不少詳細的解析,這裏就很少講了。這兩個方法比較難理解,你能夠先放一放。

去掉這兩個方法onMeasure、onLayout,自定義的套路就簡化爲 

1.onCreate(initView):初始化常量

2.onSizeChange:計算位置

3.onDraw: 繪製

 

接下咱們使用這個套路像屏幕寫字

public class MyView extends View{
    private String TAG = "MyView";
    private Paint paint;
    float x, y;
    private String text = "簡單的自定義View";

    public MyView(Context context) {
        super(context);
        initView();
    }

    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    public void initView(){
        Log.d(TAG, "onCreat");
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setTextSize(40);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        Log.d(TAG, "onSizeChanged");
        super.onSizeChanged(w, h, oldw, oldh);
        Rect bounds = new Rect();
        paint.getTextBounds(text, 0, text.length(), bounds);
        x = w / 2 - bounds.width() / 2;
        y = h / 2 - bounds.height() / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        Log.d(TAG, "onDraw");
        super.onDraw(canvas);
        canvas.drawText("簡單的自定義View", x, y , paint);
    }
}

效果:

 

這就是我實現自定義view的基本套路。

在這個基礎上能夠加入 手機監聽、計時器 來實現各類動畫效果。

相關文章
相關標籤/搜索