鹤岗信息网:自定义View实战

admin 3周前 (10-02) 科技 125 2

PS:上一篇从0最先学自定义View有博友给我留言说要看实战,今天我特意写了几个例子,供人人参考,所画的图案加上动画看着确实让人舒适,喜欢的博友可以直接拿到自己的项目中去使用,由于我这个写的是demo,代码花样写的有些乱,以是,要自己封装一下才可以使用,固然你若是真的不想封装,可以直接使用,也可以给我留言,我封装好放在github上供人人参考,也会做成依赖让人人直接添加即可

先上图再剖析

可以看出图中有三种样式

  • 第一种是通俗的一个label,使用场景:商品过时,促销等展示。
  • 第二种是圆形进度条,      使用场景:下载文件进度,加载视频进度,耗电量进度.....
  • 第三种是条形进度条,      使用场景:滑动调值,手机音效巨细...

上面的三种,均是demo,思量使用场景并不完善,比如说第三种条形进度条还可以加上刻度,滑动到双方需要判断越界等。那就先拿第三个来吧

条形进度条-可拖动

剖析:我们想要做一个类似的控件,需要思量的问题不只是眼睛看的到的,看不到的就好比我只能点击小红球才可以滑动,我点击其他区域是不能有任何操作的,这个时刻就要判断手指down的时刻是否落在了小球上。

  • 线条 : 渐变颜色,线帽花样,长度,宽度设置,父结构宽高花样设置花样设置,子view宽高花样设置
  • 球 :颜色,起始位置和终止位置要在线上,尺寸

在做之前我们先一个一个知识点剖析,首先是线的渐变颜色,单独拿出

/**
     * 设置进度圆环颜色(支持渐变色)
     *
     * @param colorArray 渐变色聚集
     */
    private int[] mColorArray;  // 圆环渐变色
    public void setProgColor(@ColorRes int[] colorArray) {
        if (colorArray == null || colorArray.length < 2) return;
        mColorArray = new int[colorArray.length];
        for (int index = 0; index < colorArray.length; index++)
            mColorArray[index] = ContextCompat.getColor(getContext(), colorArray[index]);
        paint.setShader(new LinearGradient(0, 0, getMeasuredWidth(),0 , mColorArray, new float[]{0,.3F,.6F,.9F}, Shader.TileMode.MIRROR));
        invalidate();
    }

我们可以看到我封装成了一个方式,通过paint.setShader举行着色,方式传入的是LinearGradient工具,我们看源码,注释参数

 /**
     * Create a shader that draws a linear gradient along a line.
     *
     * @param x0           The x-coordinate for the start of the gradient line
     * @param y0           The y-coordinate for the start of the gradient line
     * @param x1           The x-coordinate for the end of the gradient line
     * @param y1           The y-coordinate for the end of the gradient line
     * @param colors       The colors to be distributed along the gradient line
     * @param positions    May be null. The relative positions [0..1] of
     *                     each corresponding color in the colors array. If this is null,
     *                     the the colors are distributed evenly along the gradient line.
     * @param tile         The Shader tiling mode
    */
    public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[],
            @Nullable float positions[], @NonNull TileMode tile) {
        if (colors.length < 2) {
            throw new IllegalArgumentException("needs >= 2 number of colors");
        }
        if (positions != null && colors.length != positions.length) {
            throw new IllegalArgumentException("color and position arrays must be of equal length");
        }
        mType = TYPE_COLORS_AND_POSITIONS;
        mX0 = x0;
        mY0 = y0;
        mX1 = x1;
        mY1 = y1;
        mColors = colors.clone();
        mPositions = positions != null ? positions.clone() : null;
        mTileMode = tile;
    }

参数

  1. x0,y0着色的起始位置
  2. x1,y1终止位置
  3. colors区域内着色的颜色集
  4. positions区域内部划分模块,逐一着色,如:区域1-100划分为4块,第一块1-25红色,26-50蓝色..。系统会默认在两种颜色不一样的情形下举行颜色过分渲染,到达渐变的效果,以是我们不用忧郁泛起红蓝划分显著的情形。
  5. TileMode 模式选择
    1.   CLAMP:当图片小于绘制尺寸时要举行界限拉伸来填充
    2.   REPEAT:当图片小于绘制尺寸时重复平铺
    3.   MIRROR:当图片小于绘制尺寸时镜像平铺

