SeniorUI33_自定义控件的概括

SeniorUI_高级UI汇总目录
自定义控件一般分为三类:继承控件、自绘控件、组合控件
可以直接看第四部分: 自定义控件onMeasure的常见“套路”

一 继承控件

指继承系统的原生控件,修改或者装饰系统控件某些方法

  • 看系统控件里面是否有控件 能够支持 (50%-80%)产品功能
  • 在原有基础上 添加特定场景的产品功能。

1 Demo

public class ASpecImageView extends ImageView {

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

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

    public ASpecImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int desiredSizeWidth;
        float aspect;

        Drawable d = getDrawable();
        if (d == null) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            return;
        }

        desiredSizeWidth = d.getIntrinsicWidth();
        aspect = (float) d.getIntrinsicWidth() / (float) d.getIntrinsicHeight();

        int widthsSize = View.resolveSize(desiredSizeWidth, widthMeasureSpec);

        int heightSize = (int) (widthsSize/ aspect);
        int specMode = MeasureSpec.getMode(heightMeasureSpec);
        int specSize = MeasureSpec.getSize(heightMeasureSpec);

        if (specMode == MeasureSpec.AT_MOST || specMode == MeasureSpec.EXACTLY) {
            if (heightSize > specSize) {
                heightSize = specSize;
                widthsSize = (int) (heightSize * aspect);
            }
        }
        setMeasuredDimension(widthsSize, heightSize);
    }
}

2 效果

在这里插入图片描述

3 代码地址

AspecImageViewActivity

二 自绘控件

  • 系统的控件库中找不到 相似逻辑的额控件
  • 完成 产品逻辑不规则 / 较为特殊的产品需求, 需要自己进行绘制
  • 封装性/适配性
  • 知识点 canvas path
    invalidate();
    postInvalidate();

1 Demo

public class DoubleImageView extends View {

    /*Image Contents*/
    private Drawable mLeftDrawable, mRightDrawable;
    /*Text Contents*/
    private CharSequence mText;
    private StaticLayout mTextLayout;
    /*Text Drawing*/
    private TextPaint mTextPaint;
    private Point mTextOrigin;
    private int mSpacing;
    private int desiredWidth;


    public DoubleImageView(Context context) {
        this(context, null);
    }

