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

Android Canvas之drawBitmap方法案例詳解

 更新時(shí)間:2021年08月26日 10:13:12   作者:怪毛大俠  
這篇文章主要介紹了Android Canvas之drawBitmap方法案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下

前面講了paint,后面會(huì)花幾篇主要講講canvas,并且由于最近項(xiàng)目比較緊,所以近期的文章都會(huì)“短小精悍”;

paint 作為畫筆,里面有非常多而強(qiáng)大的設(shè)置方法,比如設(shè)置顏色過濾器,設(shè)置位圖渲染、漸變,設(shè)置圖像的混合模式等等,而canvas呢?里面提供了哪些利器可以為我們所用,一起來看看:

     

   

通過上圖我們可以看到,canvas 里的方法基本可以分為這么幾類:

  1. save、restore 等與層的保存和回滾相關(guān)的方法;
  2. scale、rotate、clipXXX 等對(duì)畫布進(jìn)行操作的方法;
  3. drawXXX 等一系列繪畫相關(guān)的方法;

所以canvas 我們也就可以分上面三塊逐個(gè)擊破,今天咱們主要看 drawXXX里的drawBitmap,看完之后一起做一個(gè)漂浮星空的小栗子;

在Canvas 里 drawBitmap 有如下方法可用 :

而咱們也主要講其中的 drawBitmap(Bitmap,Rect,Rect,Paint);

首先咱們創(chuàng)建一個(gè)View,照舊重寫里面的 onMeasure、onDraw、onSizeChanged,并且在 onSizeChanged 里拿到view的寬高:

public class DrawBitmapView extends View {  
    private Resources mResources;  
    private Paint mBitPaint;  
    private Bitmap mBitmap;  
    private Rect mSrcRect, mDestRect;  
  
    // view 的寬高  
    private int mTotalWidth, mTotalHeight;  
  
    public DrawBitmapView(Context context) {  
        super(context);  
        mResources = getResources();  
        initBitmap();  
        initPaint();  
    }  
  
    private void initPaint() {  
        mBitPaint = new Paint(Paint.ANTI_ALIAS_FLAG);  
        mBitPaint.setFilterBitmap(true);  
        mBitPaint.setDither(true);  
    }  
  
    private void initBitmap() {  
        mBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.<span style="font-family: Arial, Helvetica, sans-serif;">beautiful_girl</span>))  
                .getBitmap();  
    }  
  
    @Override  
    protected void onDraw(Canvas canvas) {  
        super.onDraw(canvas);  
    }  
  
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
    }  
  
    @Override  
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {  
        super.onSizeChanged(w, h, oldw, oldh);  
        mTotalWidth = w;  
        mTotalHeight = h;  
    }  
}

上面我們通過

mBitmap = ((BitmapDrawable) mResources.getDrawable(R.drawable.<span style="font-family: Arial, Helvetica, sans-serif;">beautiful_girl</span>))  
                .getBitmap();

拿到了對(duì)應(yīng)的bitmap,這時(shí)候我們?nèi)绻獙⑺L制在屏幕上,需要?jiǎng)?chuàng)建兩個(gè)Rect,其實(shí)只要明白了這兩個(gè)Rect的意義并會(huì)靈活運(yùn)用就可以做出不少效果;

第一個(gè)Rect 代表要繪制的bitmap 區(qū)域,第二個(gè) Rect 代表的是要將bitmap 繪制在屏幕的什么地方,我們一起來看下:

此時(shí)我先定義兩個(gè)Rect,mSrcRect 取值為整個(gè)Bitmap 區(qū)域 ,mDestRect 取值為view左上方和bitmap同樣大小;

private Rect mSrcRect, mDestRect;
mSrcRect = new Rect(0, 0, mBitWidth, mBitHeight);  
mDestRect = new Rect(0, 0, mBitWidth, mBitHeight);

在onDraw 里繪制該位圖:

canvas.drawBitmap(mBitmap, mSrcRect, mDestRect, mBitPaint);

此時(shí)繪制效果如下,在屏幕的左上方出現(xiàn)了個(gè)美女:

畫在左上方似乎缺乏美感,我們把美女畫在view的中心,沒錯(cuò),我們只需要改變mDestRect:

