android自定义控件实现简易时间轴(2)

 更新时间:2022年01月24日 17:19:36   作者:哈哈哈哈哈哈_Y  
这篇文章主要为大家详细介绍了android自定义控件实现简易时间轴的第二篇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

这篇做了一个简单的时间轴控件。右侧的数据就是一个简单的字符串。问题还是有的,当右侧的文字长度不一样的时候就会有问题了。现在可以修改一下适配右侧的文字。

效果如下:

代码:

private Paint bgPaint, linePaint, borderPaint,textPaint;
private Rect bgRect, textRect;

//基本属性
private int mTextSize;
private int mTextColor;
private String mTextTitle="默认文本内容";

private int lineColr = Color.parseColor("#AAAAAA");
private int borderColor = Color.parseColor("#AAAAAA");
private int bgColor = Color.parseColor("#138DDD");
private int mBorderColor=0xFFDDDDDD;
private int mBorderWidth = 10;
private int mLineColor=Color.parseColor("#ff000000");
private int mLineWidth = 2;
private int mLineHeight;
private int mBgColor;

private  int mWidth =0;
private  int mHeight =300;//整个控件的宽和高

//line绘制
private int lineLocation = -1;//0  上方 1  下方 2  上下两个
private int mRadius = 90;//直径,最终会被宽高限制

//设置line的位置 0  上方 1  下方 2  上下两个

public void setLineLocation(int lineLocation) {
        this.lineLocation = lineLocation;
    }


//设置纯色的整圆形,包括背景
public void setBgAndBorderColor(int color) {
        this.mBgColor = color;
    }

    public void setmHeight(int mHeight) {

        this.mHeight = mHeight;
    }

    public void setmBorderColor(int mBorderColor) {
        this.mBorderColor = mBorderColor;
    }

    public void setmTextTitle(String mTextTitle) {
        this.mTextTitle = mTextTitle;
    }

    public void setmRadius(int mRadius) {
        this.mRadius = mRadius;
    }

    public void setmLineHeight(int mLineHeight) {
        this.mLineHeight = mLineHeight;
    }

    public TimeLineSingleView(Context context) {
        this(context,null);
    }

    public TimeLineSingleView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public TimeLineSingleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCicleView, defStyleAttr, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
                case R.styleable.CustomCicleView_textSize:
                    // 默认设置为16sp,TypeValue也可以把sp转化为px
                    mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_DIP, 14, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomCicleView_textColor:
                    mTextColor = a.getColor(attr, Color.BLACK);
                    break;
                case R.styleable.CustomCicleView_textTitle:
                    mTextTitle = a.getString(attr);
                    break;
                case R.styleable.CustomCicleView_lineWidth:
                    mLineWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_DIP, 2, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomCicleView_lineColor:
                    mLineColor = a.getColor(attr, lineColr);
                    break;

                case R.styleable.CustomCicleView_mRadius:
                    mRadius=a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomCicleView_borderWidth:
                    mBorderWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(
                            TypedValue.COMPLEX_UNIT_DIP, 10, getResources().getDisplayMetrics()));
                    break;
                case R.styleable.CustomCicleView_borderColor:
                    mBorderColor = a.getColor(attr, borderColor);
                    break;
                case R.styleable.CustomCicleView_bgColor:
                    mBgColor = a.getColor(attr, bgColor);
                    break;
            }
        }
        a.recycle();
        bgPaint = new Paint();
        borderPaint = new Paint();
        linePaint = new Paint();
        textPaint = new Paint();
        textRect = new Rect();
        textPaint.setTextSize(mTextSize);

    }

    //EXACTLY :在准确的数值和Match_parent的状态是这个值 列表中,wrap_content的状态下必须计算一个合适的值
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int w = 0;
        int h =0;
        int widthMode=MeasureSpec.getMode(widthMeasureSpec);
        int heightMode=MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        if(widthMode==MeasureSpec.EXACTLY){

            w=widthSize;
        }else{
            w=Math.max(mHeight,mRadius+getPaddingRight()+getPaddingLeft());
        }

        if(heightMode==MeasureSpec.EXACTLY){

            h=heightSize;
        }else{
            h=Math.max(mHeight,mRadius+getPaddingTop()+getPaddingBottom());
        }

        setMeasuredDimension(w,h);
        }

    @Override
    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);


        int centreX = getWidth()/ 2; // 获取圆心的x坐标
        int centreY=getHeight()/2;

        //半径比较
        mBorderWidth =(mBorderWidth>=mRadius/10)?(mRadius/10):mBorderWidth;//半径的1/5
        int radius = mRadius/2 - mBorderWidth / 2;// 半径

        if(mLineHeight<=0){

            mLineHeight=Math.abs(getHeight()/2-radius);//这个地方要判断设置正负
        }
        //绘制圆

        bgPaint.setAntiAlias(true); // 消除锯齿
        bgPaint.setColor(mBgColor);
        bgPaint.setStyle(Paint.Style.FILL); // 设置实心
        canvas.drawCircle(centreX, centreY, radius, bgPaint);
        //绘制圆环
        borderPaint.setStrokeWidth(mBorderWidth); // 设置圆环的宽度
        borderPaint.setAntiAlias(true); // 消除锯齿
        if (mBorderColor != 0) {
            borderPaint.setColor(mBorderColor);
        } else {
            borderPaint.setColor(borderColor);
        }
        borderPaint.setStyle(Paint.Style.STROKE); // 设置实心
        canvas.drawCircle(centreX,centreY, radius - mBorderWidth / 2+mLineWidth/2, borderPaint);

        //绘制文本
        textPaint.setTextSize(mTextSize);
        textPaint.setColor(mTextColor);
        textPaint.getTextBounds(mTextTitle, 0, mTextTitle.length(), textRect);

        canvas.drawText(mTextTitle, centreX -textRect.width()/2-mBorderWidth/2, centreY  + textRect.height() / 2, textPaint);


        //绘制线条
        drawLineAll(canvas,centreX,centreY,radius);

    }
    //上下都绘制不用
    //1  上方 0  下方 2  上下两个

    private void drawLineAll(Canvas canvas,  float centreX, float centreY,int radius) {

        if(lineLocation==-1){
            linePaint.setColor(borderColor);
            linePaint.setStrokeWidth(mLineWidth);
            canvas.drawLine(centreX, 0, centreX, centreY-radius, linePaint);//上方的
            canvas.drawLine(centreX, centreY+radius, centreX, getHeight(), linePaint);//下方的
        }else{
            //这个可以绘制不同的line
            linePaint.setColor(lineColr);
            linePaint.setStrokeWidth(mLineWidth);
            if (lineLocation == 0) {
                canvas.drawLine(centreX, centreY+radius, centreX, getHeight(), linePaint);
            } else if (lineLocation == 1) {
                canvas.drawLine(centreX, 0, centreX, centreY -radius , linePaint);

            } else if (lineLocation == 2) {
                canvas.drawLine(centreX, centreY+radius, centreX, getHeight(), linePaint);
                canvas.drawLine(centreX, 0, centreX, centreY -radius , linePaint);
            }
        }

    }

