Android 自定义控件: 圆形、圆角、边框、渐变、下拉关闭、

2019-07-18  本文已影响0人  Enowr

效果图

WechatIMG24.png

源码

简单使用

  1. gradle 集成
api 'com.enowr.android:Widgets:0.0.8'
  1. 相关属性
        <attr name="vh_isAreaClick" format="boolean" />                                     <!--是否区域内可点击,默认 false-->
        <attr name="vh_isAreaPadding" format="boolean" />                                   <!--是否区域包含padding值,默认 true-->
        <attr name="vh_isDropdownClose" format="boolean" />                                 <!-- 是否开启滑动关闭,ViewGroup中使用,默认 false -->

        <!--圆形、圆角-->
        <attr name="vh_isCircle" format="boolean" />                                        <!--是否是圆形-->
        <attr name="vh_cornersRadius" format="dimension" />                                 <!--四周圆角角度-->
        <attr name="vh_cornersRadiusTopLeft" format="dimension" />                          <!--四周圆角角度 左上-->
        <attr name="vh_cornersRadiusTopRight" format="dimension" />                         <!--四周圆角角度 右上-->
        <attr name="vh_cornersRadiusBottomLeft" format="dimension" />                       <!--四周圆角角度 左下-->
        <attr name="vh_cornersRadiusBottomRight" format="dimension" />                      <!--四周圆角角度 右下-->

        <!--文本颜色-->
        <attr name="vh_textColor" format="color" />
        <attr name="vh_textColorNormal" format="color" />
        <attr name="vh_textColorPressed" format="color" />
        <attr name="vh_textColorUnable" format="color" />
        <attr name="vh_textColorChecked" format="color" />

        <!--前景-->
        <attr name="vh_prospectColor" format="color" />                                     <!--前景颜色-->
        <attr name="vh_prospectColorNormal" format="color" />
        <attr name="vh_prospectColorPressed" format="color" />
        <attr name="vh_prospectColorChecked" format="color" />
        <attr name="vh_prospectColorUnable" format="color" />

        <attr name="vh_prospectDrawable" format="reference" />                              <!--前景图片-->
        <attr name="vh_prospectDrawableNormal" format="reference" />
        <attr name="vh_prospectDrawablePressed" format="reference" />
        <attr name="vh_prospectDrawableChecked" format="reference" />
        <attr name="vh_prospectDrawableUnable" format="reference" />

        <!--背景-->
        <attr name="vh_backgroundColor" format="color" />                                   <!--背景颜色 会被系统背景覆盖-->
        <attr name="vh_backgroundColorNormal" format="color" />
        <attr name="vh_backgroundColorPressed" format="color" />
        <attr name="vh_backgroundColorChecked" format="color" />
        <attr name="vh_backgroundColorUnable" format="color" />

        <attr name="vh_backgroundDrawable" format="reference" />                            <!--背景图片 会被系统背景覆盖-->
        <attr name="vh_backgroundDrawableNormal" format="reference" />
        <attr name="vh_backgroundDrawablePressed" format="reference" />
        <attr name="vh_backgroundDrawableChecked" format="reference" />
        <attr name="vh_backgroundDrawableUnable" format="reference" />

        <!--边框-->
        <attr name="vh_borderColor" format="color" />                                       <!--边框颜色-->
        <attr name="vh_borderColorNormal" format="color" />
        <attr name="vh_borderColorPressed" format="color" />
        <attr name="vh_borderColorChecked" format="color" />
        <attr name="vh_borderColorUnable" format="color" />

        <attr name="vh_borderWidth" format="dimension" />                                   <!--边框宽度-->
        <attr name="vh_borderWidthNormal" format="dimension" />
        <attr name="vh_borderWidthPressed" format="dimension" />
        <attr name="vh_borderWidthChecked" format="dimension" />
        <attr name="vh_borderWidthUnable" format="dimension" />

        <attr name="vh_borderDashArray" format="reference" />                               <!--虚线间距数组,最少两个-->
        <attr name="vh_borderDashWidth" format="dimension" />                               <!--虚线边框宽度-->
        <attr name="vh_borderDashGap" format="dimension" />                                 <!--虚线边框间隔-->

        <!--颜色渐变 Gradient 相关,在背景色绘制之后-->
        <attr name="vh_gradientColorStart" format="color" />                                <!--渐变颜色开始-->
        <attr name="vh_gradientColorStartNormal" format="color" />
        <attr name="vh_gradientColorStartPressed" format="color" />
        <attr name="vh_gradientColorStartChecked" format="color" />
        <attr name="vh_gradientColorStartUnable" format="color" />
        <attr name="vh_gradientColorCenter" format="color" />                               <!--渐变颜色中间-->
        <attr name="vh_gradientColorCenterNormal" format="color" />
        <attr name="vh_gradientColorCenterPressed" format="color" />
        <attr name="vh_gradientColorCenterChecked" format="color" />
        <attr name="vh_gradientColorCenterUnable" format="color" />
        <attr name="vh_gradientColorEnd" format="color" />                                  <!--渐变颜色结束-->
        <attr name="vh_gradientColorEndNormal" format="color" />
        <attr name="vh_gradientColorEndPressed" format="color" />
        <attr name="vh_gradientColorEndChecked" format="color" />
        <attr name="vh_gradientColorEndUnable" format="color" />

        <attr name="vh_gradientColorArray" format="reference" />                            <!--渐变颜色数组,最少两个-->
        <attr name="vh_gradientColorArrayNormal" format="reference" />
        <attr name="vh_gradientColorArrayPressed" format="reference" />
        <attr name="vh_gradientColorArrayChecked" format="reference" />
        <attr name="vh_gradientColorArrayUnable" format="reference" />

        <attr name="vh_gradientColorPositionArray" format="reference" />                    <!--渐变颜色数组对应的位置数组,取值为0~1,若为null,颜色沿渐变线均匀分布,最少两个-->
        <attr name="vh_gradientColorPositionArrayNormal" format="reference" />
        <attr name="vh_gradientColorPositionArrayPressed" format="reference" />
        <attr name="vh_gradientColorPositionArrayChecked" format="reference" />
        <attr name="vh_gradientColorPositionArrayUnable" format="reference" />

        <attr name="vh_gradientType">                                                       <!--渐变类型-->
            <enum name="linear" value="0" />
            <enum name="radial" value="1" />
            <enum name="sweep" value="2" />
        </attr>
        <attr name="vh_gradientMode">                                                       <!--渐变模式,仅在 type=linear、radial 时适用-->
            <enum name="clamp" value="0"/>
            <enum name="repeat" value="1"/>
            <enum name="mirror" value="2"/>
        </attr>
        <attr name="vh_gradientAngle" format="float"/>                                      <!--渐变旋转角度,仅在 type=sweep、linear 时适用-->
        <attr name="vh_gradientRadius" format="dimension" />                                <!--渐变半径,仅在 type=radial 时适用-->
        <attr name="vh_gradientCenterX" format="float" />                                   <!--渐变中心X,比例值范围 0.0 ~ 1.0,仅在 type=linear、radial 时适用-->
        <attr name="vh_gradientCenterY" format="float" />                                   <!--渐变中心Y,比例值范围 0.0 ~ 1.0,仅在 type=linear、radial 时适用-->

        <!--模糊背景-->
        <attr name="vh_blurScale" format="float" />                                         <!--模糊图片缩放比例,(0,1]-->
        <attr name="vh_blurRadius" format="dimension" />

        <!--阴影-->
        <attr name="vh_shadowColor" format="color" />
        <attr name="vh_shadowColorNormal" format="color" />
        <attr name="vh_shadowColorPressed" format="color" />
        <attr name="vh_shadowColorChecked" format="color" />
        <attr name="vh_shadowColorUnable" format="color" />
        <attr name="vh_shadowRadius" format="dimension" />
        <attr name="vh_shadowRadiusNormal" format="dimension" />
        <attr name="vh_shadowRadiusPressed" format="dimension" />
        <attr name="vh_shadowRadiusChecked" format="dimension" />
        <attr name="vh_shadowRadiusUnable" format="dimension" />
        <attr name="vh_shadowOffsetX" format="dimension" />
        <attr name="vh_shadowOffsetXNormal" format="dimension" />
        <attr name="vh_shadowOffsetXPressed" format="dimension" />
        <attr name="vh_shadowOffsetXChecked" format="dimension" />
        <attr name="vh_shadowOffsetXUnable" format="dimension" />
        <attr name="vh_shadowOffsetY" format="dimension" />
        <attr name="vh_shadowOffsetYNormal" format="dimension" />
        <attr name="vh_shadowOffsetYPressed" format="dimension" />
        <attr name="vh_shadowOffsetYChecked" format="dimension" />
        <attr name="vh_shadowOffsetYUnable" format="dimension" />
  1. 简单使用
      <com.enowr.widgets.extension.TextViewExtension
            android:id="@+id/view_1"
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:gravity="center"
            android:text="圆角 点击字体和背景变色"
            android:textSize="12sp"
            android:onClick="onClick"
            app:vh_cornersRadius="3dp"
            app:vh_textColor="@android:color/white"
            app:vh_textColorPressed="@android:color/black"
            app:vh_backgroundColor="@android:color/holo_orange_dark"
            app:vh_backgroundColorPressed="@android:color/holo_blue_dark"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    TextViewExtension tve = findViewById(R.id.view_1);
    tve.getHelper().setCornersRadius(10);
  1. 扩展 使用ViewHelper

