美文网首页Android 成长笔记
Android 自定义 View 之使用 drawBitmapM

Android 自定义 View 之使用 drawBitmapM

作者: 赵者也 | 来源:发表于2017-04-17 23:07 被阅读20次

    本文参考文献:《疯狂Android讲义 : 第2版

    实例:可以揉动的图片

    下面的程序示例将会通过 drawBitmapMesh 方法来控制图片的扭曲,当用户“触摸”图片的指定点时,该图片会在这个点被用户“按”下去, —— 就像这张图片铺在“极软的床上”一样。

    package com.toby.personal.testlistview;
    
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.MotionEvent;
    import android.view.View;
    
    public class MainActivity extends AppCompatActivity {
    
        final private static String TAG = "Toby_Test";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(new TestView(this, R.drawable.img04));
        }
    
        class TestView extends View {
    
            // 定义两个常量,这两个常量将图片的横向、纵向划分20格
            private final int WIDTH = 20;
            private final int HEIGHT = 20;
    
            private final int COUNT = (WIDTH + 1) * (HEIGHT + 1);
    
            // 记录 Bitmap 上的 21 × 21 个点的坐标
            private final float[] orig = new float[COUNT * 2];
    
            // 记录 Bitmap 上的 21 × 21 个点经过扭曲之后的坐标
            // 对图片进行扭曲的关键就是修改该数组里面元素的值
            private final float[] verts = new float[COUNT * 2];
    
            private Bitmap bitmap;
    
            public TestView(Context context, int drawableId) {
                super(context);
                setFocusable(true);
    
                bitmap = BitmapFactory.decodeResource(getResources(), drawableId);
                float bitmapWidth = bitmap.getWidth();
                float bitmapHeight = bitmap.getHeight();
                int index = 0;
                for (int y = 0; y <= HEIGHT; ++y) {
                    float fy = bitmapHeight * y / HEIGHT;
                    for (int x = 0; x <= WIDTH; ++x) {
                        float fx = bitmapWidth * x / WIDTH;
                        orig[index * 2] = verts[index * 2] = fx;
                        orig[index * 2 + 1] = verts[index * 2 + 1] = fy;
                        index += 1;
                    }
                }
    
                setBackgroundColor(Color.WHITE);
            }
    
            @Override
            protected void onDraw(Canvas canvas) {
                super.onDraw(canvas);
                canvas.drawColor(Color.GRAY);
                canvas.drawBitmapMesh(bitmap, WIDTH, HEIGHT, verts, 0, null, 0, null);
            }
    
            private void warp(float cx, float cy) {
                for (int i = 0; i < COUNT * 2; i += 2) {
                    float dx = cx - orig[i];
                    float dy = cy - orig[i + 1];
                    float dd = dx * dx + dy * dy;
                    float d = (float) Math.sqrt(dd);
                    float pull = 80000 / ((float) (dd * d));
                    if (pull >= 1) {
                        verts[i] = cx;
                        verts[i + 1] = cy;
                    } else {
                        verts[i] = orig[i] + dx * pull;
                        verts[i + 1] = orig[i + 1] + dy * pull;
                    }
                }
                invalidate();
            }
    
            @Override
            public boolean onTouchEvent(MotionEvent event) {
                warp(event.getX(), event.getY());
                return super.onTouchEvent(event);
            }
        }
    
    }
    

    显示效果:


    显示效果

    相关文章

      网友评论

        本文标题:Android 自定义 View 之使用 drawBitmapM

        本文链接:https://www.haomeiwen.com/subject/xqxxzttx.html