Andriod 自定义View(1)

1.创建自定义控件
App->New->Ui Component ->Custom View,创建一个ATank控件
生成三个文件
1.ATank.Java
2.Sample_a_tank.xml
3.attrs_a_tank.xml

首先看一下 attrs_a_tank.xml

<resources>
    <declare-styleable name="ATank">
        <attr name="exampleString" format="string" />
        <attr name="exampleDimension" format="dimension" />
        <attr name="exampleColor" format="color" />
        <attr name="exampleDrawable" format="color|reference" />
    </declare-styleable>
</resources>

再看一下

ATank.Java

public class ATank extends View {
    private String mExampleString; // 在xml定义字符属性
    private int mExampleColor = Color.RED; //颜色属性
    private float mExampleDimension = 0; // 尺度
    private Drawable mExampleDrawable;//背景

    private TextPaint mTextPaint; //绘制字符
    private float mTextWidth; //字符宽度
    private float mTextHeight; //字符高度

    public ATank(Context context) {  //构造1
        super(context);
        init(null, 0);
    }

    public ATank(Context context, AttributeSet attrs) { //构造2
        super(context, attrs);
        init(attrs, 0);
    }

    public ATank(Context context, AttributeSet attrs, int defStyle) {  //构造3
        super(context, attrs, defStyle);
        init(attrs, defStyle);
    }

    private void init(AttributeSet attrs, int defStyle) { //初始化
        // Load attributes  从xml中加载属性
        final TypedArray a = getContext().obtainStyledAttributes(
                attrs, R.styleable.ATank, defStyle, 0);

        mExampleString = a.getString(
                R.styleable.ATank_exampleString);
        mExampleColor = a.getColor(
                R.styleable.ATank_exampleColor,
                mExampleColor);
        // Use getDimensionPixelSize or getDimensionPixelOffset when dealing with
        // values that should fall on pixel boundaries.
        mExampleDimension = a.getDimension(
                R.styleable.ATank_exampleDimension,
                mExampleDimension);
//获取背景参数属性
        if (a.hasValue(R.styleable.ATank_exampleDrawable)) {
            mExampleDrawable = a.getDrawable(
                    R.styleable.ATank_exampleDrawable);
            mExampleDrawable.setCallback(this);
        }

        a.recycle(); //释放该实例,从而使其可被其他模块复用。

        // //设置字符参数属性 1
        mTextPaint = new TextPaint();
        mTextPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
//Paint.FILTER_BITMAP_FLAG是使位图过滤的位掩码标志
//Paint.ANTI_ALIAS_FLAG是使位图抗锯齿的标志
//Paint.DITHER_FLAG是使位图进行有利的抖动的位掩码标志
        mTextPaint.setTextAlign(Paint.Align.LEFT);

        //设置字符参数属性 2
        invalidateTextPaintAndMeasurements();
    }

//获取字符尺度属性
    private void invalidateTextPaintAndMeasurements() {
        mTextPaint.setTextSize(mExampleDimension);
        mTextPaint.setColor(mExampleColor);
        mTextWidth = mTextPaint.measureText(mExampleString);

        Paint.FontMetrics fontMetrics = mTextPaint.getFontMetrics();
        mTextHeight = fontMetrics.bottom;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // TODO: consider storing these as member variables to reduce
        // allocations per draw cycle. 边界宽度
        int paddingLeft = getPaddingLeft();
        int paddingTop = getPaddingTop();
        int paddingRight = getPaddingRight();
        int paddingBottom = getPaddingBottom();

        int contentWidth = getWidth() - paddingLeft - paddingRight; //内容宽度
        int contentHeight = getHeight() - paddingTop - paddingBottom;

        // Draw the text. 放到 Content的中间
        canvas.drawText(mExampleString,
                paddingLeft + (contentWidth - mTextWidth) / 2, //字符位置计算x
                paddingTop + (contentHeight + mTextHeight) / 2,
                mTextPaint);
//        X+mTextWidth()/2 = (getWidth()-paddingRight-paddingLeft)/2 + paddingLeft
//        X=[(getWidth()-paddingRight-paddingLeft) - mTextWidth()]/2 +paddingLeft


//        // Draw the example drawable on top of the text.
        if (mExampleDrawable != null) {
            mExampleDrawable.setBounds(paddingLeft, paddingTop,
                    paddingLeft + contentWidth, paddingTop + contentHeight);
            mExampleDrawable.draw(canvas);
        }
    }
}

在Activity_main.xml 中加入控件

<com.example.tankcombat.ATank
    android:layout_width="300dp"
    android:layout_height="300dp"
    android:background="#ccc"
    android:paddingLeft="20dp"
    android:paddingBottom="40dp"
    app:exampleColor="#33b5e5"
    app:exampleDimension="24sp"
    app:exampleString="Hello, ATank"
    tools:ignore="MissingConstraints" />

字符定位的X,Y计算:
int contentWidth = getWidth() - paddingLeft - paddingRight;
int contentHeight = getHeight() - paddingTop - paddingBottom;

  // Draw the text.
  canvas.drawText(mExampleString,
          paddingLeft + (contentWidth - mTextWidth) / 2,
          paddingTop + (contentHeight + mTextHeight) / 2,
          mTextPaint);

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值