android 自定义继承view

android自定义view:
 
参考:
 
https://www.cnblogs.com/yukino/p/4438919.html
https://www.cnblogs.com/itgungnir/p/6217447.html
 
1、实现一个柱状图的view
 
   错误:StackOverflowError: stack size 8MB
   b
   原因:onLayout()中使用了layout()
        onLayout()方法负责布局,大多数情况是在自定义ViewGroup中才会重写,主要用来确定子View在这个布局空间中的摆放位置
   eer
   解决:暂不处理,定位可以在使用自定义的view时调整,比如在xml布局里设置margin等
 
2、widthMeasureSpec, heightMeasureSpec这两个啥意思怎么用?
 
   参考:https://segmentfault.com/a/1190000007948959
 
3、view代码:
   /**
 * Created by baiyingbin on 2018/10/15.
 * function : 自定义柱状图,1、画出横竖轴标上刻度
 *              2、计算能画的柱状图个数和分割空柱
 *              3、标上不同的颜色和数值
 */
public class BarGraphView extends View {
 
    private Context mContext;
    private Canvas mCanvas = null;
    private ScreenUtil.ScreenBean mScreenBean = null;
    private Paint mPaint = null;
    private int margin = 100;
    private final int axisMargin = 20;//横竖轴距离背景margin
 
    public BarGraphView(Context context) {
        super(context);
        init(context);
    }
 
    public BarGraphView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }
 
    public BarGraphView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }
 
    /**
     * 初始化view和基本逻辑
     * @param context
     */
    private void init(Context context){
        mContext = context;
        mScreenBean = ScreenUtil.getInstance().getScreenWidth(mContext);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }
 
 
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        /**
         * 在setMeasuredDimension()方法调用之后,我们才能使用getMeasuredWidth()和
         * getMeasuredHeight()来获取视图测量出的宽高,以此之前调用这两个方法得到的值都会是0
         */
        int specModeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int specSizeWidth = MeasureSpec.getSize(widthMeasureSpec);//当前view存在的父view宽度1080
        int specModeHeight = MeasureSpec.getMode(heightMeasureSpec);
        int specSizeHeight = MeasureSpec.getSize(heightMeasureSpec);//当前view存在的父view高度1807
        setMeasuredDimension(mScreenBean.getWidth()-margin*2,mScreenBean.getHeight()/3);
    }
 
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        mScreenBean.setLeft(left);//100
        mScreenBean.setTop(top);//636
        mScreenBean.setRight(right);//980
        mScreenBean.setBottom(bottom);//1396
        super.onLayout(changed, left, top, right, bottom);
        //暂不处理,定位可以在使用自定义的view时调整,比如在xml布局里设置margin等
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mCanvas = canvas;
        initDrawView(canvas);//初始化横竖轴
        drawLineScale(canvas);//画刻度
 
        List<Integer> list = new ArrayList<>();
        list.add(30);
        list.add(50);
        list.add(70);
        list.add(93);
        list.add(50);
        list.add(100);
        list.add(45);
        drawValue(list);
    }
 
    /**
     * 提供画布对象
     */
    public Canvas getCanvas(){
        return  mCanvas;
    }
 
    /**
     * 画刻度
     */
    private void drawLineScale(Canvas canvas){
        int mainWidth = getWidth()-axisMargin;
        int height = getHeight() -  axisMargin*2;
        int scaleHeight = 5;
 
        //数轴分成一百份,展示数值
        for(int i=0;i<100;i++){
            int scaleUnit =height/100*i;
            canvas.drawPoint(axisMargin+scaleHeight,getHeight()-axisMargin-scaleUnit,mPaint);
        }
        //数轴分成十份,展示类型
        for(int i=0;i<20;i++){
            int scaleUnit =mainWidth/20*i;
            canvas.drawPoint(axisMargin+scaleUnit,getHeight()-axisMargin-scaleHeight,mPaint);
        }
    }
    /**
     * 画柱形图
     */
    private void drawValue(List<Integer> values){
        Canvas canvas = getCanvas();
        initDrawView(canvas);//初始化横竖轴
        drawLineScale(canvas);//画刻度
 
        int mainWidth = getWidth()-axisMargin;
        int height = getHeight() -  axisMargin*2;
 
        int validScale =(height-(height-height/100*100))/100;
        for(int i=0;i<values.size();i++){
            //数轴分成一百份,展示数值
            int scaleUnit =height-validScale*values.get(i);
            //数轴分成十份,展示类型
            int valueUnit =mainWidth/20;
            int unitPos = valueUnit*i;
            int unitPos1 = valueUnit*i;
            canvas.drawRect(axisMargin+unitPos+unitPos1,scaleUnit,axisMargin+unitPos+unitPos1+valueUnit,getHeight()-axisMargin,mPaint);
        }
    }
    /**
     * 初始化横竖轴
     * @param canvas
     */
    private void initDrawView(Canvas canvas){
        setBackgroundColor(mContext.getResources().getColor(R.color.colorAccent));
        mPaint.setColor(mContext.getResources().getColor(R.color.colorPrimary));
        mPaint.setStrokeWidth(5);
        //画横轴
        canvas.drawLine(axisMargin,getHeight()-axisMargin,getWidth()-axisMargin,getHeight()-axisMargin,mPaint);
        //画数轴
        canvas.drawLine(axisMargin,axisMargin,axisMargin,getHeight()-axisMargin,mPaint);
        //画箭头
        drawArrow(canvas);
        //写标志 白
        mPaint.setTextSize(20);
        canvas.drawText("白",0,getHeight()-axisMargin/3,mPaint);
    }
    /**
     * 画横竖轴箭头
     * @param canvas
     */
    private void drawArrow(Canvas canvas){
        Path verticalPath = new Path();
        verticalPath.moveTo(0, axisMargin);// 此点为多边形的起点
        verticalPath.lineTo(axisMargin*2, axisMargin);
        verticalPath.lineTo(axisMargin, 0);
        verticalPath.lineTo(0, axisMargin);
        verticalPath.close(); // 使这些点构成封闭的多边形
        canvas.drawPath(verticalPath,mPaint);
        Path horizontalPath = new Path();
        horizontalPath.moveTo(getWidth()-axisMargin, getHeight()-axisMargin*2);// 此点为多边形的起点
        horizontalPath.lineTo(getWidth()-axisMargin, getHeight());
        horizontalPath.lineTo(getWidth(), getHeight()-axisMargin);
        horizontalPath.lineTo(getWidth()-axisMargin, getHeight()-axisMargin*2);
        horizontalPath.close(); // 使这些点构成封闭的多边形
        canvas.drawPath(horizontalPath,mPaint);
    }
}
实现简单的view
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

漠天515

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值