Android条形统计图实现_第1张图片

StripeStaticsView.java

import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.os.Handler;import android.os.Message;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewGroup;import com.careeach.sport.R;import java.util.List;/** * 条形统计图 */public class StripeStaticsView extends View {    private List values;    private List titles;    private int height;    private int width;    private Paint stripePaint;    private Paint stripeSelectedPaint; // 选中状态    private Paint titleTextPaint;       //  标题字    private Paint bodyBackGroundPaint;    private Paint titleBackGroundPaint;    private float itemHeight;             // 一个值对于高度    //ATTR    private int itemColor;          // 条形颜色    private float itemWidth;        // 条形宽度    private float itemSpaceWidth;  // 条形间隙    private int itemSelectColor;    private int maxValue;    private float centerX;    private float startX; // 第一条条形起始X座标    private float moveWidth = 0f;    private float touchStarX = 0;    private float titleHeight;          // 标题高度    private float titleTextY;          // 标题Y坐标    private float titleTextSize;        // 标题字体大小    private float titleTextLineSpace;  // 标题行间隙    private int titleTextColor;         // 标题字颜色    private int titleTextSelectColor;         // 标题字颜色    private int bodyBackGroundColor;         // 主背景    private int titleBackGroundColor;         // 标题背景    private boolean isMove = false;    private boolean isUp = false;    private OnStripeStaticsListener onStripeStaticsListener;    private int selectPosition = -1;    private TouchEventCountThread touchEventCountThread;    private final int HANDLER_WHAT_CLICK = 1;    private final int HANDLER_WHAT_SELECT_CHANGE = 2;    private ViewGroup parentViewGroup;    public StripeStaticsView(Context context) {        super(context);    }    public StripeStaticsView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init(context, attrs);    }    public StripeStaticsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context, attrs);    }    public StripeStaticsView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        init(context, attrs);    }    private void init(Context context, AttributeSet attrs) {        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.StripeStaticsView);        itemColor = typedArray.getColor(R.styleable.StripeStaticsView_itemColor, Color.BLACK);        itemSelectColor = typedArray.getColor(R.styleable.StripeStaticsView_itemSelectColor, Color.WHITE);        itemSpaceWidth = typedArray.getDimension(R.styleable.StripeStaticsView_itemSpaceWidth, Color.BLACK);        itemWidth = typedArray.getDimension(R.styleable.StripeStaticsView_itemWidth, dip2px(20));        maxValue = typedArray.getInt(R.styleable.StripeStaticsView_maxValue, 100);        titleTextSize = typedArray.getDimension(R.styleable.StripeStaticsView_titleTextSize, sp2px(12));        titleTextLineSpace = typedArray.getDimension(R.styleable.StripeStaticsView_titleTextLineSpace, dip2px(10));        titleTextColor = typedArray.getColor(R.styleable.StripeStaticsView_titleTextColor, Color.WHITE);        titleTextSelectColor = typedArray.getColor(R.styleable.StripeStaticsView_titleTextSelectColor, Color.WHITE);        bodyBackGroundColor = typedArray.getColor(R.styleable.StripeStaticsView_contentBGColor, Color.WHITE);        titleBackGroundColor = typedArray.getColor(R.styleable.StripeStaticsView_titleBGColor, Color.WHITE);        typedArray.recycle();        stripePaint = new Paint();        stripePaint.setColor(itemColor);        stripePaint.setAntiAlias(true);        stripePaint.setStyle(Paint.Style.FILL);        stripeSelectedPaint = new Paint();        stripeSelectedPaint.setColor(itemSelectColor);        stripeSelectedPaint.setAntiAlias(true);        stripeSelectedPaint.setStyle(Paint.Style.FILL);        titleTextPaint = new Paint();        titleTextPaint.setColor(titleTextColor);        titleTextPaint.setTextSize(titleTextSize);        titleTextPaint.setAntiAlias(true);        bodyBackGroundPaint = new Paint();        bodyBackGroundPaint.setColor(bodyBackGroundColor);        bodyBackGroundPaint.setStyle(Paint.Style.FILL);        titleBackGroundPaint = new Paint();        titleBackGroundPaint.setColor(titleBackGroundColor);        titleBackGroundPaint.setStyle(Paint.Style.FILL);        touchEventCountThread = new TouchEventCountThread();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        width = getMeasuredWidth();        height = getMeasuredHeight();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        centerX = (width - itemWidth) / 2;        if (values != null && values.size() > 0) {            startX = ((width / 2) + (itemWidth / 2)) - ((itemWidth * values.size()) + ((values.size() - 1) * itemSpaceWidth));        }        titleHeight = titleTextSize + (titleTextLineSpace * 2);        itemHeight = (height - titleHeight) / maxValue;        titleTextY = height - titleTextSize;        // 主背景        canvas.drawRect(0f, 0, width, height - titleHeight, bodyBackGroundPaint);        // 标题背景        canvas.drawRect(0f, height - titleHeight, width, height, titleBackGroundPaint);        if (values != null && values.size() > 0 && titles != null && titles.size() == values.size()) {            for (int i = 0; i < values.size(); i++) {                int value = values.get(i);                float left = startX + (itemWidth + itemSpaceWidth) * i + moveWidth;                float top = height - titleHeight - (itemHeight * value);                float right = left + itemWidth;                float bottom = height - titleHeight;                String title = titles.get(i);                float textWidth = titleTextPaint.measureText(title, 0, title.length());                float textX = left + ((itemWidth - textWidth) / 2);                // 判断是否中心                if (left >= centerX && left <= (width + itemWidth) / 2) {                    canvas.drawRect(left, top, right, bottom, stripeSelectedPaint);                    // 标题                    titleTextPaint.setColor(titleTextSelectColor);                    canvas.drawText(title, textX, titleTextY, titleTextPaint);                    if (i == 0 || selectPosition != i) {                        Message message = handler.obtainMessage();                        message.what = HANDLER_WHAT_SELECT_CHANGE;                        message.arg1 = i;                        message.sendToTarget();                    }                    selectPosition = i;                } else {                    canvas.drawRect(left, top, right, bottom, stripePaint);                    // 标题                    titleTextPaint.setColor(titleTextColor);                    canvas.drawText(title, textX, titleTextY, titleTextPaint);                }            }        }    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                touchStarX = event.getX();                isMove = false;                isUp = false;                postDelayed(touchEventCountThread, 100);                if(parentViewGroup != null){                    parentViewGroup.requestDisallowInterceptTouchEvent(true);                }                break;            case MotionEvent.ACTION_MOVE:                isMove = true;                if (Math.abs(event.getX() - touchStarX) > 1) {                    moveWidth += event.getX() - touchStarX;                    postInvalidate();                    touchStarX = event.getX();                }                break;            case MotionEvent.ACTION_UP:                isUp = true;                if (isMove) {                    aligning();                }                if(parentViewGroup != null){                    parentViewGroup.requestDisallowInterceptTouchEvent(false);                }                break;        }        //return super.onTouchEvent(event);        return true;    }    /**     * 对齐,让靠中间的条形移至正中间     */    private void aligning() {        if(values == null || values.isEmpty()){            return;        }        Float tagX = null;        Float tagXValue = null;        for (int i = 0; i < values.size(); i++) {            float left = startX + (itemWidth + itemSpaceWidth) * i + moveWidth;            float distance = Math.abs(centerX - left);            if (tagX == null || distance < tagX) {                tagX = distance;                tagXValue = centerX - left;            }        }        if (tagX != null) {            moveWidth += tagXValue;        }        isMove = false;        postInvalidate();    }    public void setValue(List values) {        this.values = values;        selectPosition = 0;    }    public void setTitle(List titles) {        this.titles = titles;    }    public void refresh() {        postInvalidate();    }    private int dip2px(float dpValue) {        final float scale = getContext().getResources().getDisplayMetrics().density;        return (int) (dpValue * scale + 0.5f);    }    private float sp2px(float spValue) {        final float scale = getContext().getResources().getDisplayMetrics().scaledDensity;        return (spValue * scale + 0.5f);    }    class TouchEventCountThread implements Runnable {        @Override        public void run() {            if (!isMove && isUp && values != null && values.size() > 0 && titles != null && titles.size() == values.size()) {                for (int i = 0; i < values.size(); i++) {                    float left = startX + (itemWidth + itemSpaceWidth) * i + moveWidth;                    float right = left + itemWidth;                    if (touchStarX >= left && right >= touchStarX) {                        selectTo(i);                        if (onStripeStaticsListener != null) {                            Message message = handler.obtainMessage();                            message.what = HANDLER_WHAT_CLICK;                            message.arg1 = i;                            message.sendToTarget();                        }                        break;                    }                }            }        }    }    Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            super.handleMessage(msg);            switch (msg.what) {                case HANDLER_WHAT_CLICK:                    if(onStripeStaticsListener != null) {                        onStripeStaticsListener.onItemClick(msg.arg1);                    }                    break;                case HANDLER_WHAT_SELECT_CHANGE:                    if(onStripeStaticsListener != null) {                        onStripeStaticsListener.onSelectChanged(msg.arg1);                    }                    break;            }        }    };    public void selectTo(int position) {        if (selectPosition == position) {            return;        }        if (position > selectPosition) {            moveWidth -= ((itemWidth + itemSpaceWidth) * (position - selectPosition));        } else {            moveWidth += ((itemWidth + itemSpaceWidth) * (selectPosition - position));        }        postInvalidate();    }    public interface OnStripeStaticsListener {        void onItemClick(int position);        void onSelectChanged(int position);    }    public void setOnStripeStaticsListener(OnStripeStaticsListener onClickListener) {        this.onStripeStaticsListener = onClickListener;    }    public void setParentViewGroup(ViewGroup parentViewGroup) {        this.parentViewGroup = parentViewGroup;    }}

attr.xml添加属性

                                            

使用

// 设置值void setValue(List values)// 设置值对应的标题(注:数量要对应)void setTitle(List titles)// 设置标题和内容后刷新控件void refresh()// 控件添加在上下滑动控件中时,当手在该控件左右滑动时不会触发上下滑动,添强体验,如ListViewvoid setParentViewGroup(ViewGroup parentViewGroup)

更多相关文章

  1. Android(Java):自定义控件
  2. Android标题栏各种设置
  3. android 获取界面上所有控件
  4. Android开发——控件基础(七)ListView组件:示例代码
  5. Android实现圆形头像-使用自定义控件
  6. android -布局控件禁用多点触控
  7. 1、ListView自定义控件下拉刷新(一)
  8. Android使用AttributeSet自定义控件的方法

随机推荐

  1. Android中ADT插件的安装
  2. 这个软件真不简单
  3. 为什么你就不能加个空格呢?
  4. 每日一技|巧用 Telnet 调试 Dubbo 服务
  5. Azure Lab Service 体验
  6. 小奎因的 PYTHON 项目部署与调度直播分享
  7. 使用类型注解让 Python 代码更易读
  8. widnows 下如何使用 ping加时间戳,来ping
  9. 正式工作后的一些变化和感受
  10. 爬虫智能解析库 Readability 和 Newspape