自定义View示例-04-02 仿MaterialEditText

1.效果图

edittext-01.gif

2.效果分析

2.1扩大EditText的上下范围
2.2添加透明、不透明效果、添加向上向下效果
2.3添加方法,使调用者可以在代码中或者布局文件中启用关闭float TextView功能

3.具体实现

3.1 扩大EditText上下范围
image.png
    public class cmMaterialEditTextView extends AppCompatEditText {
    
        private static final String TAG = cmMaterialEditTextView.class.getSimpleName();
    
        private static final float TEXT_SIZE = DpToPxUtil.dp2px(18);
        private static final float TEXT_MARGIN = DpToPxUtil.dp2px(8);
        private static final float TEXT_VERTRICAL_OFFSET = DpToPxUtil.dp2px(28);
        private static final float TEXT_HORIZONTAL_OFFSET = DpToPxUtil.dp2px(5);
        //画笔
        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
     
        {
            //设置Padding
            setPadding(getPaddingLeft(),(int) (getPaddingTop() + TEXT_SIZE + TEXT_MARGIN),getPaddingRight(),getPaddingBottom());
            mPaint.setTextSize(TEXT_SIZE);
        }
    
        public cmMaterialEditTextView(Context context) {
            super(context);
        }
    
        public cmMaterialEditTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public cmMaterialEditTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            canvas.drawText(getHint().toString(),TEXT_HORIZONTAL_OFFSET,TEXT_VERTRICAL_OFFSET,mPaint);
        }
    }
3.2 添加透明、不透明效果、添加向上向下效果
        boolean floatingLabelShown = false;
        float floatingLabelFraction;
    
        public float getFloatingLabelFraction() {
            return floatingLabelFraction;
        }
    
        public void setFloatingLabelFraction(float floatingLabelFraction) {
            this.floatingLabelFraction = floatingLabelFraction;
            invalidate();
        }
    
    
    addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
    
                    //隐藏
                    if(floatingLabelShown && TextUtils.isEmpty(s)){
                        ObjectAnimator animator1 = ObjectAnimator.ofFloat(cmMaterialEditTextView.this,"floatingLabelFraction",0);
                        animator1.start();
                        floatingLabelShown = false;
                    }else if(!floatingLabelShown && !TextUtils.isEmpty(s)){
                        ObjectAnimator animator2 = ObjectAnimator.ofFloat(cmMaterialEditTextView.this,"floatingLabelFraction",1);
                        animator2.start();
                        floatingLabelShown = true;
                    }
                }
    
                @Override
                public void afterTextChanged(Editable s) {
    
                }
            });
3.3添加方法,使调用者可以在代码中或者布局文件中启用关闭float TextView功能
    attrs文件中
        
        
            
        
    
    public class cmMaterialEditTextView extends AppCompatEditText {
    
        private static final String TAG = cmMaterialEditTextView.class.getSimpleName();
    
        private static final float TEXT_SIZE = DpToPxUtil.dp2px(18);
        private static final float TEXT_MARGIN = DpToPxUtil.dp2px(8);
        private static final float TEXT_VERTRICAL_OFFSET = DpToPxUtil.dp2px(28);
        private static final float TEXT_HORIZONTAL_OFFSET = DpToPxUtil.dp2px(5);
        private static final float TEXT_ANIMATION_OFFSET = DpToPxUtil.dp2px(28);
    
        ObjectAnimator animator;
    
        boolean floatingLabelShown = false;
        float floatingLabelFraction;
        public float getFloatingLabelFraction() {
            return floatingLabelFraction;
        }
        public void setFloatingLabelFraction(float floatingLabelFraction) {
            this.floatingLabelFraction = floatingLabelFraction;
            invalidate();
        }
    
        //画笔
        private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    
    
        //是否使用Floating Label
        boolean userFloatingLabel;
        Rect rectBackground = new Rect();
    
        public void setUserFloatingLabel(boolean userFloatingLabel){
            if(this.userFloatingLabel != userFloatingLabel){
                this.userFloatingLabel = userFloatingLabel;
                onUserFloationgLabel();
            }
        }
    
        private void onUserFloationgLabel(){
            getBackground().getPadding(rectBackground);
            if(userFloatingLabel){
                setPadding(rectBackground.left,(int) (rectBackground.top + TEXT_SIZE + TEXT_MARGIN),rectBackground.right,rectBackground.bottom);
            }else{
                setPadding(rectBackground.left,rectBackground.top,rectBackground.right,rectBackground.bottom);
            }
        }
    
        private ObjectAnimator getAnimator() {
            if(animator == null){
                animator = ObjectAnimator.ofFloat(cmMaterialEditTextView.this,"floatingLabelFraction",0,1);
            }
            return animator;
        }
    
        public cmMaterialEditTextView(Context context) {
            super(context);
        }
    
        public cmMaterialEditTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
    
            initMaterialEditTextView(context,attrs);
        }
    
        public cmMaterialEditTextView(Context context, AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
        }
    
        private void initMaterialEditTextView(Context context, AttributeSet attrs) {
    
            TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.cmMaterialEditTextView);
            userFloatingLabel = typedArray.getBoolean(R.styleable.cmMaterialEditTextView_cmMaterialEditTextViewUserFloating,true);
            typedArray.recycle();
    
            mPaint.setTextSize(TEXT_SIZE);
    
            //设置Padding
            onUserFloationgLabel();
    
            addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
    
                    if(userFloatingLabel){
                        //隐藏
                        if(floatingLabelShown && TextUtils.isEmpty(s)){
                            getAnimator().reverse();
                            floatingLabelShown = false;
                        }else if(!floatingLabelShown && !TextUtils.isEmpty(s)){
                            getAnimator().start();
                            floatingLabelShown = true;
                        }
                    }
                }
    
                @Override
                public void afterTextChanged(Editable s) {
    
                }
            });
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
    
            mPaint.setAlpha((int) (0xff * floatingLabelFraction));
            float extraOffset = TEXT_ANIMATION_OFFSET * (1 - floatingLabelFraction);
            canvas.drawText(getHint().toString(),TEXT_HORIZONTAL_OFFSET,TEXT_VERTRICAL_OFFSET + extraOffset,mPaint);
        }
    }

Demo:CMViewDemo Github地址

你可能感兴趣的:(自定义View示例-04-02 仿MaterialEditText)