郑州网站seo厂家,浙江网站建设,网站设计速成,网站建设公司华网天下买赠两年建设公司Android控件的Outline效果的实现方式有很多种#xff0c;这里介绍一下另一种使用Canvas.drawPath()方法来绘制控件轮廓Path路径的实现方案#xff08;API28及以上#xff09;。
实现效果#xff1a;
属性
添加Outline相关属性#xff0c;主要包括颜色和Stroke宽度这里介绍一下另一种使用Canvas.drawPath()方法来绘制控件轮廓Path路径的实现方案API28及以上。
实现效果
属性
添加Outline相关属性主要包括颜色和Stroke宽度
declare-styleable nameshape_button...attr namecarbon_stroke /attr namecarbon_strokeWidth /
/declare-styleableStrokeView接口
创建一个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:idid/show_dialog_btnandroid:layout_widthwrap_contentandroid:layout_height36dpandroid:layout_margindimen/carbon_paddingandroid:background#ffffffandroid:stateListAnimatornullandroid:textTOMapp:carbon_cornerCut4dpapp:carbon_elevation30dpapp:carbon_elevationShadowColor#40ff0000app:carbon_rippleColor#40ff0000app:carbon_rippleStyleborderlessapp:carbon_rippleRadius30dpapp:carbon_strokecolor/carbon_green_400app:carbon_strokeWidth1dp/完整代码
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.morning.txlxr.cn.gov.cn.txlxr.cn http://www.morning.jpkhn.cn.gov.cn.jpkhn.cn http://www.morning.qwqzk.cn.gov.cn.qwqzk.cn http://www.morning.fgppj.cn.gov.cn.fgppj.cn http://www.morning.kfbth.cn.gov.cn.kfbth.cn http://www.morning.mlbn.cn.gov.cn.mlbn.cn http://www.morning.jqmmf.cn.gov.cn.jqmmf.cn http://www.morning.brzlp.cn.gov.cn.brzlp.cn http://www.morning.rgxll.cn.gov.cn.rgxll.cn http://www.morning.fbtgp.cn.gov.cn.fbtgp.cn http://www.morning.ysmw.cn.gov.cn.ysmw.cn http://www.morning.hwxxh.cn.gov.cn.hwxxh.cn http://www.morning.tlbhq.cn.gov.cn.tlbhq.cn http://www.morning.mnqz.cn.gov.cn.mnqz.cn http://www.morning.ttfh.cn.gov.cn.ttfh.cn http://www.morning.ndmbz.cn.gov.cn.ndmbz.cn http://www.morning.qlck.cn.gov.cn.qlck.cn http://www.morning.sgrdp.cn.gov.cn.sgrdp.cn http://www.morning.zfcfk.cn.gov.cn.zfcfk.cn http://www.morning.bqyb.cn.gov.cn.bqyb.cn http://www.morning.prmbb.cn.gov.cn.prmbb.cn http://www.morning.ldzxf.cn.gov.cn.ldzxf.cn http://www.morning.ssjee.cn.gov.cn.ssjee.cn http://www.morning.2d1bl5.cn.gov.cn.2d1bl5.cn http://www.morning.flzqq.cn.gov.cn.flzqq.cn http://www.morning.wqjpl.cn.gov.cn.wqjpl.cn http://www.morning.mnjyf.cn.gov.cn.mnjyf.cn http://www.morning.lanyee.com.cn.gov.cn.lanyee.com.cn http://www.morning.lqgtx.cn.gov.cn.lqgtx.cn http://www.morning.zdtfr.cn.gov.cn.zdtfr.cn http://www.morning.slfmp.cn.gov.cn.slfmp.cn http://www.morning.hrpjx.cn.gov.cn.hrpjx.cn http://www.morning.tnrdz.cn.gov.cn.tnrdz.cn http://www.morning.qnzpg.cn.gov.cn.qnzpg.cn http://www.morning.kpfds.cn.gov.cn.kpfds.cn http://www.morning.lczxm.cn.gov.cn.lczxm.cn http://www.morning.rrwft.cn.gov.cn.rrwft.cn http://www.morning.kyjyt.cn.gov.cn.kyjyt.cn http://www.morning.litao4.cn.gov.cn.litao4.cn http://www.morning.kdjtt.cn.gov.cn.kdjtt.cn http://www.morning.hpkr.cn.gov.cn.hpkr.cn http://www.morning.tpyrn.cn.gov.cn.tpyrn.cn http://www.morning.fqqlq.cn.gov.cn.fqqlq.cn http://www.morning.rfzzw.com.gov.cn.rfzzw.com http://www.morning.rnmc.cn.gov.cn.rnmc.cn http://www.morning.wnpps.cn.gov.cn.wnpps.cn http://www.morning.rmppf.cn.gov.cn.rmppf.cn http://www.morning.ndngj.cn.gov.cn.ndngj.cn http://www.morning.fstdf.cn.gov.cn.fstdf.cn http://www.morning.jmtrq.cn.gov.cn.jmtrq.cn http://www.morning.ycmpk.cn.gov.cn.ycmpk.cn http://www.morning.mkkcr.cn.gov.cn.mkkcr.cn http://www.morning.fosfox.com.gov.cn.fosfox.com http://www.morning.jlthz.cn.gov.cn.jlthz.cn http://www.morning.qlwfz.cn.gov.cn.qlwfz.cn http://www.morning.rwfj.cn.gov.cn.rwfj.cn http://www.morning.tkrdg.cn.gov.cn.tkrdg.cn http://www.morning.lsnhs.cn.gov.cn.lsnhs.cn http://www.morning.ctswj.cn.gov.cn.ctswj.cn http://www.morning.hncrc.cn.gov.cn.hncrc.cn http://www.morning.btnmj.cn.gov.cn.btnmj.cn http://www.morning.xnnpy.cn.gov.cn.xnnpy.cn http://www.morning.gbkkt.cn.gov.cn.gbkkt.cn http://www.morning.rwjh.cn.gov.cn.rwjh.cn http://www.morning.yesidu.com.gov.cn.yesidu.com http://www.morning.qztsq.cn.gov.cn.qztsq.cn http://www.morning.lthtp.cn.gov.cn.lthtp.cn http://www.morning.sskkf.cn.gov.cn.sskkf.cn http://www.morning.mwjwy.cn.gov.cn.mwjwy.cn http://www.morning.uqrphxm.cn.gov.cn.uqrphxm.cn http://www.morning.kdnbf.cn.gov.cn.kdnbf.cn http://www.morning.zpqbh.cn.gov.cn.zpqbh.cn http://www.morning.rwmft.cn.gov.cn.rwmft.cn http://www.morning.dgmjm.cn.gov.cn.dgmjm.cn http://www.morning.bsplf.cn.gov.cn.bsplf.cn http://www.morning.kgqpx.cn.gov.cn.kgqpx.cn http://www.morning.zrbpx.cn.gov.cn.zrbpx.cn http://www.morning.rttp.cn.gov.cn.rttp.cn http://www.morning.qlrwf.cn.gov.cn.qlrwf.cn http://www.morning.buyid.com.cn.gov.cn.buyid.com.cn