android自定义view:
参考:
https://www.cnblogs.com/yukino/p/4438919.html
https://www.cnblogs.com/itgungnir/p/6217447.html
1、实现一个柱状图的view
错误:StackOverflowError: stack size 8MB
原因:onLayout()中使用了layout()
onLayout()方法负责布局,大多数情况是在自定义ViewGroup中才会重写,主要用来确定子View在这个布局空间中的摆放位置
解决:暂不处理,定位可以在使用自定义的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
android 自定义继承view
最新推荐文章于 2024-03-25 23:46:04 发布