美文网首页
横向柱状图

横向柱状图

作者: 小婷android | 来源:发表于2021-11-25 09:21 被阅读0次

    自定义View

    public class HorizontalBarView extends View {
    
        private ArrayList<HoBarEntity> hoBarEntityList = new ArrayList<>();
        private float barStartX = 0f;//
        private Paint mContentPaint;
        private Paint mbarPaint;
        private Paint mCountPaint;
        private Paint mLinePaint;
        private float barHeight = dp2px(15); //bar的高度
        private float barInterval = dp2px(15);//bar之间的距离
        private int mContentPaintColor = Color.parseColor("#9699A2"); //最左边文字的颜色
        private int mbarPaintColor = Color.parseColor("#fda33c");//bar的颜色
        private int mCountPaintColor = Color.parseColor("#ffffff");//最右边文字的颜色
        private int mLinePaintColor = Color.parseColor("#ededed");//线的颜色
        private int contentTextSize = 12;//最左边文字的大小
        private int countTextSize = 30;//最右边文字的大小
        private int viewIntervar = 10;//view的距离
        private float topAndBottomInterval = dp2px(10);//上下边距的距离(上下线与bar的距离)
        private float rightInterval = dp2px(10);//最右侧文字和右边距离
        private int defaltHeight = 0;
        private int textMaxWidth = 0;
        private int maxCount = 0;
        private float countMaxWidth = 0;
        private float contentTextHeight = 0;
        private float countTextHeight = 0;
    
        public HorizontalBarView(Context context) {
            this(context, null);
        }
    
        public HorizontalBarView(Context context, @Nullable AttributeSet attrs) {
            this(context, attrs, 0);
        }
    
        public HorizontalBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
            super(context, attrs, defStyleAttr);
            initPaints();
        }
    
        public float getBarHeight() {
            return barHeight;
        }
    
        public float getBarInterval() {
            return barInterval;
        }
    
        public int getmContentPaintColor() {
            return mContentPaintColor;
        }
    
        public int getMbarPaintColor() {
            return mbarPaintColor;
        }
    
        public int getmCountPaintColor() {
            return mCountPaintColor;
        }
    
        public int getmLinePaintColor() {
            return mLinePaintColor;
        }
    
        public int getContentTextSize() {
            return contentTextSize;
        }
    
        public int getCountTextSize() {
            return countTextSize;
        }
    
        public int getViewIntervar() {
            return viewIntervar;
        }
    
        public float getTopAndBottomInterval() {
            return topAndBottomInterval;
        }
    
        public int dp2px(float dpValue) {
            final float scale = getContext().getResources().getDisplayMetrics().density;
            return (int) (dpValue * scale + 0.5f);
        }
    
        private void initPaints() {
            mContentPaint = new Paint();
            mContentPaint.setAntiAlias(true);
            mContentPaint.setStyle(Paint.Style.FILL);
            mContentPaint.setColor(mContentPaintColor);
            mContentPaint.setTextSize(36);
            mContentPaint.setTextAlign(Paint.Align.RIGHT);
            mContentPaint.setStrokeCap(Paint.Cap.ROUND);
    
            mbarPaint = new Paint();
            mbarPaint.setAntiAlias(true);
            mbarPaint.setStyle(Paint.Style.FILL);
    //        mbarPaint.setColor(mbarPaintColor);
            mbarPaint.setStrokeCap(Paint.Cap.ROUND);
    
    
            mCountPaint = new Paint();
            mCountPaint.setAntiAlias(true);
            mCountPaint.setStyle(Paint.Style.FILL);
            mCountPaint.setTextSize(countTextSize);
            mCountPaint.setColor(mCountPaintColor);
            mCountPaint.setStrokeCap(Paint.Cap.ROUND);
    
            mLinePaint = new Paint();
            mLinePaint.setAntiAlias(true);
            mLinePaint.setStyle(Paint.Style.FILL);
            mLinePaint.setTextSize(countTextSize);
            mLinePaint.setColor(mLinePaintColor);
            mLinePaint.setStrokeCap(Paint.Cap.ROUND);
            mLinePaint.setStrokeWidth(dp2px(0.8f));
        }
    
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            int widthMode = MeasureSpec.getMode(widthMeasureSpec);
            int widthSize = MeasureSpec.getSize(widthMeasureSpec);
            int heightMode = MeasureSpec.getMode(heightMeasureSpec);
            int heightSize = MeasureSpec.getSize(heightMeasureSpec);
            int width = 0;
            int height = 0;
            if (widthMode == MeasureSpec.EXACTLY) {
                width = widthSize;
            } else {
                width = getScreenWidth();
            }
            if (heightMode == MeasureSpec.EXACTLY) {
                height = heightSize;
            } else {
                //计算高度
                computeHeightAndTextMaxWidth();
                height = defaltHeight;
            }
            setMeasuredDimension(width, height);
        }
    
        //计算高度
        private void computeHeightAndTextMaxWidth() {
            if (hoBarEntityList.size() == 0) {
                defaltHeight = getPaddingTop() + getPaddingBottom();
            } else {
                defaltHeight = (int) ((int) (getPaddingTop() + getPaddingBottom() + barHeight * hoBarEntityList.size() + (hoBarEntityList.size() - 1) * barInterval) + 2 * topAndBottomInterval);
                for (int i = 0; i < hoBarEntityList.size(); i++) {
                    float tempWidth = mContentPaint.measureText(hoBarEntityList.get(i).content);
                    if (tempWidth > textMaxWidth) {
                        textMaxWidth = (int) tempWidth;
                    }
                    //获取文字高度
                    if (contentTextHeight <= 0) {
                        Rect rect = new Rect();
                        mContentPaint.getTextBounds(hoBarEntityList.get(i).content, 0, hoBarEntityList.get(i).content.length(), rect);
                        contentTextHeight = rect.width();
                    }
                    if (countTextHeight <= 0) {
                        Rect rect = new Rect();
                        mCountPaint.getTextBounds(hoBarEntityList.get(i).count + "", 0, (hoBarEntityList.get(i).count + "").length(), rect);
                        countTextHeight = rect.width();
                    }
                    if (hoBarEntityList.get(i).count > maxCount) {
                        maxCount = hoBarEntityList.get(i).count;
                    }
                }
                countMaxWidth = mCountPaint.measureText(maxCount + "");
                barStartX = getPaddingLeft() + textMaxWidth + viewIntervar;
                Log.e("TAG", "textMaxWidth===" + textMaxWidth + "    countMaxWidth===" + countMaxWidth);
            }
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            super.onDraw(canvas);
            //计算最长的bar的长度
            float maxBarWidth = getMeasuredWidth() - getPaddingRight() - barStartX - countMaxWidth - 2 * viewIntervar - rightInterval;
            float perBarWidth = 0;
            if (maxCount > 0) {
                perBarWidth = maxBarWidth / maxCount;
            }
    
            //绘制bar
            float barStartY = getPaddingTop() + topAndBottomInterval;
            float barEndX = 0;
            float barEndY = 0;
            //绘制content
            float contentTextStart = barStartX - viewIntervar;
    
            //绘制上边的线
    //        canvas.drawLine(barStartX, getPaddingTop(), getMeasuredWidth() - getPaddingRight(), getPaddingTop(), mLinePaint);
            //绘制下边的线
    //        canvas.drawLine(barStartX, getMeasuredHeight() - getPaddingBottom(), getMeasuredWidth() - getPaddingRight(), getMeasuredHeight() - getPaddingBottom(), mLinePaint);
            //绘制左边的线
    //        canvas.drawLine(barStartX, getPaddingTop(), barStartX, getMeasuredHeight() - getPaddingBottom(), mLinePaint);
    
            for (int i = 0; i < hoBarEntityList.size(); i++) {
                barEndX = barStartX + perBarWidth * hoBarEntityList.get(i).count;
                barEndY = barStartY + barHeight;
                Log.e("TAG", "barStartX-barEndX===" + (barStartX - barEndX));
                //绘制bar
    //            canvas.drawRect(barStartX, barStartY, barEndX, barEndY, mbarPaint);
    
                RectF rectF = new RectF(barStartX + 20, barStartY, barEndX, barEndY);
                Path path = new Path();
                //float数组中4个角分别是左上、右上、右下、左下
                path.addRoundRect(rectF, new float[]{0, 0, 200, 200, 200, 200, 0, 0}, Path.Direction.CCW);
                LinearGradient linearGradient;
                if (hoBarEntityList.get(i).count != 0) {
                    linearGradient = new LinearGradient(barStartX + 20, barStartY, barEndX, barEndY, Color.parseColor("#ffffff"), Color.parseColor("#4A77FC"), Shader.TileMode.MIRROR);
                } else {
                    linearGradient = new LinearGradient(barStartX + 20, barStartY, barEndX, barEndY, Color.parseColor("#ffffff"), Color.parseColor("#ffffff"), Shader.TileMode.MIRROR);
                }
                mbarPaint.setShader(linearGradient);
                canvas.drawPath(path, mbarPaint);
                //绘制content
                //计算基线
    
                //绘制count
                Paint.FontMetricsInt fontMetrics = mCountPaint.getFontMetricsInt();
                float countBaseLine = barStartY + barHeight / 2 + -(fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.top;
                //获取文字的宽度
                Rect rect = new Rect();
                mCountPaint.getTextBounds(Double.valueOf(hoBarEntityList.get(i).count + "") / 100 + "", 0, (Double.valueOf(hoBarEntityList.get(i).count + "") / 100 + "").length(), rect);
                int w = rect.width();
                canvas.drawText(Double.valueOf(hoBarEntityList.get(i).count + "") / 100 + "", barEndX - w - 20, countBaseLine, mCountPaint);
                Paint.FontMetricsInt contentfontMetrics = mContentPaint.getFontMetricsInt();
                float contentBaseLine = barStartY + barHeight / 2 + -(contentfontMetrics.bottom - contentfontMetrics.top) / 2 - contentfontMetrics.top;
                canvas.drawText(hoBarEntityList.get(i).content, contentTextStart, contentBaseLine, mContentPaint);
    
                barStartY = barEndY + barInterval;
            }
    
    
        }
    
        private int getScreenWidth() {
            WindowManager wm = (WindowManager) getContext()
                    .getSystemService(Context.WINDOW_SERVICE);
            return wm.getDefaultDisplay().getWidth();
        }
    
    
        public void setHoBarData(ArrayList<HoBarEntity> list) {
            hoBarEntityList.clear();
            hoBarEntityList.addAll(list);
            barStartX = 0f;//
    
            barHeight = dp2px(15); //bar的高度
            barInterval = dp2px(15);//bar之间的距离
            mContentPaintColor = Color.parseColor("#9699A2"); //最左边文字的颜色
            mbarPaintColor = Color.parseColor("#fda33c");//bar的颜色
            mCountPaintColor = Color.parseColor("#999999");//最右边文字的颜色
            mLinePaintColor = Color.parseColor("#ededed");//线的颜色
            contentTextSize = 12;//最左边文字的大小
            countTextSize = 30;//最右边文字的大小
            viewIntervar = 10;//view的距离
            topAndBottomInterval = dp2px(10);//上下边距的距离(上下线与bar的距离)
            rightInterval = dp2px(10);//最右侧文字和右边距离
            defaltHeight = 0;
            textMaxWidth = 0;
            maxCount = 0;
            countMaxWidth = 0;
            contentTextHeight = 0;
            countTextHeight = 0;
            requestLayout();
            invalidate();
            postInvalidate();
        }
    
        public static class HoBarEntity {
            public String content;
            public int count;
        }
    
    }
    
    
    

    布局文件

      <com.dingler.water.cloud.functionbag.drainersmanager.watermonitoring.analysis.view.zz.HorizontalBarView
                            android:id="@+id/horizontal_bar"
                            android:layout_width="match_parent"
                            android:layout_height="wrap_content"
                            android:layout_marginLeft="@dimen/dp_20" />
    

    引用

      ArrayList<HorizontalBarView.HoBarEntity> hoBarEntities = new ArrayList<>();
            for (FacilityMonthData.DataBean dataBean : facilityMonthData) {
                HorizontalBarView.HoBarEntity hoBarEntity = new HorizontalBarView.HoBarEntity();
                if (monthDataType == 0) {
                    hoBarEntity.content = dataBean.getDeviceName();
                    hoBarEntity.count = (int) (Double.valueOf(dataBean.getAbnormalRate()) * 100);
                } else {
                    hoBarEntity.content = dataBean.getDeviceName();
                    hoBarEntity.count = (int) (Double.valueOf(dataBean.getOnlineRate()) * 100);
                }
                hoBarEntities.add(hoBarEntity);
            }
    
            viewBinding.horizontalBar.setHoBarData(hoBarEntities);
    

    相关文章

      网友评论

          本文标题:横向柱状图

          本文链接:https://www.haomeiwen.com/subject/hiratrtx.html