其他代码和之前文章一样就不贴了,但是还有一个问题就是,这个控件是放在一个列表里面的,你在适配器中使用的时候布局要是wrap的状态下要计算一个合适的高度,比如listView 的Item的高度。这里我没有实现,还是在Match和固定高度中,后期更改。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • Android TextView和ImageView简单说明

    Android TextView和ImageView简单说明

    Android TextView和ImageView简单说明,需要的朋友可以参考一下
    2013-03-03
  • 详解Android内存优化策略

    详解Android内存优化策略

    这篇文章主要介绍了详解Android内存优化策略,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Android基于OpenCV实现霍夫直线检测

    Android基于OpenCV实现霍夫直线检测

    霍夫变换利用点与线之间的对偶性,将图像空间中直线上离散的像素点通过参数方程映射为霍夫空间中的曲线,并将霍夫空间中多条曲线的交点作为直线方程的参数映射为图像空间中的直线。给定直线的参数方程,可以利用霍夫变换来检测图像中的直线。本文简单讲解Android的实现
    2021-06-06
  • Kotlin协程操作之创建启动挂起恢复详解

    Kotlin协程操作之创建启动挂起恢复详解

    本文的定位是协程的创建、启动、挂起、恢复,也会示例一些简单的使用,这里不对suspend讲解,,也不对协程的高级用法做阐述(热数据通道Channel、冷数据流Flow...),本文主要讲协程稍微深入的全面知识
    2022-08-08
  • Android Loader的使用以及手机通讯录的获取方法

    Android Loader的使用以及手机通讯录的获取方法

    下面小编就为大家分享一篇Android Loader的使用以及手机通讯录的获取方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Android编程实现音量按钮添加监听事件的方法

    Android编程实现音量按钮添加监听事件的方法

    这篇文章主要介绍了Android编程实现音量按钮添加监听事件的方法,结合实例形式分析了Android事件监听实现音量控制的相关操作技巧,需要的朋友可以参考下
    2017-06-06
  • android 多线程技术应用

    android 多线程技术应用

    能够在屏幕上“实时地显示”时间的流逝,单线程程序是无法实现的,必须要多线程程序才可以实现,即便有些计算机语言可以通过封装好的类实现这一功能,但从本质上讲这些封装好的类就是封装了一个线程,具体祥看本文
    2012-12-12
  • Android编程之滑动按钮事件实例详解

    Android编程之滑动按钮事件实例详解

    这篇文章主要介绍了Android编程之滑动按钮事件,结合具体实例形式分析了Android滑动按钮功能的具体实现步骤、布局及功能实现相关操作技巧,需要的朋友可以参考下
    2017-03-03
  • Android异步更新UI的四种方式

    Android异步更新UI的四种方式

    这篇文章主要为大家详细介绍了Android异步更新UI的四种方式,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • Android使用系统自带的相机实现一键拍照功能

    Android使用系统自带的相机实现一键拍照功能

    这篇文章主要介绍了Android使用系统自带的相机实现一键拍照功能,非常不错,具有参考借鉴价值,需要的朋友参考下
    2017-01-01

最新评论