当前位置: 首页 > news >正文

湛江模板建站系统怎么免费创建自己的网站

湛江模板建站系统,怎么免费创建自己的网站,wordpress 时间设置,重大军事新闻视频Android控件的Outline效果的实现方式有很多种,这里介绍一下另一种使用Canvas.drawPath()方法来绘制控件轮廓Path路径的实现方案(API28及以上)。 实现效果: 属性 添加Outline相关属性,主要包括颜色和Stroke宽度&…

Android控件的Outline效果的实现方式有很多种,这里介绍一下另一种使用Canvas.drawPath()方法来绘制控件轮廓Path路径的实现方案(API28及以上)。

实现效果:
在这里插入图片描述

属性

添加Outline相关属性,主要包括颜色和Stroke宽度:

<declare-styleable name="shape_button">...<attr name="carbon_stroke" /><attr name="carbon_strokeWidth" />
</declare-styleable>

StrokeView接口

创建一个StrokeView通用接口:

/*** 外部轮廓相关*/
public interface StrokeView {ColorStateList getStroke();void setStroke(ColorStateList color);void setStroke(int color);float getStrokeWidth();void setStrokeWidth(float strokeWidth);
}

ShapeButton 实现这个StrokeView接口:

public class ShapeButton extends AppCompatButtonimplements ShadowView,ShapeModelView,RippleView,StrokeView {public ShapeButton(@NonNull Context context) {super(context);initButton(null, android.R.attr.buttonStyle, R.style.carbon_Button);}public ShapeButton(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);initButton(attrs, android.R.attr.buttonStyle, R.style.carbon_Button);}public ShapeButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initButton(attrs, defStyleAttr, R.style.carbon_Button);}public ShapeButton(Context context, String text, OnClickListener listener) {super(context);initButton(null, android.R.attr.buttonStyle, R.style.carbon_Button);setText(text);setOnClickListener(listener);}private static int[] elevationIds = new int[]{R.styleable.shape_button_carbon_elevation,R.styleable.shape_button_carbon_elevationShadowColor,R.styleable.shape_button_carbon_elevationAmbientShadowColor,R.styleable.shape_button_carbon_elevationSpotShadowColor};private static int[] cornerCutRadiusIds = new int[]{R.styleable.shape_button_carbon_cornerRadiusTopStart,R.styleable.shape_button_carbon_cornerRadiusTopEnd,R.styleable.shape_button_carbon_cornerRadiusBottomStart,R.styleable.shape_button_carbon_cornerRadiusBottomEnd,R.styleable.shape_button_carbon_cornerRadius,R.styleable.shape_button_carbon_cornerCutTopStart,R.styleable.shape_button_carbon_cornerCutTopEnd,R.styleable.shape_button_carbon_cornerCutBottomStart,R.styleable.shape_button_carbon_cornerCutBottomEnd,R.styleable.shape_button_carbon_cornerCut};private static int[] rippleIds = new int[]{R.styleable.shape_button_carbon_rippleColor,R.styleable.shape_button_carbon_rippleStyle,R.styleable.shape_button_carbon_rippleHotspot,R.styleable.shape_button_carbon_rippleRadius};private static int[] strokeIds = new int[]{R.styleable.shape_button_carbon_stroke,R.styleable.shape_button_carbon_strokeWidth};protected TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);private void initButton(AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.shape_button, defStyleAttr, defStyleRes);Carbon.initElevation(this, a, elevationIds);Carbon.initCornerCutRadius(this,a,cornerCutRadiusIds);Carbon.initRippleDrawable(this,a,rippleIds);// 初始化Stroke相关属性Carbon.initStroke(this,a,strokeIds);a.recycle();}// -------------------------------// shadow// -------------------------------// -------------------------------// shape// -------------------------------// -------------------------------// ripple// -------------------------------// -------------------------------// stroke// -------------------------------private ColorStateList stroke;private float strokeWidth;private Paint strokePaint;// 绘制轮廓private void drawStroke(Canvas canvas) {strokePaint.setStrokeWidth(strokeWidth * 2);strokePaint.setColor(stroke.getColorForState(getDrawableState(), stroke.getDefaultColor()));// cornersMask这是之前装载控件轮廓的path对象cornersMask.setFillType(Path.FillType.WINDING);canvas.drawPath(cornersMask, strokePaint);}// 设置轮廓颜色@Overridepublic void setStroke(ColorStateList colorStateList) {stroke = colorStateList;if (stroke == null)return;if (strokePaint == null) {strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);strokePaint.setStyle(Paint.Style.STROKE);}}// 设置轮廓颜色@Overridepublic void setStroke(int color) {setStroke(ColorStateList.valueOf(color));}@Overridepublic ColorStateList getStroke() {return stroke;}// 设置轮廓线条宽度@Overridepublic void setStrokeWidth(float strokeWidth) {this.strokeWidth = strokeWidth;}@Overridepublic float getStrokeWidth() {return strokeWidth;}}

