当前位置: 移动技术网 > IT编程>移动开发>Android > Android项目刮刮奖详解(三)

Android项目刮刮奖详解(三)

2018年08月21日  | 移动技术网IT编程  | 我要评论

有哪些革命英雄,瑜伽减肥动作,重生开饭馆

android项目刮刮奖详解(二)

前言

上一期我们已经实现了一个简易的刮刮卡功能,这一期我们来将其完善一下

目标

  • 将刮刮奖的宽高改为合适高度
  • 将刮刮奖位置居中
  • 将信息层的图片换成文字(重点)

    实现

  1. 将刮刮奖的宽高改为合适高度和将刮刮奖位置居中

    这里其实很简单,我们直接到layout布局之中将大小修改一下即可,同时,在布局中利用gravity修改位置

     <?xml version="1.0" encoding="utf-8"?>
     <linearlayout
         xmlns:android="http://schemas.android.com/apk/res/android"
         xmlns:app="http://schemas.android.com/apk/res-auto"
         xmlns:tools="http://schemas.android.com/tools"
         android:orientation="vertical"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="center"
         tools:context="com.wan.guajiang.mainactivity">
    
     <com.wan.guajiang.guaguaka
          android:layout_width="300dp"
          android:layout_height="100dp"/>
    
     </linearlayout>
  2. 将信息层的图片换成文字

之前我们信息层绘制的是中奖图片,如果没有图片怎么办?当然是直接拿文字来代替啦,canvas不仅可以画图片,还可以画文字,写文字

首先,我们来了解一下canvas的drawtext方法参数

drawtext(string text, float x, floaty, paint paint);

text即使要写的文字内容,x,y是写的位置,需要注意的是,这里的x,y坐标并不是文字的左上角,而是一个与左下角比较接近的位置。大概在这里:如图

最后一个参数就是画笔了,这个画笔设置与之前相似,待会再补充一下

我们想要把文字写在信息层的正中间,x,y的坐标该怎么写呢?由上图可以知道,canvas使用drawtext方法,xy的坐标其实是位于文字的左下角的,下图便是图解

x,y图解

相信这张图还是很好理解的,我们继续,开始写代码

  • 首先,我们需要个文字内容

      string message = "恭喜中奖,3万元!";
  • 定义我们的画笔paint,对其进行相关设置

    这里得提一下,我们需要一个rect矩形来得到文字内容的背景大小,也就是上图中的红色矩形,paint画笔中提供了一个方法gettextbounds,我们可以通过此方法来获得文字内容的背景大小
    messagepaint.gettextbounds(string text,float start,float end,rect rect);

    上述代码的意思是,截取text文字中的从start到end的长度,将截取的长度和文字的高度形成一个矩形,rect矩形接收这个矩形

      rect mbackground = new rect();//用来接收gettextbounds返回的矩形      
      paint messagepaint = new paint();
      messagepaint.setcolor(color.red);
      messagepaint.setantialias(true);
      messagepaint.setstyle(paint.style.stroke);
      messagepaint.gettextbounds(message,0,message.length(),mbackground);
      messagepaint.settextsize(30);
  • 计算x,y坐标,canvas使用drawtext写出文字
    我们有两种方法来获得之前黑色矩形的长和宽,一种是使用getmeasured,另一种使用mbitmap.get方法来获得长和宽

      canvas.drawtext(message,getmeasuredwidth()/2-mbackground.width()/2,getmeasuredheight()/2+mbackground.height()/2,messagepaint);

    或者:

      canvas.drawtext(message,mbitmap.getwidth()/2-mbackground.width()/2,mbitmap.getheight()/2+mbackground.height()/2,messagepaint);

    测试图

测试图

完整代码

public class guajiangview extends view {

    /**
     * 绘制线条的paint,即用户手指绘制path
     */
    private paint moutterpaint = new paint();
    /**
     * 记录用户绘制的path
     */
    private path mpath = new path();
    /**
     * 内存中创建的canvas
     */
    private canvas mcanvas;
    /**
     * mcanvas绘制内容在其上
     */
    private bitmap mbitmap;

