欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android通過自定義view實(shí)現(xiàn)刮刮樂效果詳解

 更新時(shí)間:2022年03月29日 08:55:33   作者:吐爾洪江Coding  
這篇文章主要介紹了如何在Android中利用自定義的view實(shí)現(xiàn)刮刮樂的效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟上小編一起動(dòng)手試一試

前言

已經(jīng)有兩個(gè)月沒有更新博客了,其實(shí)這篇文章我早在兩個(gè)月前就寫好了,一直保存在草稿箱里沒有發(fā)布出來。原因是有一些原理性的東西還沒了解清楚,最近抽時(shí)間研究了一下混合模式,終于也理解了刮刮樂是怎么實(shí)現(xiàn)的,所以想繼續(xù)分享一下自己的一些心得,先上效果圖。

效果圖:

實(shí)現(xiàn)原理

其實(shí)刮刮樂實(shí)現(xiàn)原理也不算很復(fù)雜,最關(guān)鍵的還是需要了解Paint的混合模式。因?yàn)楣喂螛肥怯蓛蓚€(gè)bitmap組成的,一個(gè)是源圖另一個(gè)是目標(biāo)圖,我們需要把目標(biāo)圖的顏色改成灰色,在源圖上面蓋上了一張灰色的目標(biāo)圖。當(dāng)手指滑動(dòng)屏幕時(shí)paint會(huì)在新的canvas上畫出路徑,由于新的canvas會(huì)持有一個(gè)新的bitmap,最終兩個(gè)bitmap的像素點(diǎn)重疊時(shí)就顯示源圖的部分,從而實(shí)現(xiàn)了刮刮樂的效果。這里用的是混合模式中的PorterDuff.Mode.DST_IN。

關(guān)鍵代碼:

pathPaint.setXfermode(new PorterDuffXfermode((PorterDuff.Mode.DST_IN)));

關(guān)鍵步驟

創(chuàng)建bitmap

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmapBackground = getBitmap(mBitmapBackground, w, h);
        mBitmapFront = Bitmap.createBitmap(mBitmapBackground.getWidth(),
                mBitmapBackground.getHeight(), Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmapFront);
        drawText(mCanvas, w, h);
    }

onSizeChanged方法里面創(chuàng)建了兩個(gè)bitmap,一個(gè)是背景圖,另一個(gè)是覆蓋在背景圖上面的bitmap。然后是在上面的bitmap上面繪制文字。

繪制文字

    private void drawText(Canvas canvas, int mWidth, int mHeight) {
        String text = "趕緊刮開吧";
        canvas.drawColor(Color.GRAY);
        Paint.FontMetrics fm = mPaintText.getFontMetrics();
        int mTxtWidth = (int) mPaintText.measureText(text, 0, text.length());
        int mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);
        int x = mWidth / 2 - mTxtWidth / 2; //文字在畫布中的x坐標(biāo)
        int y = mHeight / 2 + mTxtHeight / 4; //文字在畫布中的y坐標(biāo)
        canvas.drawText(text, x, y, mPaintText);
    }

調(diào)用canvas的drawText方法繪制文字,x,y是文字中心位置的坐標(biāo)。測(cè)量文字寬高有兩種方式,這里用的是更精確的getFontMetrics方法。

畫路徑

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.reset();
                path.moveTo(event.getX(), event.getY());//原點(diǎn)移動(dòng)至手指的觸摸點(diǎn)
                break;
            case MotionEvent.ACTION_MOVE:
                path.lineTo(event.getX(), event.getY());
                break;
        }
        mCanvas.drawPath(path, pathPaint);
        invalidate();
        return true;
    }

最終效果圖

完整代碼

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
 
import androidx.annotation.Nullable;
 
import com.example.androidprogressbar.R;
 
public class ScratchCard extends View {
 
    private Bitmap mBitmapBackground;
    private Bitmap mBitmapFront;
    private Canvas mCanvas;
    private Paint pathPaint;
    private Path path;
    private Paint mPaintText;
 
    public ScratchCard(Context context) {
        super(context);
        init();
    }
 
    public ScratchCard(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }
 
