今天看啥  ›  专栏  ›  weixin_43724742

自定义View

weixin_43724742  · CSDN  ·  · 2019-11-04 12:16

自定义View的构造函数:

public class TestView extends View {
  
    //这个构造方法会在java代码里new这个控件的时候调用
    public TestView(Context context) {
        super(context);
    }
    
    //这个构造方法会在xml布局文件中使用时自动调用
    public TestView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    //只有在API版本>21时才可能会用到
    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public TestView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }
}

自定义属性:

1.在 values/attrs.xml 文件中定义自定义属性:

    <resources>
        <declare-styleable name="test">
            <attr name="name" format="string" />
            <attr name="count" format="integer" />
            <attr name="xxx" format="color" />
            <attr name="xxx" format="reference" />	//资源ID,如xxx="@drawable/xxx"
            <attr name="xxx" format="boolean" />
            <attr name="xxx" format="dimension" />
            <attr name="xxx" format="float" />
            <attr name="xxx" format="fraction" />	//百分数,如xxx="100%"
            <attr name="xxx" format="color" />
            <attr name="xxx" format="reference|color" />	//混合属性
            <attr name="orientation">				//枚举,orientation="vertical">
        		<enum name="horizontal" value="0" />	
        		<enum name="vertical" value="1" />
    		</attr>
        </declare-styleable>
    </resources>

2.自定义View中获取这些属性:

public class MyTextView extends View {

    public MyTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.test);
        String name = ta.getString(R.styleable.test_name);
        int count = ta.getInteger(R.styleable.test_count, -1);
        ta.recycle();
    }
}

自定义控件的一般形式:

1.继承View重写onDraw创建不规则View:

一些Paint的常用设置:
注意paint的设置最好不要写在onDraw方法里

	Paint paint = new Paint();
	paint.setColor(0xFFFFFFFF); 							//设置画笔颜色
    //设置是否使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢。
    paint.setAntiAlias(true);
    //设定是否使用图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
    paint.setDither(true);
	paint.setStyle(Paint.Style.FILL);						//设置画笔实心
    paint.setStyle(Paint.Style.STROKE);						//设置画笔空心
    paint.setStrokeWidth(3);								//设置画笔宽度为3px

	Paint.setTextSize(50);									//设置字号大小

path用来画不规则图形:

	Path path = new Path();									
   	path.moveTo(100, 100);
    path.lineTo(100, 100);
    
	path.quadTo(100, 200, 200, 200);						//二阶贝塞尔曲线
	path.cubicTo(200, 100, 200, 200, 100, 200);				//三阶贝塞尔曲线
	
	path.close();											//把第一个点和最后一个点连接在一起,构成一个封闭图形

渐变:

	Shader shader = new LinearGradient(x1, y1, x2, y2,		//设置渐变的起始坐标和终点坐标
	new int[]{Color.RED,Color.BLACK,Color.GREEN},			//设置渐变的颜色及顺序
	new float[]{0 , 0.5f, 1.0f}								//设置各个颜色的位置比例,null表示均匀分布
	Shader.TileMode.REPEAT);								//REPEAT循环;CLAMP界外使用边界颜色;MIRROR镜像循环
    paint.setShader(shader);

canvas:
canvas才是最后绘制的主体,它可以:绘制图形,变换,存档

	canvas.drawLine(x1, y1, x2, y2, paint);								//绘制直线  
	canvas.drawRect(x1, y1, x2, y2, paint);     						//绘制矩形  
	canvas.drawCircle(ox, oy, r, paint);								//绘制圆心
	canvas.drawOval(new RectF(x1, y1, x2, y2), paint);					//绘制椭圆
	canvas.drawPath(path, paint);										//画某种路径
	canvas.drawText("hello world", 100, 100, mPaint);					//绘制字符串
	canvas.drawRoundRect(new RectF(x1, y1, x2, y2), 30, 20, mPaint); 	//绘制圆角矩形
	canvas.drawColor(Color.GRAY); 										//绘制画布背景颜色
	
	
	//以下四个画布变换的操作,必须要先执行画布变换,再绘制图形,顺序不可颠倒
	canvas.translate(100, 100); 										//向右下方平移画布
	canvas.scale(0.5f, 0.5f); 											//缩放画布,默认缩放中心为0,0点
	canvas.rotate(45,200,200)											//旋转画布,顺时针为正
	canvas.skew(0, 1); 													//向上倾斜45 度 
	
	
	//存档画布当前状态,记录当前时刻画布的平移旋转等变换信息,这个方法必须配合restore使用,否则没有任何作用
	canvas.save(); 									
	//画布的变换状态回滚到上次存档的状态,在执行这个方法之前必须有save方法执行过,否则会引发崩溃
	canvas.restore(); 								

2.继承某种ViewGroup

用来继承某个布局中包含多个控件的情况,类似于<Merge>标签的功能,只是通过自定义控件的方式控件组增加一些逻辑

public class SimpleEditor extends FrameLayout {
    private EditText editor;
    private Context context;

    public SimpleEditor(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    private void init() {
        inflate(context, R.layout.layout_simple_editor, this);
        editor = (EditText) findViewById(R.id.root_view);
    }
}

3.继承某种系统控件,扩展其功能

例如给TextView加条下划线:

public class LineTextView extends TextView {
    private Paint mPaint;
    
    public LineTextView(Context context) {
        super(context);
        init();
    }

    public LineTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setColor(Color.BLACK);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = getWidth();
        int height = getHeight();
        mPaint.setColor(Color.BLUE);
        canvas.drawLine(0,height,width,height,mPaint);
    }
}



原文地址:访问原文地址
快照地址: 访问文章快照