View 中

public class TextViewExtension extends AppCompatTextView implements Checkable {
    private ViewHelper mHelper = new ViewHelper();

    public TextViewExtension(Context context) {
        super(context);
        mHelper.init(this);
    }

    public TextViewExtension(Context context, AttributeSet attrs) {
        super(context, attrs);
        mHelper.init(this, attrs);
    }

    public TextViewExtension(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mHelper.init(this, attrs, defStyleAttr);
    }

    public ViewHelper<FrameLayoutExtension> getHelper() {
        return mHelper;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mHelper.onAttachedToWindow(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mHelper.onDetachedFromWindow();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHelper.onSizeChanged(w, h);
    }

    @Override
    public void draw(Canvas canvas) {
        mHelper.saveLayer(canvas);
        super.draw(canvas);
    }

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

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return mHelper.dispatchTouchEvent(ev) && super.dispatchTouchEvent(ev);
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        mHelper.drawableStateChanged();
    }

    @Override
    public boolean isChecked() {
        return mHelper.isChecked();
    }

    @Override
    public void setChecked(boolean checked) {
        mHelper.setChecked(checked);
    }

    @Override
    public void toggle() {
        setChecked(!mHelper.isChecked());
    }
}

ViewGroup 中

public class FrameLayoutExtension extends FrameLayout implements Checkable {
    private ViewHelper<FrameLayoutExtension> mHelper = new ViewHelper<>();

