談到 Android自定義控件 ,這是一個令人渴望又害怕的領(lǐng)域,是作為一個Android開發(fā)人員的必經(jīng)之路。
鄙人也是一名初學(xué)者,懷著一顆分享的心,將自己所理解的知識點與君分享,不足之處望糾正
哈哈哈,說的有點多了,下面直入正題吧!
一、自定義控件預(yù)備知識點①構(gòu)造方法
package com.example.mytextview;
//import javax.swing.text.View; 這里別到錯了包,這個包是錯誤的
import android.content.Context;
import android.util.AttributeSet;
import android.view.View; //這個是正確的包
import androidx.annotation.Nullable;
ppublic class TextView extends View {
// 構(gòu)造函數(shù)會在代碼里面new的時候調(diào)用 : TextView tv = new TextView(this);
// 用 this 的好處就是 不管你從哪個構(gòu)造函數(shù) 進(jìn)入, 都會走到第三個里面 進(jìn)行統(tǒng)一處理
public TextView(Context context) {
this(context,null);
}
// 在布局 layout 中使用(調(diào)用) :
// <com.example.view_day01.TextView
// android:layout_width="wrap_content"
// android:layout_height="wrap_content"
// android:text="Hello World!" />
public TextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
// 在布局 layout 中使用(調(diào)用) 但是會有style:
// <com.example.view_day01.TextView
// style="@style/myStyle"
// android:text="Hello World!" />
public TextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
}
系統(tǒng)為我們提供了 四種構(gòu)造方法 但是,第四種幾乎用不到,所有,為列出。
對于以上三種構(gòu)造方法,我們需要掌握的就是:①這幾個構(gòu)造方法在什么時候被調(diào)用,和Activity生命周期檢測一樣,可以通過打印Log來分辨,(調(diào)用時期已注解在旁邊,望知)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?②我們通常將前兩個構(gòu)造方法的 super 修改為 this,方便在第三個構(gòu)造方法里進(jìn)行統(tǒng)一處理。
②常用方法
/**
*自定義View的測量方法
*@Author yiqi
*@created 2021/2/22 14:04
*@param widthMeasureSpec || heightMeasureSpec 32位的值 前兩位是 model :MeasureSpec.AT_MOST
* 后三十位是 Integer.MAX_VALUE
*@return
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//這個可以解決 ScrollView 嵌套 ListView 顯示不全的問題(面試常被問及)
heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2 , MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//布局的寬高都是由這個方法指定
//指定控件的寬高,需要測量
//獲取寬高的模式
int widthMode = MeasureSpec.getMode(widthMeasureSpec); //獲取前兩位
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
//獲取寬高的值
int widthSize = MeasureSpec.getSize(widthMeasureSpec); //獲取后面30位
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
// MeasureSpec.AT_MOST : 在布局中指定了wrap_content
// MeasureSpec.EXACTLY : 在布局中指定了確切的值 100dp match_parent fill_parent
// MeasureSpec.UNSPECIFIED : 盡可能的大 , 很少能用到 ListView ScrollView 在測量子布局的時候會用到 UNSPECIFIED
if (widthMode == MeasureSpec.UNSPECIFIED){
}
}
?對于onMeasure()這個方法,我們需要弄清楚一下幾點:
? ? ? ???第一點:widthMeasureSpec, heightMeasureSpec 都是 32位二進(jìn)制值,前兩位代表模式 可以通過?MeasureSpec.getMode 獲取,后30位代表最大寬高 可以通過?MeasureSpec.getSize 獲取
? ? ? ? ?第二點:MeasureSpec.makeMeasureSpec() 這個方法可以用來設(shè)置 測量模式,(這個地方會牽扯一個面試問題=》S從rollView里嵌套ListView ListView顯示不全問題,后面章節(jié)進(jìn)行講解)
? ? ? ? ?第三點:setMeasuredDimension()? 這個方法可以用來設(shè)置自定義控件的寬高
/**
*用于繪制
*@Author yiqi
*@created 2021/2/22 18:00
*@param
*@return
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//畫文本
canvas.drawText();
//畫弧
canvas.drawArc();
//畫圓
canvas.drawCircle();
}
?對于?onDraw() 方法 主要是掌握以上就差不多了,后面用到時會詳細(xì)講解
/**
*處理跟用戶交互的 手指觸摸等等
*@Author yiqi
*@created 2021/2/22 18:05
*@param
*@return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onTouchEvent(event);
}
?對于?onTouchEvent() 方法,并非一言兩語就能說盡的,它也是得在實戰(zhàn)中體現(xiàn)其價值。
看到這里,就說明你掌握基礎(chǔ)了,是不是覺得很簡單呢?。?!,哈哈哈??墒莿e輕敵,前面輕松代表后面很苦哦
本文摘自 :https://blog.51cto.com/u