初始化Stroke属性

    public static void initStroke(StrokeView strokeView, TypedArray a, int[] ids) {int carbon_stroke = ids[0];int carbon_strokeWidth = ids[1];View view = (View) strokeView;ColorStateList color =  a.getColorStateList(carbon_stroke);if (color != null)strokeView.setStroke(color);strokeView.setStrokeWidth(a.getDimension(carbon_strokeWidth, 0));}

绘制轮廓

onDraw()方法的super.draw(canvas);后面执行drawStroke()方法:

public void drawInternal(@NonNull Canvas canvas) {super.draw(canvas);if(stroke!=null){drawStroke(canvas);}}

如何使用

<com.chinatsp.demo1.shadow.ShapeButtonandroid:id="@+id/show_dialog_btn"android:layout_width="wrap_content"android:layout_height="36dp"android:layout_margin="@dimen/carbon_padding"android:background="#ffffff"android:stateListAnimator="@null"android:text="TOM"app:carbon_cornerCut="4dp"app:carbon_elevation="30dp"app:carbon_elevationShadowColor="#40ff0000"app:carbon_rippleColor="#40ff0000"app:carbon_rippleStyle="borderless"app:carbon_rippleRadius="30dp"app:carbon_stroke="@color/carbon_green_400"app:carbon_strokeWidth="1dp"/>

完整代码:

