关于Android 的自定义控件
在Android 中自定义控件可以分为三种
1.android 原生控件的扩展
2.组合控件(增加新的属性等)
3.通过重写onMearse onLayout onDraw以及OnTouch 完全自定义的全新控件
一 原生扩展空间
该种模式的自定义控件是 由于原生控件无法完全满足需求,从而对对原本控件进行扩展 。
通常自定义一个空间 去继承需要扩展的控件,对onDraw onTouch 进行扩写 或者 重写设计事件分发机制,对事件分发的三个函数 进行修改 (dispatchTouchEvent onInterceptTouchEvent onTouchEvent)
示例代码:
/**
* 简单的自定义控件 继承Android 的TextView 控件 进行扩充
* 该控件的ondraw方法保留了TextView 中的部分
*/
public class MyTextView extends TextView{
private int mViewWith;
private LinearGradient linearGradient;
private Matrix matrix;
private int translate;
public MyTextView(Context context) {
super(context);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@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) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(mViewWith==0){
mViewWith=getMeasuredWidth();
if(mViewWith>0){
//getPaint 获取绘制text的 画笔
Paint paint = getPaint();
linearGradient =new LinearGradient(0,0,mViewWith,0,new int[]{Color.BLUE,0xffffffff,Color.BLUE},null, Shader.TileMode.CLAMP);
paint.setShader(linearGradient);
matrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
//在super之前进行操作 是在原本的TextView 绘制文字之前进行其他绘制
//super 正常的绘制文字
super.onDraw(canvas);
//super 之后执行 绘制完文字之后进行处理
if(matrix!=null){
translate+=mViewWith/5;
if(translate>2*mViewWith){
translate=-mViewWith;
}
matrix.setTranslate(translate,0);
linearGradient.setLocalMatrix(matrix);
postInvalidateDelayed(100);
}
}
}
二 组合控件
该种模式的自定义控件主要是将原有的控件进行整合
该种方式 通过加载xml的方式 将多个原生控件整合在一起,使用自定义属性的方式队员友控件进行设置 通过自定义接口 进行回掉
示例代码:
/**
* Created by xgd6612 on 2016/12/25.
* 简单的组合空间 这里只是简单的进行了控件的组合使用
*/
public class MyTitleBar extends RelativeLayout implements View.OnClickListener {
private String titleName;
private TextViewOnClickListener textViewOnClickListener;
public interface TextViewOnClickListener{
void LeftClick();
}
public void setTextViewOnClickListener(TextViewOnClickListener listener){
textViewOnClickListener=listener;
}
public MyTitleBar(Context context) {
super(context);
}
public MyTitleBar(Context context, AttributeSet attrs) {
super(context, attrs);
View view = View.inflate(context, R.layout.MyTitleBar, this);
TextView title = (TextView) view.findViewById(R.id.tv_title);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MyTitleBar);
//在这里 typedArray 通过使用getXXX 的方法进行属性获取,第一个参数是属性名 如果有第二个参数的话 第二个参数返回的是默认值
titleName=typedArray.getString(R.styleable.MyTitleBar_title);
title.setText(titleName);
title.setOnClickListener(this);
typedArray.recycle();
}
public MyTitleBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void onClick(View v) {
int id=v.getId();
if(id==R.id.tv_title){
textViewOnClickListener.LeftClick();
}
}
}
在使用自定义属性的时候 需要引入命名空间
xmlns:mytitle="http://schemas.android.com/apk/res-auto"