好了,下面我们就先画线和红点,若是有看不懂的博友,可以先看上一篇从0最先学自定义View。

public void init(){
        paint = new Paint();
        paint.setStrokeWidth(20);//画笔宽度
        paint.setStyle(Paint.Style.FILL);//填充类型
        paint.setAntiAlias(true);
        paint.setStrokeCap(Paint.Cap.ROUND);//线帽,半圆
        paintCircle2 = new Paint();
        paintCircle2.setColor(Color.RED);
        paintCircle2.setStrokeWidth(5);
        paintCircle2.setStyle(Paint.Style.FILL);
        paintCircle2.setAntiAlias(true);
    }
 @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = MeasureSpec.getSize(widthMeasureSpec);
        heigth =  MeasureSpec.getSize(heightMeasureSpec);
        Log.e("heigth -- width ",heigth+"  -- "+width);
        circleX=width/2;//初始化红点坐标位置
        circleY=20;
    }
 int[] colors={R.color.colorPrimary,R.color.colorAccent,R.color.color_environment_serious,R.color.color_environment_mild};
    @Override
    protected void onDraw(Canvas canvas) {

        super.onDraw(canvas);
        setProgColor(colors);
        //绘制一条线,线帽为半圆
        canvas.drawLine(50,20,width-50,20,paint);
        canvas.drawCircle(circleX,circleY,15,paintCircle2);
    }

到这里,线和点就已经做好了,只是静态的,下面是若何拖动,就要在onTouchEvent方式中去写了,代码都已经添加了注释  Math.abs(dhx)<50&&Math.abs(dhy)<50  是证实down的坐标点和原始球的坐标点相差范围在50内,若是小球在屏幕200,200的位置,而我们手指down的点在800,800,那么相差云云伟大,一定不是我们想要的效果,以是,我们就以为down的坐标减去球的坐标差值最小(50内)才是我们想要的效果,这个时刻我们再设置小球move的坐标(让小球追随手指移动)。

/**
     * 判断所按压的坐标和红点坐标的关系
     * 若是手指按在了红点的下方,那么down-红点y坐标的绝对值若是即是或者小于半径,也就是说现在按压的就是红点,
     *
     * */
    private boolean clickCircle(int downHeigth,int downWidth){
        int dhy = downHeigth - circleY;
        int dhx = downWidth - circleX;
        //证实按压的是原点
        if(Math.abs(dhx)<50&&Math.abs(dhy)<50){
            return true;
        }
        return false;
    }
    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        return super.dispatchTouchEvent(event);
    }
    boolean isFlag=false;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int rawX = (int) event.getX();
        int rawY = (int) event.getY();//获取到视图坐标,想对于外部viewgroup来说。
        Log.e("raw",rawX+"  ---  "+rawY);
        Log.e("rawwww",circleX+"  ---  "+circleY);
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                //若是是手指down在了红点上,move时可重绘
                if(clickCircle(rawY,rawX)) {
                    circleX = rawX;
                    isFlag=true;
                }else{
                    isFlag=false;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if(isFlag){
                    circleX = rawX;
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                isFlag=false;//抬起手指,状态恢复
                break;
        }
        return true;//自己消费
    }

下一篇是圆形进度条

,

阳光在线

阳光在线www.sinotter.com(原诚信在线)现已开放阳光在线手机版下载。阳光在线游戏公平、公开、公正,用实力赢取信誉。

阳光在线声明:该文看法仅代表作者自己,与本平台无关。转载请注明:鹤岗信息网:自定义View实战

站点信息

  • 文章总数:199
  • 页面总数:0
  • 分类总数:8
  • 标签总数:298
  • 评论总数:452
  • 浏览总数:24012

标签列表