自定义View(本篇讲解Matrix,自定义属性),消蒙版小游戏

来源:互联网 发布:淘宝店铺怎么推广 编辑:程序博客网 时间:2024/05/09 20:27

先说要求:实现如下效果

这里写图片描述
(由于电脑特别卡,看起来不流畅,在手机上试过很流畅的)

接下来说一下具体做法:

1、layout下的布局文件

</RelativeLayout><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:mystyle="http://schemas.android.com/apk/res-auto"//声明自定义属性    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context=".MainActivity">    <com.my.administrator.zdyview.BitmapView2//这个名字BitmapView2要与view类名相同        android:id="@+id/view"        android:layout_width="match_parent"        android:layout_height="match_parent"        mystyle:myview_background="@mipmap/meinv4"//设置自定义属性        mystyle:myview_paintwidth="30dp" />//设置自定义属性    <Button        android:id="@+id/button"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:background="#ffccff"        android:text="保存" />//点击保存按钮</RelativeLayout>

2、写BitmapView2 类继承View,加构造器,重写onMeasure,onDraw方法,在onDraw方法里面画东西

public class BitmapView2 extends View {    private int width;    private int height;    private Paint mPaintMeng;    private Paint mPaintRect;    private Bitmap mBitmap;    private Canvas mCanvas;    private Bitmap mBitmapImage;    private Matrix matrix;    private Path mPath;//两个构造器    public BitmapView2(Context context) {        super(context);    }    public BitmapView2(Context context, AttributeSet attrs) {        super(context, attrs);        //下面几行代码是对自定义属性的设置        final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.mystyle);//解析xml,解析方式为value文件夹下mystyle        BitmapDrawable dra = (BitmapDrawable) a.getDrawable(R.styleable.mystyle_myview_background);//得到layout下xml文件传的myview_background        if (dra != null) {//如果在xml中传入了图片            mBitmapImage = dra.getBitmap();        } else {//若没有传图片,则在下面设置添加            mBitmapImage = BitmapFactory.decodeResource(getResources(), R.mipmap.me);        }        int paintWidth = a.getDimensionPixelOffset(R.styleable.mystyle_myview_paintwidth, 10);//得到xml中设置的画笔宽度属性,设置默认10        mPaintMeng = new Paint();//画蒙板的画笔        mPaintMeng.setColor(Color.GREEN);        mPaintRect = new Paint();//画bitmap的画笔        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);        mPaintRect.setXfermode(mode);        mPaintRect.setStrokeJoin(Paint.Join.ROUND);//设置连接部分样式        mPaintRect.setStrokeCap(Paint.Cap.ROUND);//设置中间部分的样式        mPaintRect.setStrokeWidth(paintWidth);//设置画笔宽度属性        mPaintRect.setStyle(Paint.Style.FILL_AND_STROKE);//去掉锯齿        matrix = new Matrix();//初始化矩阵        mPath = new Path();    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);        setMeasuredDimension(width, height);        mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);//设置Bitmap的大小        mCanvas = new Canvas(mBitmap);//自定义的画布    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        matrix.reset();        matrix.postScale((float) width / mBitmapImage.getWidth(), (float) height / mBitmapImage.getHeight());//放大到整个bitview界面        canvas.drawBitmap(mBitmapImage, matrix, null);//图片        mCanvas.drawRect(0, 0, width, height, mPaintMeng);//蒙板        mCanvas.drawPath(mPath, mPaintRect);//画点击时的圆,画笔为XOR透明        canvas.drawBitmap(mBitmap, 0, 0, null);//相当于底版    }    float x;    float y;    float old_x;    float old_y;    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()) {            case MotionEvent.ACTION_DOWN:                x = event.getX();                y = event.getY();                mPath.moveTo(x, y);                invalidate();                old_x = x;                old_y = y;                return true;            case MotionEvent.ACTION_MOVE:                x = event.getX();                y = event.getY();                mPath.moveTo(old_x, old_y);                mPath.lineTo(x, y);//也可以写下面的代码                // mPath.quadTo((x+old_x)/2,(y+old_y)/2,x,y);                invalidate();                old_x = x;                old_y = y;                break;        }        return super.onTouchEvent(event);    }}

3、Activity文件,布局文件中有保存按钮,实现点击按钮时保存当前的图片

public class MainActivity extends AppCompatActivity {   private Button mButton;   private  BitmapView2 bitmapView2;  @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        bitmapView2 = (BitmapView2) findViewById(R.id.view);        mButton = (Button) findViewById(R.id.button);        mButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                bitmapView2.setDrawingCacheEnabled(true);//要获取cache首先要通过setDrawingCacheEnable方法开启cache,                // 然后再调用getDrawingCache方法就可以获得view的cache图片了。                Bitmap bit = bitmapView2.getDrawingCache(true);                File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");//保存图片到这个路径                if(!file.exists()){                    try {                        file.createNewFile();                    } catch (IOException e) {                        e.printStackTrace();                    }                }                try {                    bit.compress(Bitmap.CompressFormat.JPEG,100,new FileOutputStream(file));                } catch (FileNotFoundException e) {                    e.printStackTrace();                }            }        });

4、在这个布局文件中用到了自定义属性,那么,怎样实现自定义属性?

《1》在values文件夹下新建resource file

<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="mystyle">//styleable的名字       //下面定义几个属性,包括名字和参数值类型        <attr name="myview_background" format="reference"></attr>        <attr name="myview_paintwidth" format="dimension|reference"></attr>    </declare-styleable></resources>

《2》在layout的xml布局文件中声明,设置自定义属性,见layout下的布局文件加注释的部分
《3》在view类中解析layout下xml布局文件,解析方式为value文件夹下mystyle,并找到xml布局文件的设置。详情见上面BitmapView2类中对自定义属性的设置代码

0 0
原创粉丝点击