安卓下的刮刮卡摸奖的实现

indam 8年前
   <p>效果如下:</p>    <p><img src="https://simg.open-open.com/show/396f88d771772cdf08313ae1cb0123b2.jpg"></p>    <p>呱呱卡开奖前</p>    <p><img src="https://simg.open-open.com/show/de89932c6bb1c3165892e71d1ea40888.jpg"></p>    <p>呱呱卡开奖后</p>    <h3>实现思路</h3>    <p>一张呱呱卡有三层,最底层我用一个TextView控件显示中奖内容,中间层是刮完之后的显示图样,最上面一层是刮刮卡的封面。手指刮除封面的过程就是把刮刮卡最上面一层裁剪的过程。</p>    <h3>涉及的知识点</h3>    <ol>     <li>canvas.clipPath(),Path类,Region.Op类</li>     <li>onDraw方法和onTouchEvent方法的配合</li>    </ol>    <p>核心代码如下:</p>    <pre>  <code class="language-java">public class LotteryView extends View {    public static final int STROKE_WIDTH = 15;    private float mEventX;  private float mEventY;    /**   * 呱呱卡封面 画笔   */  private Paint mOverlayPaint;  private RectF mRectBorder;  /**   * 呱呱卡边缘 画笔   */  private Paint mStrokePaint;  private RectF mRectFill;    private Path mClipPath;      public LotteryView(Context context) {      this(context,null,0);  }    public LotteryView(Context context, AttributeSet attrs) {      this(context, attrs, 0);  }    public LotteryView(Context context, AttributeSet attrs, int defStyleAttr) {      super(context, attrs, defStyleAttr);      init();  }      private void init() {      Bitmap lotteryOverlay = BitmapFactory.decodeResource(getResources(), R.drawable.icon_lottery_overlay);      mOverlayPaint = new Paint(Paint.ANTI_ALIAS_FLAG);      mOverlayPaint.setShader(new BitmapShader(lotteryOverlay, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT));        mStrokePaint = new Paint();      mStrokePaint.setAntiAlias(true);      mStrokePaint.setStyle(Paint.Style.STROKE);      mStrokePaint.setColor(Color.BLACK);      mStrokePaint.setStrokeWidth(STROKE_WIDTH);        mClipPath = new Path();  }    @Override  protected void onDraw(Canvas canvas) {      if (mRectBorder == null) {          mRectBorder = new RectF(0, 0, getWidth(), getHeight());      }      if (mRectFill == null) {          mRectFill = new RectF(0, 0, getWidth(), getHeight());      }        canvas.drawRoundRect(mRectBorder, 10, 10, mStrokePaint);        if (mEventX != 0 || mEventY != 0) {          mClipPath.addCircle(mEventX, mEventY, 50, Path.Direction.CW);          canvas.clipPath(mClipPath, Region.Op.DIFFERENCE);      }      canvas.drawRect(mRectFill, mOverlayPaint);  }    @Override  public boolean onTouchEvent(MotionEvent event) {      int action = event.getAction();      switch (action) {          case MotionEvent.ACTION_MOVE:              mEventX = event.getX();              mEventY = event.getY();              invalidate();              break;      }      return true;  }    }</code></pre>    <p>布局里的使用</p>    <pre>  <code class="language-xml"><RelativeLayout      android:layout_width="match_parent"      android:layout_height="120dp"      >        <TextView          android:id="@+id/tv_lottery_content"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:layout_centerInParent="true"          android:gravity="center"          android:textColor="@android:color/white"          android:textSize="20sp"          android:background="@android:color/darker_gray"          android:text="恭喜您,荣获2016年年度最佳程序员"          />      <com.sugary.roundimageview.LotteryView          android:layout_width="match_parent"          android:layout_height="120dp"          />  </RelativeLayout></code></pre>    <h3>小结</h3>    <ol>     <li>刮刮卡的中奖内容是放在TextView控件,作为最底层显示。</li>     <li>如果项目里需要有刮卡完成后回调,可以计算刮除的面积与刮刮卡总面积的比例,超过一定值,即认为呱卡完成。</li>     <li>后续的优化方向可以是,把底层的TextView放到LotteryView自定义控件里</li>    </ol>    <p> </p>    <p>来自:http://www.jianshu.com/p/2f17658eed60</p>    <p> </p>