// 計(jì)算左邊位置
int left = mHalfWidth - mBitWidth / 2;
// 計(jì)算上邊位置
int top = mHalfHeight - mBitHeight / 2;
mDestRect = new Rect(left, top, left + mBitWidth, top + mBitHeight);

位置計(jì)算的時(shí)候,只需要注意在android屏幕坐標(biāo)系里,左上角的位置是(0,0),往右往下為正,此時(shí)效果如下:

既然可以如此輕易的改變繪制的位置,那咱們不斷的改變bitmap繪制的位置,模擬一下translate效果;

我們向外提供兩個(gè)接口:

public void startTranslate() {
        startTranslate(0, 0, 200, 200, 1000);
    }
 
    /**
     * 移動(dòng)位圖
     * 
     * @param startLeft 起始左邊距
     * @param startTop 起始距上邊距離
     * @param toLeft 到達(dá)左邊距
     * @param toTop 到達(dá)上邊距
     * @param duration 時(shí)長(zhǎng)
     */
    public void startTranslate(int startLeft, int startTop, int toLeft, int toTop, long duration) {
        mStartLeft = startLeft;
        mStartTop = startTop;
 
        mToLeft = toLeft;
        mToTop = toTop;
 
        // 使用ValueAnimator創(chuàng)建一個(gè)過程
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.setDuration(duration);
        valueAnimator.setInterpolator(new AccelerateInterpolator());
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
 
            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                // 不斷重新計(jì)算上下左右位置
                float fraction = (Float) animator.getAnimatedValue();
                int currentLeft = (int) ((mToLeft - mStartLeft) * fraction + mStartLeft);
                int currentTop = (int) ((mToTop - mStartTop) * fraction + mStartTop);
                if (mDestRect == null) {
                    mDestRect = new Rect(currentLeft, currentTop, currentLeft + mBitWidth,
                            currentTop + mBitHeight);
                }
                mDestRect.left = currentLeft;
                mDestRect.right = currentLeft + mBitWidth;
                mDestRect.top = currentTop;
                mDestRect.bottom = currentTop + mBitHeight;
                // 重繪
                postInvalidate();
            }
        });
        valueAnimator.start();
    }

Activity 里控制view的移動(dòng):

final DrawBitmapView drawBitmapView = new DrawBitmapView(this);
        setContentView(drawBitmapView, new LayoutParams(LayoutParams.MATCH_PARENT,
                LayoutParams.MATCH_PARENT));
        drawBitmapView.startTranslate();
        drawBitmapView.setOnTouchListener(new OnTouchListener() {
 
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                Random random = new Random();
                int startLeft = random.nextInt(200);
                int startTop = random.nextInt(250);
                int toLeft = random.nextInt(550) + 200;
                int toBottom = random.nextInt(1000) + 250;
                drawBitmapView.startTranslate(startLeft, startTop, toLeft, toBottom, 1000);
                return true;
            }
        });
 
    }

點(diǎn)擊之后起始點(diǎn)和到達(dá)點(diǎn)隨機(jī)生成,此時(shí)效果如下:

相信到這里大家已經(jīng)能靈活控制bitmap的位置了,順勢(shì)咱們?cè)僮鰝€(gè)水平縮放為0的小例子:

public void startScale(long duration) {
 
        // 使用ValueAnimator創(chuàng)建一個(gè)過程
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(1, 0);
        valueAnimator.setDuration(duration);
        valueAnimator.setInterpolator(new AccelerateInterpolator());
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
 
            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                // 不斷重新計(jì)算上下左右位置
                float fraction = (Float) animator.getAnimatedValue();
                if (mDestRect == null) {
                    mDestRect = new Rect(0, 0, mBitWidth,
                            mBitHeight);
                }
                mDestRect.right = (int) (fraction * mBitWidth);
                // 重繪
                postInvalidate();
            }
        });
        valueAnimator.start();
    }

