Canvas配合MotionEvent實現畫板功能
阿新 • • 發佈:2018-10-31
最近在學習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>
這樣,一個簡易的畫板功能就實現了。