    public FrameLayoutExtension(Context context) {
        super(context);
        mHelper.init(this);
    }

    public FrameLayoutExtension(Context context, AttributeSet attrs) {
        super(context, attrs);
        mHelper.init(this, attrs);
    }

    public FrameLayoutExtension(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mHelper.init(this, attrs, defStyleAttr);
    }

    public ViewHelper<FrameLayoutExtension> getHelper() {
        return mHelper;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mHelper.onAttachedToWindow(this);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mHelper.onDetachedFromWindow();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHelper.onSizeChanged(w, h);
    }

    @Override
    public void draw(Canvas canvas) {
        mHelper.saveLayer(canvas);
        super.draw(canvas);
    }

    @Override
    protected void dispatchDraw(Canvas canvas) {
        mHelper.trySaveLayer(canvas);
        super.dispatchDraw(canvas);
        mHelper.onClipDraw(canvas);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        return mHelper.dispatchTouchEvent(ev) && super.dispatchTouchEvent(ev);
    }

    @Override
    protected void drawableStateChanged() {
        super.drawableStateChanged();
        mHelper.drawableStateChanged();
    }

    @Override
    public boolean isChecked() {
        return mHelper.isChecked();
    }

    @Override
    public void setChecked(boolean checked) {
        mHelper.setChecked(checked);
    }

    @Override
    public void toggle() {
        setChecked(!mHelper.isChecked());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return mHelper.onInterceptTouchEvent(ev) || super.onInterceptTouchEvent(ev);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return mHelper.onTouchEvent(event) || super.onTouchEvent(event);
    }
}

说明

由于阴影和模糊的特殊性,单独将ViewHelper进行封装;
ViewHelper 支持:设置范围是否包含Padding,默认true;是否只有设置范围内点击生效,默认false;是否是圆形,默认false;圆角设置;文本颜色设置;背景颜色、图设置;前景颜色、图设置;渐变色设置;边框设置;同时这些属性可以设置不同状态的值(默认、按下、选中、不可点击);下拉关闭(用于ViewGroup,可实现微信朋友圈的图片查看器);

  1. 使用阴影将不支持:前景图、背景图、边框、下拉关闭;
  2. 使用模糊将不支持:前景、背景、渐变、边框、下拉关闭;
上一篇下一篇

猜你喜欢

热点阅读