自定义控件(1)

自己写下的思路,为了方便。

注意点:在不同构造方法里面写上下面对应的话,不然会报错

this(context, null);
 this(context, attrs, 0);


 

//获取完属性以后要释放资源
        typedArray.recycle();

onMeasure里面测量的三种模式

  • UNSPECIFIED(未指定),父控件对子控件不加任何束缚,子元素可以得到任意想要的大小,这种MeasureSpec一般是由父控件自身的特性决定的。比如ScrollView,它的子View可以随意设置大小,无论多高,都能滚动显示,这个时候,size一般就没什么意义。EXACTLY(完全),父控件为子View指定确切大小,希望子View完全按照自己给定尺寸来处理,跟上面的场景1跟2比较相似,这时的MeasureSpec一般是父控件根据自身的MeasureSpec跟子View的布局参数来确定的。一般这种情况下size>0,有个确定值。AT_MOST(至多),父控件为子元素指定最大参考尺寸,希望子View的尺寸不要超过这个尺寸,跟上面场景3比较相似。这种模式也是父控件根据自身的MeasureSpec跟子View的布局参数来确定的,一般是子View的布局参数采用wrap_content的时候

界面刷新是要调用postInvalidate();

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import java.util.HashSet;
import java.util.Random;

/**
 * Created by Administrator on 2017/9/15.
 */

public class CustomTextView extends View{

    // 文字
    private String mTitleText;
    // 文字颜色
    private int mTitleTextColor;
    // 字号
    private int mTitleTextSize;
    private Rect mBound;
    private Paint paint;

    public CustomTextView(Context context) {
        this(context, null);
        Log.e("-----CustomTitleView:", "111");
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        Log.e("-----CustomTitleView:", "222");
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        Log.e("-----CustomTitleView:", "333");
        /**
         * 获得我们所定义的自定义样式属性
         */
        TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTextView, defStyleAttr, 0);
        int n = typedArray.getIndexCount();
        for (int i=0;i<n;i++){
            //获取单个属性的值的ID
            int aar = typedArray.getIndex(i);
            switch (aar) {
                case R.styleable.CustomTextView_titleText :
                     mTitleText = typedArray.getString(aar);
                    break;
                case R.styleable.CustomTextView_titleTextColor:
                     mTitleTextColor = typedArray.getColor(aar, Color.BLACK);
                    break;
                case R.styleable.CustomTextView_titleTextSize :
                    //typedArray.getDimensionPixelSize这个方法是获得int,
                    //typedArray.getDimension这个方法是获得float,
                     mTitleTextSize = typedArray.getDimensionPixelSize(aar, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
                    break;
                default:
                    break;
            }
        }
        //获取完属性以后要释放资源
        typedArray.recycle();
        // 获取文本的宽高
        paint = new Paint();
        paint.setTextSize(mTitleTextSize);
        mBound = new Rect();
        paint.getTextBounds(mTitleText,0,mTitleText.length(), mBound);

        //点击事件
        this.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                mTitleText=randdomText();
                postInvalidate();
            }
        });
    }

    public String randdomText(){
        Random random = new Random();
        HashSet<Integer> integers = new HashSet<>();
        while(integers.size()<4){
            int randomint = random.nextInt(100);
            integers.add(randomint);
        }
        StringBuffer stringBuffer = new StringBuffer();
        for (Integer i:integers){
            stringBuffer.append("").append(i);
        }
        return stringBuffer.toString();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthmode = MeasureSpec.getMode(widthMeasureSpec);
        int widthsize = MeasureSpec.getSize(widthMeasureSpec);
        int heightmode = MeasureSpec.getMode(heightMeasureSpec);
        int heightsize = MeasureSpec.getSize(heightMeasureSpec);
        int width=0;
        int height=0;

        switch (widthmode) {
            case  MeasureSpec.EXACTLY:
                width = getPaddingLeft() + getPaddingRight() + widthsize;
                break;
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                float textWidth = paint.measureText(mTitleText);
                width = (int) (getPaddingLeft() + getPaddingRight() + textWidth);
                break;

        }
        switch (heightmode) {
            case  MeasureSpec.EXACTLY:
                height = getPaddingLeft() + getPaddingRight() + heightsize;
                break;
            case MeasureSpec.AT_MOST:
            case MeasureSpec.UNSPECIFIED:
                //                int textHeight = mRect.height(); //直接计算出来的会有误差
                Paint.FontMetrics fontMetrics = paint.getFontMetrics();
//                float textHeight = Math.abs((fontMetrics.descent - fontMetrics.ascent));
                float textHeight = Math.abs((fontMetrics.bottom - fontMetrics.top));
                height = (int) (getPaddingTop() + getPaddingBottom() + textHeight);
                break;

        }
        setMeasuredDimension(width,height);
          }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        paint.setColor(Color.YELLOW);
        canvas.drawRect(0,0,getMeasuredWidth(),getMeasuredHeight(),paint);
        paint.setColor(mTitleTextColor);
        canvas.drawText(mTitleText,getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, paint);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值