    private int mlastx;
    private int mlasty;

    private string message;//中奖信息
    private rect mbackground;//文字背景矩形大小
    private paint messagepaint = new paint();//文字画笔
    private boolean isclear = false;
    public guajiangview(context context) {
        super(context);

    }



    public guajiangview(context context, @nullable attributeset attrs) {
        super(context, attrs);
    }

    public guajiangview(context context, @nullable attributeset attrs, int defstyleattr) {
        super(context, attrs, defstyleattr);
    }

    public guajiangview(context context, @nullable attributeset attrs, int defstyleattr, int defstyleres) {
        super(context, attrs, defstyleattr, defstyleres);
    }

    @override
    protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {
        super.onmeasure(widthmeasurespec, heightmeasurespec);
        log.d(tag, "onmeasure: 测量");
        int width = getmeasuredwidth();
        int height = getmeasuredheight();


        // 初始化bitmap
        mbitmap = bitmap.createbitmap(width, height, bitmap.config.argb_8888);//以获得的宽高创建一个32位的bitmap
        mcanvas = new canvas(mbitmap);//以bitmap创建了一个画布
        mcanvas.drawcolor(color.green);//设置画布的颜色为绿色

        mbackground = new rect();
        message = "恭喜中奖,3万元!";
        messagepaint.setcolor(color.red);
        messagepaint.setantialias(true);
        messagepaint.setstyle(paint.style.stroke);
        messagepaint.gettextbounds(message,0,message.length(),mbackground);
        messagepaint.settextsize(30);


        // 设置画笔
        moutterpaint.setcolor(color.blue);
        moutterpaint.setantialias(true);//使用抗锯齿功能,会消耗较大资源,绘制图形速度会变慢
        moutterpaint.setdither(true);//图像抖动处理,会使绘制出来的图片颜色更加平滑和饱满,图像更加清晰
        moutterpaint.setstyle(paint.style.stroke);
        moutterpaint.setstrokejoin(paint.join.round);//圆角,平滑
        moutterpaint.setstrokecap(paint.cap.round); //圆角
        moutterpaint.setstrokewidth(20); // 设置画笔宽度

        messagepaint.setcolor(color.red);

    }

    @override
    protected void ondraw(canvas canvas) {
        log.d(tag, "ondraw: 画");


        canvas.drawtext(message,mbitmap.getwidth()/2-mbackground.width()/2,getmeasuredheight()/2+mbackground.height()/2,messagepaint);
        drawpath();
        canvas.drawbitmap(mbitmap, 0,0, null);

    }

    private void drawpath() {
        log.d(tag, "drawpath: ");

        moutterpaint.setxfermode(new porterduffxfermode(porterduff.mode.dst_out));
        mcanvas.drawpath(mpath, moutterpaint);
    }

    @override
    public boolean ontouchevent(motionevent event) {
        //当手指按到屏幕上的时候,path路径之中就使用moveto方法,移动到手指当前位置,invalidate刷新view,回调ondraw方法,(还没有画出来)
        //之后,手指移动,action是处于action_move的状态,path路径使用lineto方法(画直线),
        // 同时,将x,y坐标进行了更新,invalidate刷新view,回调ondraw方法,canvas通过drawpath使用画笔将path画了出来,之后如果用户没有抬起手指,则继续循环action_move中的步骤

        int action = event.getaction();
        int x = (int) event.getx();//获得x坐标
        int y = (int) event.gety();//获得y坐标
        switch (action){
            case motionevent.action_down:
                mlastx = x;
                mlasty = y;
                mpath.moveto(mlastx, mlasty);//之后回调ondraw方法canvas将path
                break;
            case motionevent.action_move:
                mpath.lineto(x, y);//之后回调ondraw方法时canvas画直线到(x,y)该点
                mlastx = x;//更新x坐标
                mlasty = y;//更新y坐标
                break;
            default:break;
        }
        invalidate();//刷新view,回调ondraw方法
        log.d(tag, "ontouchevent: invalidate");
        return true;

    }
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网