android自定義控件 幾種方式總結

方式1:不繼承任何組件 , 直接在代碼裏面調用實例化。
public class ProgressDialog {canvas

private Dialog dialog;ide

public ProgressDialog(@NonNull Context context) { //構造函數必須有
dialog = new Dialog(context);
buildDialog(context);
}函數

……其餘邏輯方法佈局

}ui

 


方式2:單獨控件,繼承與View ,能夠在xml上調用(沒法預覽,由於須要在運行時候才onDraw繪製)
public class ProgressPieView extends View {this



public ProgressPieView(Context context) {
this(context, null);
}xml

public ProgressPieView(Context context, AttributeSet attrs) {//必須添加有AttributeSet 的構造函數,才能在xml佈局上編寫不然報錯
this(context, attrs, 0);
}繼承

public ProgressPieView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);資源

init(context, attrs);//暴露出來的自定義方法。。。
}get


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//控制控件手勢衝突 和 高度
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
……
}


@Override
protected void onDraw(Canvas canvas) { // 繪製,用畫布繪製。。。,Linerlayout,RelatityLayout,FrameLayout裏面沒有這個方法
super.onDraw(canvas);

……
}


@Override
public void layout(int l, int t, int r, int b) {//控制佈局位置
……
}

 

@Override
protected void onAttachedToWindow() {//佈局 附加到主 佈局視圖中時會執行;不用再手動資源回收了
super.onAttachedToWindow();

}

@Override
protected void onDetachedFromWindow() {//佈局 從主佈局移除會執行;不用再手動資源回收了
super.onDetachedFromWindow();

}


……其餘邏輯方法
}

 

方式3:組合控件,裏面有多個控件的,繼承與Linerlayout或者RelatityLayout或FrameLayout;可在xml上直接編寫(可預覽)
;;;layout佈局自己就是繼承與 ViewGroup ViewGroup ViewGroup!
public class GirdMenuView extends FrameLayout {

private RecyclerView mRecyclerView;
private List<CategoriesModel> datas = new ArrayList<>();

//執行加載,xml佈局的時候,就會執行構造函數
public GirdMenuView(@NonNull Context context) {
this(context, null);
}

public GirdMenuView(@NonNull Context context, @Nullable AttributeSet attrs) {////必須添加有AttributeSet 的構造函數,才能在xml佈局上編寫不然報錯
this(context, attrs, 0);
}

public GirdMenuView(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);

initViews(context, attrs);//暴露出來的自定義方法。。。
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {//控制控件手勢衝突 和 高度,不是必須設置~
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
……
}


@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {//加載佈局時候,控制位置
……
}


@Override
protected void onAttachedToWindow() {//佈局 附加到主 佈局視圖中時會執行;不用再手動資源回收了
super.onAttachedToWindow();
if (mProgressDrawable != null) {

mProgressDrawable.start();
}
}

@Override
protected void onDetachedFromWindow() {//佈局 從主佈局移除會執行;不用再手動資源回收了
super.onDetachedFromWindow();
if (null != mProgressDrawable) {

mProgressDrawable.stop();
}
}
}

 


方式4:直接繼承現有控件,對現有控件擴展,相似繼承與view (但可預覽);系統自帶的全部控件都是繼承與view,裏面實現onDraw()方法
public class CustomViewPager extends ViewPager {
private static final String TAG = CustomViewPager.class.getSimpleName();

private float mTouchX;
private float mTouchY;

public CustomViewPager(Context context) {
super(context);
}

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

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {

return super.onInterceptTouchEvent(event);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
return super.onTouchEvent(event);
}
}

 

 

注意:

1 若要拋出和暴露結果,能夠結合回調函數使用

2 能夠參考系統自帶的控件 源碼,查看相關方法,更容易看明白自定義控件的方式。

相關文章
相關標籤/搜索