Canvas配合MotionEvent实现画板功能

      最近在学习Android中关于控件滑动以及2D绘制图形API,所以就简单的结合了两者做了一个简易的画板功能,很多画板都是通过自定义View或者SurfaceView来实现,在后续我也会做,但是今天就简单的用Bitmap创建Canvas然后通过ImageView的形式展示一下。下面先来看一下效果:

1,实现思路

我们的这里的思路很简单,主要分为以下几个步骤:

第一步:创建一个装载画板的控件(ImageView);

第二步:创建一个和控件一样大小的画布(Bitmap)并装载在画板(Canvas)上

第三步:实现两者坐标完全一致

第四步:监听控件(ImageView)的MotionEvent事件,获取坐标信息在画布(Bitmap)上作画;

第五步:绘制完成放在控件上,感觉就像在控件上绘制一样的效果

可见,这是一种模拟实现自定义View 的效果。

2,示例代码

MainActivity代码:

package com.hfut.simpledrawer;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.Spinner;


/**
 * @author why
 * @date 2018-8-28 20:24:16
 */
public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    ImageView displayWindow;
    Bitmap bitmap;
    Spinner colorSpinner;
    Spinner widthSpinner;
    float lastX = 0.0f;
    float lastY = 0.0f;

    int color;
    int width;
    Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
        bitmap = Bitmap.createBitmap(getScreenWidth(), 600, Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas(bitmap);
        final Paint paint = new Paint();

        handler=new Handler(){
            @Override
            public void handleMessage(Message msg) {
                canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
            }
        };

        colorSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                //Toast.makeText(MainActivity.this,""+position,Toast.LENGTH_SHORT).show();
                switch (position){
                    case 0:
                        color=Color.RED;
                        break;
                    case 1:
                        color=Color.RED;
                        break;
                    case 2:
                        color=Color.BLUE;
                        break;
                    case 3:
                        color=Color.YELLOW;
                        break;
                    case 4:
                        color=Color.BLACK;
                        break;
                    default:
                        break;
                }
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        widthSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                if(position!=0) {
                    width = position + 1;
                }
                else{
                    width=1;
                }
                }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });

        displayWindow.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int x = (int) event.getX();
                int y = (int) event.getY();
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        paint.setColor(color);
                        paint.setStrokeWidth(width);
                        x = (int) event.getX();
                        y = (int) event.getY();
                        lastX = x;
                        lastY = y;
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.d(TAG, "onTouch: " + System.currentTimeMillis());
                        canvas.drawLine(lastX, lastY, x, y, paint);
                        lastX = x;
                        lastY = y;
                        displayWindow.setImageBitmap(bitmap);
                        break;
                    case MotionEvent.ACTION_UP:
                        break;
                    default:
                        break;
                }
                return true;
            }
        });
    }

    private void initUI() {
        displayWindow = findViewById(R.id.display_window);
        colorSpinner = findViewById(R.id.paint_color);
        widthSpinner = findViewById(R.id.paint_width);
    }


    //清除画布
    public void clearDrawer(View view){
        displayWindow.setImageBitmap(null);
        Message message=new Message();
        handler.sendMessage(message);
    }

    //获取显示屏宽度
    public int getScreenWidth(){
        WindowManager manager = getWindowManager();
        DisplayMetrics metrics = new DisplayMetrics();
        manager.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }
}



activity_main.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.hfut.simpledrawer.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:background="#DCDCDC"
        android:padding="10px">

        <ImageView
            android:id="@+id/display_window"
            android:layout_width="match_parent"
            android:layout_height="600px" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:orientation="horizontal"
        android:weightSum="3">

        <Spinner
            android:id="@+id/paint_color"
            android:layout_width="0dip"
            android:layout_height="30dp"
            android:layout_marginLeft="20dp"
            android:layout_weight="1"
            android:background="#FFC0CB"
            android:entries="@array/paintcolor" />

        <Spinner
            android:id="@+id/paint_width"
            android:layout_width="0dip"
            android:layout_height="30dp"
            android:layout_marginLeft="10dp"
            android:layout_weight="1"
            android:background="#B0E0E6"
            android:entries="@array/paintwidth" />

        <Button
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_marginLeft="50dp"
            android:layout_weight="0.5"
            android:onClick="clearDrawer"
            android:text="清除" />

    </LinearLayout>

</LinearLayout>

values文件夹下画笔属性参数文件paintattr.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="paintcolor">
        <item>颜色</item>>
        <item>红色</item>
        <item>蓝色</item>
        <item>黄色</item>
        <item>黑色</item>
    </string-array>

    <string-array name="paintwidth">
        <item>粗细</item>
        <item>1</item>
        <item>2</item>
        <item>3</item>
        <item>4</item>
        <item>5</item>
        <item>6</item>
        <item>7</item>
        <item>8</item>
        <item>9</item>
        <item>10</item>
    </string-array>
</resources>

这样,一个简易的画板功能就实现了。

猜你喜欢

转载自blog.csdn.net/hfut_why/article/details/82228383