    public ScratchCard(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
 
    private void init() {
        pathPaint = new Paint();
        pathPaint.setAlpha(0);
        pathPaint.setStyle(Paint.Style.STROKE);
        pathPaint.setStrokeWidth(70);
        pathPaint.setXfermode(new PorterDuffXfermode((PorterDuff.Mode.DST_IN)));//混合模式
        pathPaint.setStrokeJoin(Paint.Join.ROUND);//線段之間連接處的樣式
        pathPaint.setStrokeCap(Paint.Cap.ROUND);//設(shè)置畫筆的線冒樣式
        path = new Path();
        mBitmapBackground = BitmapFactory.decodeResource(getResources(), R.drawable.card);
        mCanvas = new Canvas();
        mPaintText = new Paint();
        mPaintText.setColor(Color.WHITE);
        mPaintText.setTextSize(100);
        mPaintText.setStrokeWidth(20);
    }
 
    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawBitmap(mBitmapBackground, 0, 0, null);
        canvas.drawBitmap(mBitmapFront, 0, 0, null);
    }
 
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mBitmapBackground = getBitmap(mBitmapBackground, w, h);
        mBitmapFront = Bitmap.createBitmap(mBitmapBackground.getWidth(),
                mBitmapBackground.getHeight(), Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(mBitmapFront);
        drawText(mCanvas, w, h);
    }
 
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                path.reset();
                path.moveTo(event.getX(), event.getY());//原點(diǎn)移動(dòng)至手指的觸摸點(diǎn)
                break;
            case MotionEvent.ACTION_MOVE:
                path.lineTo(event.getX(), event.getY());
                break;
        }
        mCanvas.drawPath(path, pathPaint);
        invalidate();
        return true;
    }
 
    private void drawText(Canvas canvas, int mWidth, int mHeight) {
        String text = "趕緊刮開吧";
        canvas.drawColor(Color.GRAY);
        Paint.FontMetrics fm = mPaintText.getFontMetrics();
        int mTxtWidth = (int) mPaintText.measureText(text, 0, text.length());
        int mTxtHeight = (int) Math.ceil(fm.descent - fm.ascent);
        int x = mWidth / 2 - mTxtWidth / 2; //文字在畫布中的x坐標(biāo)
        int y = mHeight / 2 + mTxtHeight / 4; //文字在畫布中的y坐標(biāo)
        canvas.drawText(text, x, y, mPaintText);
    }
 
    public Bitmap getBitmap(Bitmap bm, int newWidth, int newHeight) {
        // 獲得圖片的寬高
        int width = bm.getWidth();
        int height = bm.getHeight();
        // 計(jì)算縮放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要縮放的matrix參數(shù)
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的圖片
        Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
        return newbm;
    }
 
}

以上就是Android通過自定義view實(shí)現(xiàn)刮刮樂效果詳解的詳細(xì)內(nèi)容,更多關(guān)于Android刮刮樂的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • android屏幕圓角實(shí)現(xiàn)方法的示例代碼

    android屏幕圓角實(shí)現(xiàn)方法的示例代碼

    本篇文章主要介紹了android屏幕圓角實(shí)現(xiàn)方法的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-11-11
  • Android控件ListView使用方法詳解

    Android控件ListView使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了Android控件ListView的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Android 應(yīng)用的全屏和非全屏實(shí)現(xiàn)代碼

    Android 應(yīng)用的全屏和非全屏實(shí)現(xiàn)代碼

    這篇文章主要介紹了Android 應(yīng)用的全屏和非全屏實(shí)現(xiàn)代碼的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Android開發(fā)之完全隱藏軟鍵盤的方法

    Android開發(fā)之完全隱藏軟鍵盤的方法

    這篇文章主要介紹了Android開發(fā)之完全隱藏軟鍵盤的方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • Android如何禁止橫屏豎屏的變換

    Android如何禁止橫屏豎屏的變換

    android4.0 禁止橫豎屏切換使:android:configChanges="orientation|keyboardHidden|screenSize" 感興趣的朋友可以了解下哈
    2013-06-06
  • android viewpager實(shí)現(xiàn)豎屏滑動(dòng)效果

    android viewpager實(shí)現(xiàn)豎屏滑動(dòng)效果

    這篇文章主要為大家詳細(xì)介紹了android viewpager實(shí)現(xiàn)豎屏滑動(dòng)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • 總結(jié)Android App內(nèi)存優(yōu)化之圖片優(yōu)化

    總結(jié)Android App內(nèi)存優(yōu)化之圖片優(yōu)化

    網(wǎng)上有很多大拿分享的關(guān)于Android性能優(yōu)化的文章,主要是通過各種工具分析,使用合理的技巧優(yōu)化APP的體驗(yàn),提升APP的流暢度,但關(guān)于內(nèi)存優(yōu)化的文章很少有看到。下面是我在實(shí)踐過程中使用的一些方法,很多都是不太成熟的項(xiàng)目,只是將其作為一種處理方式分享給大家。
    2016-08-08
  • 關(guān)于Android Activity之間跳轉(zhuǎn)問題(Intent)

    關(guān)于Android Activity之間跳轉(zhuǎn)問題(Intent)

    這篇文章主要介紹了Android Activity之間跳轉(zhuǎn)Intent,當(dāng)一個(gè)Acitivity需要啟動(dòng)另一個(gè)Activity時(shí),通過Intent來表達(dá)自己的意圖,告知系統(tǒng)啟動(dòng)哪個(gè)Activity,本文給大家詳細(xì)講解,需要的朋友可以參考下
    2022-10-10
  • 實(shí)例詳解Android 獲取短信會(huì)話列表

    實(shí)例詳解Android 獲取短信會(huì)話列表

    本文通過實(shí)例詳解android獲取短信會(huì)話列表的全部?jī)?nèi)容,涉及到android獲取短信列表的相關(guān)知識(shí),對(duì)android會(huì)話列表相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2015-12-12
  • Android Web3j OOM解決詳解

    Android Web3j OOM解決詳解

    這篇文章主要介紹了Android Web3j OOM解決詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07

最新評(píng)論