自定義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
能夠在這裏面初始化常量如:paint;code
也能夠獲取佈局文件中設置的屬性。(經過AttributeSet attrs, int defStyleAttr);xml
計算view的寬高,咱們能夠在這裏根據須要修改view的寬高。blog
view放置的位置。view相對於父控件的位置。如傳入的值是(8 ,9 ,100, 100),則view距離父控件的左上角位置(8,9),右下角(100, 100)的範圍內顯示。(我通常在自定義容器view 的時候會重寫這個方法來計算自定義view的子view的位置)。utf-8
view大小改變的時候會掉用這個方法。我都是用這個方法來獲取view的長寬、以及初始化一些位置常量。
經過這個方法的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的基本套路。
在這個基礎上能夠加入 手機監聽、計時器 來實現各類動畫效果。