public class ShapeButton extends AppCompatButtonimplements ShadowView,ShapeModelView,RippleView,StrokeView {public ShapeButton(@NonNull Context context) {super(context);initButton(null, android.R.attr.buttonStyle, R.style.carbon_Button);}public ShapeButton(@NonNull Context context, @Nullable AttributeSet attrs) {super(context, attrs);initButton(attrs, android.R.attr.buttonStyle, R.style.carbon_Button);}public ShapeButton(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);initButton(attrs, defStyleAttr, R.style.carbon_Button);}public ShapeButton(Context context, String text, OnClickListener listener) {super(context);initButton(null, android.R.attr.buttonStyle, R.style.carbon_Button);setText(text);setOnClickListener(listener);}private static int[] elevationIds = new int[]{R.styleable.shape_button_carbon_elevation,R.styleable.shape_button_carbon_elevationShadowColor,R.styleable.shape_button_carbon_elevationAmbientShadowColor,R.styleable.shape_button_carbon_elevationSpotShadowColor};private static int[] cornerCutRadiusIds = new int[]{R.styleable.shape_button_carbon_cornerRadiusTopStart,R.styleable.shape_button_carbon_cornerRadiusTopEnd,R.styleable.shape_button_carbon_cornerRadiusBottomStart,R.styleable.shape_button_carbon_cornerRadiusBottomEnd,R.styleable.shape_button_carbon_cornerRadius,R.styleable.shape_button_carbon_cornerCutTopStart,R.styleable.shape_button_carbon_cornerCutTopEnd,R.styleable.shape_button_carbon_cornerCutBottomStart,R.styleable.shape_button_carbon_cornerCutBottomEnd,R.styleable.shape_button_carbon_cornerCut};private static int[] rippleIds = new int[]{R.styleable.shape_button_carbon_rippleColor,R.styleable.shape_button_carbon_rippleStyle,R.styleable.shape_button_carbon_rippleHotspot,R.styleable.shape_button_carbon_rippleRadius};private static int[] strokeIds = new int[]{R.styleable.shape_button_carbon_stroke,R.styleable.shape_button_carbon_strokeWidth};protected TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);private void initButton(AttributeSet attrs, @AttrRes int defStyleAttr, @StyleRes int defStyleRes) {TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.shape_button, defStyleAttr, defStyleRes);Carbon.initElevation(this, a, elevationIds);Carbon.initCornerCutRadius(this,a,cornerCutRadiusIds);Carbon.initRippleDrawable(this,a,rippleIds);Carbon.initStroke(this,a,strokeIds);a.recycle();}// -------------------------------// shadow// -------------------------------private float elevation = 0;private float translationZ = 0;private ColorStateList ambientShadowColor, spotShadowColor;@Overridepublic float getElevation() {return elevation;}@Overridepublic void setElevation(float elevation) {if (Carbon.IS_PIE_OR_HIGHER) {super.setElevation(elevation);super.setTranslationZ(translationZ);} else if (Carbon.IS_LOLLIPOP_OR_HIGHER) {if (ambientShadowColor == null || spotShadowColor == null) {super.setElevation(elevation);super.setTranslationZ(translationZ);} else {super.setElevation(0);super.setTranslationZ(0);}} else if (elevation != this.elevation && getParent() != null) {((View) getParent()).postInvalidate();}this.elevation = elevation;}@Overridepublic float getTranslationZ() {return translationZ;}public void setTranslationZ(float translationZ) {if (translationZ == this.translationZ)return;if (Carbon.IS_PIE_OR_HIGHER) {super.setTranslationZ(translationZ);} else if (Carbon.IS_LOLLIPOP_OR_HIGHER) {if (ambientShadowColor == null || spotShadowColor == null) {super.setTranslationZ(translationZ);} else {super.setTranslationZ(0);}} else if (translationZ != this.translationZ && getParent() != null) {((View) getParent()).postInvalidate();}this.translationZ = translationZ;}@Overridepublic ColorStateList getElevationShadowColor() {return ambientShadowColor;}@Overridepublic void setElevationShadowColor(ColorStateList shadowColor) {ambientShadowColor = spotShadowColor = shadowColor;setElevation(elevation);setTranslationZ(translationZ);}@Overridepublic void setElevationShadowColor(int color) {ambientShadowColor = spotShadowColor = ColorStateList.valueOf(color);setElevation(elevation);setTranslationZ(translationZ);}@Overridepublic void setOutlineAmbientShadowColor(ColorStateList color) {ambientShadowColor = color;if (Carbon.IS_PIE_OR_HIGHER) {super.setOutlineAmbientShadowColor(color.getColorForState(getDrawableState(), color.getDefaultColor()));} else {setElevation(elevation);setTranslationZ(translationZ);}}@Overridepublic void setOutlineAmbientShadowColor(int color) {setOutlineAmbientShadowColor(ColorStateList.valueOf(color));}@Overridepublic int getOutlineAmbientShadowColor() {return ambientShadowColor.getDefaultColor();}@Overridepublic void setOutlineSpotShadowColor(int color) {setOutlineSpotShadowColor(ColorStateList.valueOf(color));}@Overridepublic void setOutlineSpotShadowColor(ColorStateList color) {spotShadowColor = color;if (Carbon.IS_PIE_OR_HIGHER) {super.setOutlineSpotShadowColor(color.getColorForState(getDrawableState(), color.getDefaultColor()));} else {setElevation(elevation);setTranslationZ(translationZ);}}@Overridepublic int getOutlineSpotShadowColor() {return ambientShadowColor.getDefaultColor();}@Overridepublic boolean hasShadow() {return false;}@Overridepublic void drawShadow(Canvas canvas) {}@Overridepublic void draw(Canvas canvas) {boolean c = !Carbon.isShapeRect(shapeModel, boundsRect);if (Carbon.IS_PIE_OR_HIGHER) {if (spotShadowColor != null)super.setOutlineSpotShadowColor(spotShadowColor.getColorForState(getDrawableState(), spotShadowColor.getDefaultColor()));if (ambientShadowColor != null)super.setOutlineAmbientShadowColor(ambientShadowColor.getColorForState(getDrawableState(), ambientShadowColor.getDefaultColor()));}// 判断如果不是圆角矩形,需要使用轮廓Path,绘制一下Path,不然显示会很奇怪if (getWidth() > 0 && getHeight() > 0 && ((c && !Carbon.IS_LOLLIPOP_OR_HIGHER) || !shapeModel.isRoundRect(boundsRect))) {int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);drawInternal(canvas);paint.setXfermode(Carbon.CLEAR_MODE);if (c) {cornersMask.setFillType(Path.FillType.INVERSE_WINDING);canvas.drawPath(cornersMask, paint);}canvas.restoreToCount(saveCount);paint.setXfermode(null);}else{drawInternal(canvas);}}public void drawInternal(@NonNull Canvas canvas) {super.draw(canvas);if(stroke!=null){drawStroke(canvas);}if (rippleDrawable != null && rippleDrawable.getStyle() == RippleDrawable.Style.Over)rippleDrawable.draw(canvas);}// -------------------------------// shape// -------------------------------private ShapeAppearanceModel shapeModel = new ShapeAppearanceModel();private MaterialShapeDrawable shadowDrawable = new MaterialShapeDrawable(shapeModel);@Overridepublic void setShapeModel(ShapeAppearanceModel shapeModel) {this.shapeModel = shapeModel;shadowDrawable = new MaterialShapeDrawable(shapeModel);if (getWidth() > 0 && getHeight() > 0)updateCorners();if (!Carbon.IS_LOLLIPOP_OR_HIGHER)postInvalidate();}// View的轮廓形状private RectF boundsRect = new RectF();// View的轮廓形状形成的Path路径private Path cornersMask = new Path();/*** 更新圆角*/private void updateCorners() {if (Carbon.IS_LOLLIPOP_OR_HIGHER) {// 如果不是矩形,裁剪View的轮廓if (!Carbon.isShapeRect(shapeModel, boundsRect)){setClipToOutline(true);}//该方法返回一个Outline对象,它描述了该视图的形状。setOutlineProvider(new ViewOutlineProvider() {@Overridepublic void getOutline(View view, Outline outline) {if (Carbon.isShapeRect(shapeModel, boundsRect)) {outline.setRect(0, 0, getWidth(), getHeight());} else {shadowDrawable.setBounds(0, 0, getWidth(), getHeight());shadowDrawable.setShadowCompatibilityMode(MaterialShapeDrawable.SHADOW_COMPAT_MODE_NEVER);shadowDrawable.getOutline(outline);}}});}// 拿到圆角矩形的形状boundsRect.set(shadowDrawable.getBounds());// 拿到圆角矩形的PathshadowDrawable.getPathForSize(getWidth(), getHeight(), cornersMask);}@Overridepublic ShapeAppearanceModel getShapeModel() {return this.shapeModel;}@Overridepublic void setCornerCut(float cornerCut) {shapeModel = ShapeAppearanceModel.builder().setAllCorners(new CutCornerTreatment(cornerCut)).build();setShapeModel(shapeModel);}@Overridepublic void setCornerRadius(float cornerRadius) {shapeModel = ShapeAppearanceModel.builder().setAllCorners(new RoundedCornerTreatment(cornerRadius)).build();setShapeModel(shapeModel);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);if (!changed)return;if (getWidth() == 0 || getHeight() == 0)return;updateCorners();if (rippleDrawable != null)rippleDrawable.setBounds(0, 0, getWidth(), getHeight());}// -------------------------------// ripple// -------------------------------private RippleDrawable rippleDrawable;@Overridepublic boolean dispatchTouchEvent(@NonNull MotionEvent event) {if (rippleDrawable != null && event.getAction() == MotionEvent.ACTION_DOWN)rippleDrawable.setHotspot(event.getX(),event.getY());return super.dispatchTouchEvent(event);}@Overridepublic RippleDrawable getRippleDrawable() {return rippleDrawable;}@Overridepublic void setRippleDrawable(RippleDrawable newRipple) {if (rippleDrawable != null) {rippleDrawable.setCallback(null);if (rippleDrawable.getStyle() == RippleDrawable.Style.Background)super.setBackgroundDrawable(rippleDrawable.getBackground());}if (newRipple != null) {newRipple.setCallback(this);newRipple.setBounds(0, 0, getWidth(), getHeight());newRipple.setState(getDrawableState());((Drawable) newRipple).setVisible(getVisibility() == VISIBLE, false);if (newRipple.getStyle() == RippleDrawable.Style.Background)super.setBackgroundDrawable((Drawable) newRipple);}rippleDrawable = newRipple;}@Overrideprotected void drawableStateChanged() {super.drawableStateChanged();if (rippleDrawable != null && rippleDrawable.getStyle() != RippleDrawable.Style.Background)rippleDrawable.setState(getDrawableState());}@Overrideprotected boolean verifyDrawable(@NonNull Drawable who) {return super.verifyDrawable(who) || rippleDrawable == who;}@Overridepublic void invalidateDrawable(@NonNull Drawable drawable) {super.invalidateDrawable(drawable);invalidateParentIfNeeded();}@Overridepublic void invalidate(@NonNull Rect dirty) {super.invalidate(dirty);invalidateParentIfNeeded();}@Overridepublic void invalidate(int l, int t, int r, int b) {super.invalidate(l, t, r, b);invalidateParentIfNeeded();}@Overridepublic void invalidate() {super.invalidate();invalidateParentIfNeeded();}private void invalidateParentIfNeeded() {if (getParent() == null || !(getParent() instanceof View))return;if (rippleDrawable != null && rippleDrawable.getStyle() == RippleDrawable.Style.Borderless)((View) getParent()).invalidate();}@Overridepublic void setBackground(Drawable background) {setBackgroundDrawable(background);}@Overridepublic void setBackgroundDrawable(Drawable background) {if (background instanceof RippleDrawable) {setRippleDrawable((RippleDrawable) background);return;}if (rippleDrawable != null && rippleDrawable.getStyle() == RippleDrawable.Style.Background) {rippleDrawable.setCallback(null);rippleDrawable = null;}super.setBackgroundDrawable(background);}// -------------------------------// stroke// -------------------------------private ColorStateList stroke;private float strokeWidth;private Paint strokePaint;private void drawStroke(Canvas canvas) {strokePaint.setStrokeWidth(strokeWidth * 2);strokePaint.setColor(stroke.getColorForState(getDrawableState(), stroke.getDefaultColor()));cornersMask.setFillType(Path.FillType.WINDING);canvas.drawPath(cornersMask, strokePaint);}@Overridepublic void setStroke(ColorStateList colorStateList) {stroke = colorStateList;if (stroke == null)return;if (strokePaint == null) {strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG);strokePaint.setStyle(Paint.Style.STROKE);}}@Overridepublic void setStroke(int color) {setStroke(ColorStateList.valueOf(color));}@Overridepublic ColorStateList getStroke() {return stroke;}@Overridepublic void setStrokeWidth(float strokeWidth) {this.strokeWidth = strokeWidth;}@Overridepublic float getStrokeWidth() {return strokeWidth;}}
http://www.15wanjia.com/news/57214.html