只需要不斷減小mDestRect.right即可,非常簡(jiǎn)單,看下效果:

      上面兩個(gè)例子都是通過改變mDestRect ,在哪些時(shí)候我們需要?jiǎng)討B(tài)改變mSrcRect 呢?我前面講過一個(gè)水波紋的例子,那里面就是不斷截取水波紋的一部分,進(jìn)行展示,由于是連續(xù)截取,所以視覺感受上是連續(xù)波紋效果,有興趣的同學(xué)可以看看參考下; 

    好了本篇就講這么多,有些同學(xué)可能會(huì)想,尼瑪,這么簡(jiǎn)單的玩意兒能做毛線牛逼動(dòng)效啊,其實(shí)往往再復(fù)雜的動(dòng)效也就是由一個(gè)個(gè)小點(diǎn)組成的,而思路和方案的選取就已經(jīng)決定了能否成功的做出酷炫又如絲般順滑的效果,好的思路又往往來源于對(duì)簡(jiǎn)單方法的深刻理解

到此這篇關(guān)于Android Canvas之drawBitmap方法案例詳解的文章就介紹到這了,更多相關(guān)Android Canvas之drawBitmap方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Android自定義View實(shí)現(xiàn)兩種二維碼的掃描效果

    Android自定義View實(shí)現(xiàn)兩種二維碼的掃描效果

    這篇文章主要為大家詳細(xì)介紹了Android如何自定義View實(shí)現(xiàn)兩種二維碼的掃描效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • Android實(shí)現(xiàn)圖片預(yù)覽與保存功能

    Android實(shí)現(xiàn)圖片預(yù)覽與保存功能

    在App開發(fā)中,通常為了省流提高加載速度提升用戶體驗(yàn)我們通常在列表中或新聞中的插圖都是以縮略圖壓縮過的圖片來進(jìn)行展示,當(dāng)用戶點(diǎn)擊圖片時(shí)我們?cè)偃ゼ虞d真正像素的大圖讓用戶預(yù)覽。本文將利用Flutter實(shí)現(xiàn)這一功能,需要的可以參考一下
    2022-04-04
  • Android ActionBar使用教程

    Android ActionBar使用教程

    這篇文章主要為大家分享了Android ActionBar使用教程,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Android仿微信語音聊天界面設(shè)計(jì)

    Android仿微信語音聊天界面設(shè)計(jì)

    這篇文章主要為大家詳細(xì)介紹了Android仿微信語音聊天界面設(shè)計(jì)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Android貝塞爾曲線實(shí)現(xiàn)手指軌跡

    Android貝塞爾曲線實(shí)現(xiàn)手指軌跡

    這篇文章主要為大家詳細(xì)介紹了Android貝塞爾曲線實(shí)現(xiàn)手指軌跡效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • Android ImageView 固定寬高比例的實(shí)現(xiàn)方法

    Android ImageView 固定寬高比例的實(shí)現(xiàn)方法

    這篇文章主要介紹了Android ImageView 固定寬高比例的實(shí)現(xiàn)方法的相關(guān)資料,,方法一:設(shè)置 adjustViewBounds="true",方法二:使用 Universal-Image-Loader 圖片緩存類,需要注意的是方法二和方法一同時(shí)使用導(dǎo)致設(shè)置無效,需要的朋友可以參考下
    2017-07-07
  • Android帶清除按鈕、密碼可見小眼睛的輸入框

    Android帶清除按鈕、密碼可見小眼睛的輸入框

    這篇文章主要介紹了Android帶清除按鈕、密碼可見小眼睛的輸入框,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • RecyclerView的萬能分割線

    RecyclerView的萬能分割線

    RecyclerView 是Android L版本中新添加的一個(gè)用來取代ListView的SDK,它的靈活性與可替代性比listview更好。本文重點(diǎn)給大家介紹RecyclerView的萬能分割線的知識(shí),非常不錯(cuò),感興趣的朋友一起看下吧
    2016-07-07
  • Android中自定義PopupWindow實(shí)現(xiàn)彈出框并帶有動(dòng)畫效果

    Android中自定義PopupWindow實(shí)現(xiàn)彈出框并帶有動(dòng)畫效果

    這篇文章主要介紹了Android中自定義PopupWindow實(shí)現(xiàn)彈出框并帶有動(dòng)畫效果的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • 解析:android 如何從JPEG生成BufferedImage

    解析:android 如何從JPEG生成BufferedImage

    本篇文章是對(duì)在android中,如何從JPEG生成BufferedImage的解決方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06

最新評(píng)論