    public DoubleImageView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DoubleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView(context, attrs, defStyleAttr);
    }

    private void initView(Context context, AttributeSet attrs, int defStyle) {
        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        mTextOrigin = new Point(0, 0);

        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.DoubleImageView, 0, defStyle);
        Drawable d = a.getDrawable(R.styleable.DoubleImageView_android_drawableLeft);
        if (d != null) {
            setLeftDrawable(d);
        }
        d = a.getDrawable(R.styleable.DoubleImageView_android_drawableRight);
        if (d != null) {
            setRightDrawable(d);
        }

        int spacing = a.getDimensionPixelOffset(R.styleable.DoubleImageView_android_spacing, 0);
        setSpacing(spacing);

        int color = a.getColor(R.styleable.DoubleImageView_android_textColor, 0);
        mTextPaint.setColor(color);

        int rawSize = a.getDimensionPixelSize(R.styleable.DoubleImageView_android_textSize, 0);
        mTextPaint.setTextSize(rawSize);

        CharSequence text = a.getText(R.styleable.DoubleImageView_android_text);
        setText(text);
        a.recycle();
    }


    public void setLeftDrawableResource(int resId) {
        Drawable d = getResources().getDrawable(resId);
        setLeftDrawable(d);
    }

    public void setLeftDrawable(Drawable left) {
        mLeftDrawable = left;
        updateContentBounds();
        invalidate();
    }

    public void setRightDrawableResource(int resId) {
        Drawable d = getResources().getDrawable(resId);
        setRightDrawable(d);
    }

    public void setRightDrawable(Drawable right) {
        mRightDrawable = right;
        updateContentBounds();
        invalidate();
    }

    public void setSpacing(int spacing) {
        mSpacing = spacing;
        updateContentBounds();
        invalidate();
    }

    public void setText(CharSequence text) {
        if (!TextUtils.equals(mText, text)) {
            mText = text;
            updateContentBounds();
            invalidate();
        }
    }

    private void updateContentBounds() {
        if (mText == null) {
            mText = "";
        }
        float textWidth = mTextPaint.measureText(mText, 0, mText.length());
        mTextLayout = new StaticLayout(mText, mTextPaint, (int) textWidth, Layout.Alignment.ALIGN_CENTER, 1f, 0f, true);
        int left = (getWidth() - getDesiredWidth()) / 2;
        int top = (getHeight() - getDesireHeight()) / 2;

        if(mLeftDrawable != null){
            mLeftDrawable.setBounds(left, top, left + mLeftDrawable.getIntrinsicWidth(), top + mLeftDrawable.getIntrinsicHeight());
            left += (mLeftDrawable.getIntrinsicWidth() * 0.33f);
            top += (mLeftDrawable.getIntrinsicHeight() * 0.33f);
        }


        if (mRightDrawable != null) {
            mRightDrawable.setBounds(left, top, left + mRightDrawable.getIntrinsicWidth(), top + mRightDrawable.getIntrinsicHeight());
            left = mRightDrawable.getBounds().right + mSpacing;
        }


        if (mTextLayout != null) {
            top = (getHeight() - mTextLayout.getHeight()) /2;
            mTextOrigin.set(left, top);
        }
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        if (w != oldw || h != oldh) {
            updateContentBounds();
            invalidate();
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mLeftDrawable != null) {
            mLeftDrawable.draw(canvas);
        }
        if (mTextLayout != null) {
            canvas.save();
            canvas.translate(mTextOrigin.x, mTextOrigin.y);
            mTextLayout.draw(canvas);
            canvas.restore();
        }
        if (mRightDrawable != null) {
            mRightDrawable.draw(canvas);
        }
    }

    public int getDesiredWidth() {
        int leftWidth;
        if (mLeftDrawable == null) {
            leftWidth = 0;
        } else {
            leftWidth = mLeftDrawable.getIntrinsicWidth();
        }
        int rightWidth;
        if (mRightDrawable == null) {
            rightWidth = 0;
        } else {
            rightWidth = mRightDrawable.getIntrinsicWidth();
        }
        int textWidth;
        if (mTextLayout == null) {
            textWidth = 0;
        } else {
            textWidth = mTextLayout.getWidth();
        }
        return (int) (leftWidth * 0.67f) + (int) (rightWidth * 0.67f) + mSpacing + textWidth;
    }

    private int getDesireHeight(){
        int leftHeight;
        if (mLeftDrawable == null) {
            leftHeight = 0;
        } else {
            leftHeight = mLeftDrawable.getIntrinsicHeight();
        }

        int rightHeight;
        if (mRightDrawable == null) {
            rightHeight = 0;
        } else {
            rightHeight = mRightDrawable.getIntrinsicHeight();
        }
        return (int)(leftHeight * 0.67f) + (int)(rightHeight * 0.67f);
    }

}

2 效果图

在这里插入图片描述

3 代码

DoubleImageViewActivity

三 组合控件

比较简单,注意属性的声明

1 Demo

public class CustomTextView extends RelativeLayout{

    //文字
    private String leftTvString;//左边文字
    private String rightTvString;//右边文字
    private String centerTvString;//中间文字
    private String leftTopTvString;//左上文字
    private String leftBottomTvString;//左下文字
    private int leftTvSize;//左边文字大小
    private int rightTvSize;//右边文字大小
    private int centerTvSize;//中间文字大小
    private int leftTopTvSize;//左上文字大小
    private int leftBottomTvSize;//左下文字大小
    private int leftTvMarginleft;//左边文字左边距
    private int rightTvMarginright;//右边文字右边距
    private int leftTopTvColor;//左上文字颜色
    private int leftBottomTvColor;//左下文字颜色
    private int leftTvColor;//左边文字颜色
    private int rightTvColor;//右边文字颜色
    private int centerTvColor;//中间文字颜色

    //图片
    private Drawable rightImgRes;//右边图片资源
    private Drawable leftImgRes;//左边图片资源
    private int leftImgWidht;//左边图片宽带
    private int leftImgHeight;//左边图片高度
    private int rightImgWidht;//右边图片宽带
    private int rightImgHeight;//右边图片高度
    private int leftImgMarginleft;//左边图片左边距
    private int rightImgMarginright;//右边图片右边距
    private int centerTVMarginleft;//中间文字左边距
    private int leftTopTvMarginTop;//左上文字上边距
    private int leftTopTvMarginleft;//左上文字左边就
    private int leftBottomTvMarginleft;//左下文字左边距
    private int leftButtomTvMarginBottom;//左下文字下边距
    //下划线margin
    private int bottomLineMargin;
    private boolean bottomLineShow;
    private int bottomLineHeight;
    private int bottomcolor;