相关文章:

  • 天津 网站建设百度指数有哪些功能
  • b2b网站分析google优化排名
  • 今日军事新闻内容摘抄seo1现在怎么看不了
  • 教育网站赏析seo关键词查询工具
  • 如何维护给做网站的客户地推app推广赚佣金
  • 做amazon当地电信屏蔽了网站seo公司优化方案
  • 网站开发文件综述2022推广app赚佣金平台
  • 三河市城乡建设局网站东莞网络营销信息推荐
  • 宝安最好的网站建设seo网站推广方案
  • 有自己域名的个人网站软文自动发布软件
  • 爱站网自媒体免费网站制作成品
  • 东莞浩智专业网站建设哪家好vivo应用商店
  • 小程序商城代码宁阳网站seo推广
  • 广州网站建设出售网络营销产品概念
  • 南京网站建设哪家专业专业seo关键词优化
  • 建设银行不弹出网站海淀seo搜索优化多少钱
  • 建网站多少艾瑞指数
  • 怎么做网站规划windows优化大师好吗
  • 用jsp做的网站源代码seo搜索推广
  • 在哪个网站做淘宝水印成都新一轮疫情
  • 网站建设制作深圳网络游戏推广员的真实经历
  • 自助建站优化排名杭州seo联盟
  • 响应式英文网站建设郑州seo排名第一
  • 官网建设需求产品seo是什么意思
  • 网站确定关键词 如何做qq群排名优化软件
  • 台州外贸网站建设印度疫情最新消息
  • 北京西站企业网站cms
  • 惠城网站建设有哪些旅行网站排名
  • 自己做网站语言包怎么做a5站长网
  • 做设计用图片的网站百度域名提交收录网址