Android刮刮卡自定义控件

网上的都是自己绘制的或者图片,我的需求是可以随意的自定义底部和顶部的布局。所以自己重写一个,原理就是直接继承 View 来实现一个刮层,让这个刮层和图片以及文字不产生任何依赖,再结合 FrameLayout 将刮层放置最上一层,刮层之下你想放多少图片文字,图片文字要怎么布局摆放都行。由于是FrameLayout ,刮层的上面想加内容都是可以的。如图:

 

 

原理:刮刮卡无非就是文本,或者图片,就是我们下边的布局,然后在其上绘制刮奖层,设置DST_OUT,然后把用户触摸绘制上去;这样消失以后就能看到背后的奖了。

布局

1
2
3
4
5
6
7
8
9
10
11
<FrameLayout
        android:layout_width= "350dp"
        android:layout_centerInParent= "true"
        android:layout_height= "150dp" >
        <include
            layout= "@layout/scratch_view_after" />
        <coordemo.ly.com.myapplication.GuaGuaKaView
            android:layout_width= "match_parent"
            android:id= "@+id/gg1"
            android:layout_height= "match_parent" />
    </FrameLayout>

  

刮一刮控件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
public class GuaGuaKaView extends View {
     /**
      * 绘制线条的画笔
      */
     private Paint mOutterPaint = new Paint();
     /**
      * 遮层画笔
      */
     private Paint mMaskPaint = new Paint();
     /**
      * 最下面画笔
      */
     private Paint mBackPint = new Paint();
     /**
      * mCanvas绘制内容在其上
      */
     private Bitmap mBitmap;
     /**
      * 记录用户绘制的Path
      */
     private Path mPath = new Path();
     /**
      * 内存中创建的Canvas
      */
     private Canvas mCanvas;
     private boolean isComplete;
     private Rect mTextBound = new Rect();
     private String mText = "¥500,0000" ;
     private int mLastX;
     private int mLastY;
     private int measuredWidth;
     private int measuredHeight;
     public GuaGuaKaView(Context context) {
         this (context, null );
     }
     public GuaGuaKaView(Context context, AttributeSet attrs) {
         this (context, attrs, 0);
     }
     public GuaGuaKaView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
         init();
     }
     private void init() {
         mPath = new Path();
         setUpOutPaint();
         setUpBackPaint();
     }
     /**
      * 初始化canvas的绘制用的画笔
      */
     private void setUpBackPaint() {
         mBackPint.setStyle(Style.FILL);
         mBackPint.setTextScaleX(2f);
         mBackPint.setColor(Color.DKGRAY);
         mBackPint.setTextSize(32);
         mBackPint.getTextBounds(mText, 0, mText.length(), mTextBound);
     }
     @Override
     protected void onDraw(Canvas canvas) {
         if (!isComplete) {
             drawPath();
             canvas.drawBitmap(mBitmap, 0, 0, null );
         } else {
             this .setVisibility(GONE);
         }
     }
     @Override
     protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec) {
         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
         measuredWidth = getMeasuredWidth(); //宽高和父view的相同
         measuredHeight = getMeasuredHeight();
         // 初始化bitmap
         mBitmap = Bitmap.createBitmap(measuredWidth, measuredHeight, Bitmap.Config.ARGB_8888);
         mCanvas = new Canvas(mBitmap);
         mMaskPaint.setColor(Color.parseColor( "#00000000" )); //遮层透明
         mMaskPaint.setStyle(Style.FILL);
         mCanvas.drawRoundRect( new RectF(0, 0, measuredWidth, measuredHeight), 0, 0, mMaskPaint);
         mCanvas.drawBitmap(BitmapFactory.decodeResource(getResources(),
                 R.drawable.award_1), null , new RectF(0, 0, measuredWidth, measuredHeight), null ); //遮层
     }
     /**
      * 设置画笔的一些参数
      */
     private void setUpOutPaint() {
         // 设置画笔
//         mOutterPaint.setAlpha(0);
         mOutterPaint.setColor(Color.parseColor( "#c0c0c0" ));
         mOutterPaint.setAntiAlias( true );
         mOutterPaint.setDither( true );
         mOutterPaint.setStyle(Style.STROKE);
         mOutterPaint.setStrokeJoin(Paint.Join.ROUND); // 圆角
         mOutterPaint.setStrokeCap(Paint.Cap.ROUND); // 圆角
         // 设置画笔宽度
         mOutterPaint.setStrokeWidth(50);
     }
     /**
      * 绘制线条
      */
     private void drawPath() {
         mOutterPaint.setStyle(Style.STROKE);
         mOutterPaint
                 .setXfermode( new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); //取俩者的交集
         mCanvas.drawPath(mPath, mOutterPaint);
     }
     @Override
     public boolean onTouchEvent(MotionEvent event ) {
         int action = event .getAction();
         int x = ( int ) event .getX();
         int y = ( int ) event .getY();
         switch (action) {
             case MotionEvent.ACTION_DOWN:
                 mLastX = x;
                 mLastY = y;
                 mPath.moveTo(mLastX, mLastY);
                 break ;
             case MotionEvent.ACTION_MOVE:
                 int dx = Math.abs(x - mLastX);
                 int dy = Math.abs(y - mLastY);
                 if (dx > 3 || dy > 3)
                     mPath.lineTo(x, y);
                 mLastX = x;
                 mLastY = y;
                 new Thread(mRunnable).start();
                 break ;
             case MotionEvent.ACTION_UP:
                 new Thread(mRunnable).start();
                 break ;
         }
         invalidate();
         return true ;
     }
     /**
      * 统计擦除区域任务
      */
     private Runnable mRunnable = new Runnable() {
         private int [] mPixels;
         @Override
         public void run() {
             int w = getWidth();
             int h = getHeight();
             float wipeArea = 0;
             float totalArea = w * h;
             Bitmap bitmap = mBitmap;
             mPixels = new int [w * h];
             /**
              * 拿到所有的像素信息
              */
             bitmap.getPixels(mPixels, 0, w, 0, 0, w, h);
             /**
              * 遍历统计擦除的区域
              */
             for ( int i = 0; i < w; i++) {
                 for ( int j = 0; j < h; j++) {
                     int index = i + j * w;
                     if (mPixels[index] == 0) {
                         wipeArea++;
                     }
                 }
             }
             /**
              * 根据所占百分比,进行一些操作
              */
             if (wipeArea > 0 && totalArea > 0) {
                 int percent = ( int ) (wipeArea * 100 / totalArea);
//                Log.e("TAG", percent + "");
                 if (percent > 50) {
//                    Log.e("TAG", "清除区域达到50%,下面自动清除");
                     isComplete = true ;
                     postInvalidate();
                 }
             }
         }
     };
     /**
      * 将布局转换成bitmap
      * @param addViewContent
      * @return
      */
     private Bitmap getViewBitmap(View addViewContent) {
         addViewContent.setDrawingCacheEnabled( true );
         addViewContent.measure(
                 View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                 View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
         addViewContent.layout(0, 0,
                 addViewContent.getMeasuredWidth(),
                 addViewContent.getMeasuredHeight());
         addViewContent.buildDrawingCache();
         Bitmap cacheBitmap = addViewContent.getDrawingCache();
         Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
         return bitmap;
     }
}

  

 
GitHub地址:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值