    //一些默认属性
    private int defaultTvColor = 0xFF373737;//文字默认颜色
    private TextView leftTv, centerTv, rightTv,leftTopTv,leftBottomTv;
    private ImageView leftIV, rightIV;
    private View bottomView;
    private Context mContext;


    private OnTextViewClickListener OnTextViewClickListener;

    public CustomTextView setOnTextViewClickListener(OnTextViewClickListener listener) {
        this.OnTextViewClickListener = listener;
        return this;
    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;
        initAttr(attrs);
        initLayout();
        this.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (OnTextViewClickListener != null) {
                    OnTextViewClickListener.OnTextViewClick();
                }
            }
        });
    }

    private void initAttr(AttributeSet attrs) {
        TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
        leftTvString = typedArray.getString(R.styleable.CustomTextView_leftTvString);
        rightTvString = typedArray.getString(R.styleable.CustomTextView_rightTvString);
        centerTvString = typedArray.getString(R.styleable.CustomTextView_centerTvString);
        leftTopTvString = typedArray.getString(R.styleable.CustomTextView_leftTopTvString);
        leftBottomTvString = typedArray.getString(R.styleable.CustomTextView_leftBottomTvString);
        leftTvSize = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftTvSize, 16);
        rightTvSize = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_rightTvSize, 16);
        centerTvSize = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_centerTvSize, 16);
        leftImgRes = typedArray.getDrawable(R.styleable.CustomTextView_leftImg);
        rightImgRes = typedArray.getDrawable(R.styleable.CustomTextView_rightImg);
        leftTvColor = typedArray.getColor(R.styleable.CustomTextView_leftTvColor, defaultTvColor);
        rightTvColor = typedArray.getColor(R.styleable.CustomTextView_rightTvColor, defaultTvColor);
        centerTvColor = typedArray.getColor(R.styleable.CustomTextView_centerTvColor, defaultTvColor);
        leftImgWidht = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftImgWight, 0);
        leftImgHeight = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftImgHeight, 0);
        rightImgWidht = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_rightImgWidht, 0);
        rightImgHeight = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_rightImgHeight, 0);
        leftTvMarginleft = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftTvMarginleft, 0);
        rightTvMarginright = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_rightTvMarginright, 0);
        leftImgMarginleft = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftImgMarginleft, 0);
        rightImgMarginright = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_rightImgMarginright, 0);
        bottomLineMargin = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_bottomLineMargin, 0);
        bottomLineShow = typedArray.getBoolean(R.styleable.CustomTextView_bottomLineShow, false);
        bottomLineHeight = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_bottomLineHeight, 1);
        bottomcolor = typedArray.getColor(R.styleable.CustomTextView_bottomcolor, defaultTvColor);
        centerTVMarginleft = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_centerTVMarginleft, 0);
        leftTopTvMarginTop = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftTopTvMarginTop, 0);
        leftTopTvMarginleft = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftTopTvMarginleft, 0);
        leftBottomTvMarginleft = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftBottomTvMarginleft, 0);
        leftButtomTvMarginBottom = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftButtomTvMarginBottom, 0);
        leftTopTvSize = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftTopTvSize, 16);
        leftBottomTvSize = typedArray.getDimensionPixelOffset(R.styleable.CustomTextView_leftBottomTvSize, 16);
        leftTopTvColor = typedArray.getColor(R.styleable.CustomTextView_leftTopTvColor, defaultTvColor);
        leftBottomTvColor = typedArray.getColor(R.styleable.CustomTextView_leftBottomTvColor, defaultTvColor);

        typedArray.recycle();
    }

    private void initLayout() {
        //左边图片初始化
        if (leftImgRes != null) {
            initLeftImg();
        }
        //左边文字初始化
        if (!TextUtils.isEmpty(leftTvString)) {
            initLeftTv();
        }
        //中间文字初始化
        if (!TextUtils.isEmpty(centerTvString)) {
            initCenterTv();
        }
        //左上文字初始化
        if(!TextUtils.isEmpty(leftTopTvString)){
            initLeftTopTv();
        }
        //左下文字初始化
        if(!TextUtils.isEmpty(leftBottomTvString)){
            initLeftBottomTv();
        }

        //右边图片初始化
        if (rightImgRes != null) {
            initRightImg();
        }
        //右边的文字初始
        if (!TextUtils.isEmpty(rightTvString)) {
            initRightTv();
        }
        //下边线初始化
        if (bottomLineShow) {
            initBottomLine();
        }
    }

    //以下是设置字体和图片的属性,,为了适配最好不要动态设置与数字有关的属性
    //代码设置左边文字
    public CustomTextView setLeftTv(String tvStr, String tvColor) {
        leftTvString = TextUtils.isEmpty(tvStr) ? leftTvString : tvStr;
        leftTvColor = TextUtils.isEmpty(tvColor) ? leftTvColor : Color.parseColor(tvColor);
        if (leftTv == null) {
            initLeftTv();
        } else {
            leftTv.setText(leftTvString);
            leftTv.setTextColor(leftTvColor);
        }
        return this;
    }

    //代码设置右边文字
    public CustomTextView setRightTv(String tvStr, String tvColor) {
        rightTvString = TextUtils.isEmpty(tvStr) ? rightTvString : tvStr;
        rightTvColor = TextUtils.isEmpty(tvColor) ? rightTvColor : Color.parseColor(tvColor);
        if (rightTv == null) {
            initRightTv();
        } else {
            rightTv.setText(rightTvString);
            rightTv.setTextColor(rightTvColor);
        }

        return this;
    }

    //代码设置中间文字
    public CustomTextView setCenterTv(String tvStr, String tvColor) {
        centerTvString = TextUtils.isEmpty(tvStr) ? centerTvString : tvStr;
        centerTvColor = TextUtils.isEmpty(tvColor) ? centerTvColor : Color.parseColor(tvColor);
        if (centerTv == null) {
            initCenterTv();
        } else {
            centerTv.setText(centerTvString);
            centerTv.setTextColor(centerTvColor);
        }
        return this;
    }

    //代码设置左上文字颜色
    public CustomTextView setLeftTopTv(String tvStr,String tvColor){
        leftTopTvString=TextUtils.isEmpty(tvStr)?leftTopTvString:tvStr;
        leftTopTvColor=TextUtils.isEmpty(tvColor)?leftTopTvColor:Color.parseColor(tvColor);
        if(leftTopTv==null){
            initLeftTopTv();
        }else{
            leftTopTv.setTextColor(leftTopTvColor);
            leftTopTv.setText(leftTopTvString);
        }
        return this;
    }
    //代码设置左下文字颜色
    public CustomTextView setLeftBottomTv(String tvStr,String tvColor){
        leftBottomTvString=TextUtils.isEmpty(tvStr)?leftBottomTvString:tvStr;
        leftBottomTvColor=TextUtils.isEmpty(tvColor)?leftBottomTvColor:Color.parseColor(tvColor);
        if(leftBottomTv==null){
            initLeftBottomTv();
        }else{
            leftBottomTv.setTextColor(leftBottomTvColor);
            leftBottomTv.setText(leftBottomTvString);
        }
        return this;
    }


    //代码设置布局背景颜色
    public CustomTextView setCustomTvBackground(String strColor){
        CustomTextView.this.setBackgroundColor(Color.parseColor(strColor));
        return this;
    }


    //代码设置左边图片
    public CustomTextView setLeftImg(Drawable icRes) {
        leftImgRes = icRes;
        if (leftIV == null) {
            initLeftImg();
        } else {
            leftIV.setImageDrawable(leftImgRes);
        }
        return this;
    }

    //代码设置右边图片
    public CustomTextView setRightImg(Drawable icRes) {
        rightImgRes = icRes;
        if (rightIV == null) {
            initRightImg();
        } else {
            rightIV.setImageDrawable(rightImgRes);
        }
        return this;
    }

    //设置下划线
    public CustomTextView setBottomLine(String color) {
        bottomcolor = TextUtils.isEmpty(color) ? bottomcolor : Color.parseColor(color);
        if (bottomView == null) {
            initBottomLine();
        } else {
            bottomView.setBackgroundColor(bottomcolor);
        }
        return this;
    }

    private void initLeftImg() {
        leftIV = new ImageView(mContext);
        int width = leftImgWidht != 0 ? leftImgWidht : LayoutParams.WRAP_CONTENT;
        int height = leftImgHeight != 0 ? leftImgHeight : LayoutParams.WRAP_CONTENT;
        LayoutParams leftImgParams = new LayoutParams(width, height);
        leftImgParams.addRule(ALIGN_PARENT_LEFT, TRUE);
        leftImgParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
        leftImgParams.setMargins(leftImgMarginleft, 0, 0, 0);
        leftIV.setScaleType(ImageView.ScaleType.FIT_XY);
        leftIV.setId(R.id.leftImg);
        leftIV.setLayoutParams(leftImgParams);
        leftIV.setImageDrawable(leftImgRes);
        leftIV.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (OnTextViewClickListener != null) {
                    OnTextViewClickListener.OnLeftImgClick();
                }
            }
        });
        addView(leftIV);
    }

    private void initLeftTv() {
        leftTv = new TextView(mContext);
        LayoutParams leftTvParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        leftTvParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
        leftTvParams.addRule(RelativeLayout.RIGHT_OF, R.id.leftImg);
        leftTvParams.setMargins(leftTvMarginleft, 0, 0, 0);
        leftTv.setLayoutParams(leftTvParams);
        leftTv.setTextColor(leftTvColor);
        leftTv.setId(R.id.leftTv);
        leftTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, leftTvSize);
        leftTv.setText(leftTvString);
        addView(leftTv);
    }

    private void initCenterTv() {
        centerTv = new TextView(mContext);
        LayoutParams centerTvParams = new LayoutParams(LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        centerTvParams.addRule(centerTVMarginleft != 0 && !TextUtils.isEmpty(leftTvString) ? RelativeLayout.RIGHT_OF : RelativeLayout.CENTER_IN_PARENT, centerTVMarginleft != 0 && !TextUtils.isEmpty(leftTvString) ? R.id.leftTv : TRUE);
        centerTvParams.addRule(RelativeLayout.CENTER_VERTICAL);
        centerTvParams.setMargins(centerTVMarginleft, 0, 0, 0);
        centerTv.setLayoutParams(centerTvParams);
        centerTv.setTextColor(centerTvColor);
        centerTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, centerTvSize);
        centerTv.setText(centerTvString);
        addView(centerTv);
    }

    private void initLeftTopTv(){
        leftTopTv=new TextView(mContext);
        LayoutParams leftTopTvParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        leftTopTvParams.addRule(RelativeLayout.RIGHT_OF, R.id.leftImg);
        leftTopTvParams.addRule(RelativeLayout.ALIGN_PARENT_TOP,TRUE);
        leftTopTvParams.setMargins(leftTopTvMarginleft,leftTopTvMarginTop,0,0);
        leftTopTv.setLayoutParams(leftTopTvParams);
        leftTopTv.setTextSize(TypedValue.COMPLEX_UNIT_PX,leftTopTvSize);
        leftTopTv.setTextColor(leftTopTvColor);
        leftTopTv.setText(leftTopTvString);
        addView(leftTopTv);
    }

    private void initLeftBottomTv(){
        leftBottomTv=new TextView(mContext);
        LayoutParams leftBottomTvParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        leftBottomTvParams.addRule(RelativeLayout.RIGHT_OF, R.id.leftImg);
        leftBottomTvParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,TRUE);
        leftBottomTvParams.setMargins(leftBottomTvMarginleft,0,0,leftButtomTvMarginBottom);
        leftBottomTv.setLayoutParams(leftBottomTvParams);
        leftBottomTv.setTextSize(TypedValue.COMPLEX_UNIT_PX,leftBottomTvSize);
        leftBottomTv.setTextColor(leftBottomTvColor);
        leftBottomTv.setText(leftBottomTvString);
        addView(leftBottomTv);
    }


    private void initRightImg() {
        rightIV = new ImageView(mContext);
        int width = rightImgWidht != 0 ? rightImgWidht : LayoutParams.WRAP_CONTENT;
        int height = rightImgHeight != 0 ? rightImgHeight : LayoutParams.WRAP_CONTENT;
        LayoutParams rightIVParams = new LayoutParams(width, height);
        rightIVParams.addRule(RelativeLayout.CENTER_VERTICAL, TRUE);
        rightIVParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, TRUE);
        rightIVParams.setMargins(0, 0, rightImgMarginright, 0);
        rightIV.setScaleType(ImageView.ScaleType.FIT_XY);
        rightIV.setId(R.id.rightImg);
        rightIV.setLayoutParams(rightIVParams);
        rightIV.setImageDrawable(rightImgRes);
        rightIV.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (OnTextViewClickListener != null) {
                    OnTextViewClickListener.OnRightImgClick();
                }
            }
        });
        addView(rightIV);

    }

    private void initRightTv() {
        rightTv = new TextView(mContext);
        LayoutParams rightTvParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        rightTvParams.addRule(rightImgRes != null ? RelativeLayout.LEFT_OF : RelativeLayout.ALIGN_PARENT_RIGHT, rightImgRes != null ? R.id.rightImg : TRUE);
        rightTvParams.addRule(RelativeLayout.CENTER_VERTICAL);
        rightTvParams.setMargins(0, 0, rightTvMarginright, 0);
        rightTv.setLayoutParams(rightTvParams);
        rightTv.setTextColor(rightTvColor);
        rightTv.setTextSize(TypedValue.COMPLEX_UNIT_PX, rightTvSize);
        rightTv.setText(rightTvString);
        rightTv.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (OnTextViewClickListener != null) {
                    OnTextViewClickListener.OnRightTvClick();
                }
            }
        });

        addView(rightTv);
    }

    private void initBottomLine() {
        bottomView = new View(mContext);
        LayoutParams bottomParams = new LayoutParams(LayoutParams.WRAP_CONTENT, bottomLineHeight);
        bottomParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM, TRUE);
        bottomParams.setMargins(bottomLineMargin, 0, bottomLineMargin, 0);
        bottomView.setLayoutParams(bottomParams);
        bottomView.setBackgroundColor(bottomcolor);
        addView(bottomView);
    }

    //点击事件接口
    public static class OnTextViewClickListener {
        public void OnLeftImgClick() {
        }

        public void OnRightImgClick() {
        }

        public void OnTextViewClick() {
        }

        public void OnRightTvClick() {

        }

    }
}

2 效果图

在这里插入图片描述

3 代码

CustomTextViewActivity

四 自定义控件onMeasure的常见“套路”

1 继承自View的子类

			只需要重写onMeasure测量好自己的宽高就可以了。
			最终调用setMeasuredDimension()保存好自己的测量宽高。
				int mode = MeasureSpec.getMode(widthMeasureSpec);
				int Size = MeasureSpec.getSize(widthMeasureSpec);
				int viewSize = 0;
				switch(mode){
					case MeasureSpec.EXACTLY:
						viewSize = size;//当前view的尺寸就为父容器的尺寸
						break;
					case MeasureSpec.AT_MOST:
						viewSize = Math.min(size, getContentSize());//当前view的尺寸就为内容尺寸和费容器尺寸当中的最小值。
						break;
					case MeasureSpec.UNSPECIFIED:
						viewSize = getContentSize();//内容有多大,久设置多大尺寸。
						break;
					default:
						break;
				}
				
				view 提供的api: public static int resolveSize(int size, int measureSpec) 

2 继承自ViewGroup的子类

不但需要重写onMeasure测量自己,还要测量子控件的规格大小。
				可以直接使用ViewGroup的工具方法来测量里面的子控件,也可以自己来实现这一套子控件的测量(比如:RelativeLayout)
					
				//1.测量自己的尺寸
						ViewGroup.onMeasure();
				//1.1 为每一个child计算测量规格信息(MeasureSpec)
						ViewGroup.getChildMeasureSpec();
				//1.2 将上面测量后的结果,传给每一个子View,子view测量自己的尺寸
						child.measure();

				//1.3 子View测量完,ViewGroup就可以拿到这个子View的测量后的尺寸了
					child.getChildMeasuredSize();//child.getMeasuredWidth()和child.getMeasuredHeight()
				//1.4ViewGroup自己就可以根据自身的情况(Padding等等),来计算自己的尺寸
						ViewGroup.calculateSelfSize();
				//2.保存自己的尺寸
				ViewGroup.setMeasuredDimension(size);
				  ViewGroup中提供的Measure相关的api:
					measureChild
					measureChildren(所有)
					measureChildWithMargins
				    getChildMeasureSpec
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值