1.首先我们编写布局文件activity_main.xml如下:
-
1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 tools:context="com.himi.painter.MainActivity" > 6 <ImageView 7 android:layout_width="match_parent" 8 android:layout_height="match_parent" 9 android:id="@+id/iv" /> 10 </RelativeLayout>
2.初步编写MainActivity.java,如下:
-
1 package com.himi.painter; 2 import android.app.Activity; 3 import android.graphics.Bitmap; 4 import android.graphics.Canvas; 5 import android.graphics.Color; 6 import android.graphics.Paint; 7 import android.os.Bundle; 8 import android.view.MotionEvent; 9 import android.view.View; 10 import android.view.View.OnTouchListener; 11 import android.widget.ImageView; 12 public class MainActivity extends Activity { 13 private ImageView iv; 14 private Canvas canvas; 15 private Paint paint; 16 private Bitmap bitmap; 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 21 iv = (ImageView) findViewById(R.id.iv); 22 //创建一个空白的图片,以图片为模板创建一个画板 23 bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888); 24 //创建画板 25 canvas = new Canvas(bitmap); 26 //创建画笔 27 paint = new Paint(); 28 paint.setColor(Color.BLACK); 29 30 canvas.drawColor(0x22888888); 31 iv.setImageBitmap(bitmap); 32 iv.setOnTouchListener(new OnTouchListener() { 33 //手在屏幕上的初始化坐标 34 int startX; 35 int startY; 36 public boolean onTouch(View v, MotionEvent event) { 37 switch (event.getAction()) { 38 case MotionEvent.ACTION_DOWN://手指按下 39 startX = (int) event.getX(); 40 startY = (int) event.getY(); 41 break; 42 case MotionEvent.ACTION_MOVE://手指滑动 43 int newX = (int) event.getX(); 44 int newY = (int) event.getY(); 45 canvas.drawLine(startX, startY, newX, newY, paint); 46 //重新更新UI 47 iv.setImageBitmap(bitmap); 48 break; 49 case MotionEvent.ACTION_UP://手指离开屏幕 50 break; 51 } 52 53 return true ;//true ---表示监听事件处理完了, false---表示没有出来完监听事件 54 } 55 }); 56 } 57 }
运行效果如下:
这个画板程序是有问题的,就是他开始固定了划线的起始点(就是我们刚刚接触屏幕的点),然后就像如图那样好像散射一样。这是不行的。我们要不断地更新我们的划线的起始点;
MainActivity修改如下:
-
1 package com.himi.painter; 2 import android.app.Activity; 3 import android.graphics.Bitmap; 4 import android.graphics.Canvas; 5 import android.graphics.Color; 6 import android.graphics.Paint; 7 import android.os.Bundle; 8 import android.view.MotionEvent; 9 import android.view.View; 10 import android.view.View.OnTouchListener; 11 import android.widget.ImageView; 12 public class MainActivity extends Activity { 13 private ImageView iv; 14 private Canvas canvas; 15 private Paint paint; 16 private Bitmap bitmap; 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.activity_main); 21 iv = (ImageView) findViewById(R.id.iv); 22 //创建一个空白的图片,以图片为模板创建一个画板 23 bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888); 24 //创建画板 25 canvas = new Canvas(bitmap); 26 //创建画笔 27 paint = new Paint(); 28 paint.setColor(Color.BLACK); 29 30 canvas.drawColor(0x22888888); 31 iv.setImageBitmap(bitmap); 32 iv.setOnTouchListener(new OnTouchListener() { 33 //手在屏幕上的初始化坐标 34 int startX; 35 int startY; 36 public boolean onTouch(View v, MotionEvent event) { 37 switch (event.getAction()) { 38 case MotionEvent.ACTION_DOWN://手指按下 39 startX = (int) event.getX(); 40 startY = (int) event.getY(); 41 break; 42 case MotionEvent.ACTION_MOVE://手指滑动 43 int newX = (int) event.getX(); 44 int newY = (int) event.getY(); 45 canvas.drawLine(startX, startY, newX, newY, paint); 46 //重新更新UI 47 iv.setImageBitmap(bitmap); 48 //很重要,重新给开始坐标赋值 49 startX = (int) event.getX(); 50 startY = (int) event.getY(); 51 break; 52 case MotionEvent.ACTION_UP://手指离开屏幕 53 break; 54 } 55 56 return true ;//true ---表示监听事件处理完了, false---表示没有出来完监听事件 57 } 58 }); 59 } 60 }
这时候画图板就正常了,如下:
3.画图板只能一种颜色,太单调,我们完善一下:
其中 activity_main.xml:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context="com.himi.painter.MainActivity" > 7 <ImageView 8 android:id="@+id/iv" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" /> 11 <LinearLayout 12 android:layout_width="match_parent" 13 android:layout_height="wrap_content" 14 android:orientation="horizontal" > 15 <View 16 android:id="@+id/red" 17 android:layout_width="20dip" 18 android:layout_height="20dip" 19 android:background="#ff0000"/> 20 <View 21 android:id="@+id/green" 22 android:layout_width="20dip" 23 android:layout_height="20dip" 24 android:background="#00ff00"/> 25 <View 26 android:id="@+id/blue" 27 android:layout_width="20dip" 28 android:layout_height="20dip" 29 android:background="#0000ff" /> 30 31 </LinearLayout> 32 <!-- android:max="20" 进度条范围对应于 这里是针对画笔粗细范围设置为0~20 --> 33 <SeekBar 34 android:id="@+id/seekBar1" 35 android:max="100" 36 android:layout_width="match_parent" 37 android:layout_height="wrap_content" /> 38 <Button 39 android:onClick="save" 40 android:layout_width="match_parent" 41 android:layout_height="wrap_content" 42 android:text="保存图片"/> 43 44 45 </LinearLayout>
其次是MainActivity.java:
1 package com.himi.painter; 2 import java.io.File; 3 import java.io.FileOutputStream; 4 import android.app.Activity; 5 import android.content.Intent; 6 import android.graphics.Bitmap; 7 import android.graphics.Bitmap.CompressFormat; 8 import android.graphics.Canvas; 9 import android.graphics.Color; 10 import android.graphics.Paint; 11 import android.net.Uri; 12 import android.os.Bundle; 13 import android.os.Environment; 14 import android.os.SystemClock; 15 import android.view.MotionEvent; 16 import android.view.View; 17 import android.view.View.OnClickListener; 18 import android.view.View.OnTouchListener; 19 import android.widget.ImageView; 20 import android.widget.SeekBar; 21 import android.widget.SeekBar.OnSeekBarChangeListener; 22 import android.widget.Toast; 23 public class MainActivity extends Activity implements OnClickListener { 24 private ImageView iv; 25 private Canvas canvas; 26 private Paint paint; 27 private Bitmap bitmap; 28 private View red,green,blue; 29 private SeekBar seekBar1; 30 @Override 31 protected void onCreate(Bundle savedInstanceState) { 32 super.onCreate(savedInstanceState); 33 setContentView(R.layout.activity_main); 34 iv = (ImageView) findViewById(R.id.iv); 35 seekBar1 = (SeekBar) findViewById(R.id.seekBar1); 36 red = (View) findViewById(R.id.red); 37 green = (View) findViewById(R.id.green); 38 blue = (View) findViewById(R.id.blue); 39 40 red.setOnClickListener(this); 41 green.setOnClickListener(this); 42 blue.setOnClickListener(this); 43 44 seekBar1.setOnSeekBarChangeListener(new OnSeekBarChangeListener() { 45 46 public void onStopTrackingTouch(SeekBar seekBar) {//停止拖动进度条,调用的方法 47 int size = seekBar.getProgress(); 48 //设置画笔的粗细 49 paint.setStrokeWidth(size); 50 } 51 52 public void onStartTrackingTouch(SeekBar seekBar) {//刚刚接触进度条,调用的方法 53 // TODO 自动生成的方法存根 54 55 } 56 57 public void onProgressChanged(SeekBar seekBar, int progress, 58 boolean fromUser) {//拖动进度条过程中,调用的方法 59 // TODO 自动生成的方法存根 60 61 } 62 }); 63 64 //创建一个空白的图片,以图片为模板创建一个画板 65 bitmap = Bitmap.createBitmap(300, 300, Bitmap.Config.ARGB_8888); 66 //创建画板 67 canvas = new Canvas(bitmap); 68 //创建画笔 69 paint = new Paint(); 70 paint.setColor(Color.BLACK); 71 72 canvas.drawColor(0x22888888); 73 iv.setImageBitmap(bitmap); 74 iv.setOnTouchListener(new OnTouchListener() { 75 //手在屏幕上的初始化坐标 76 int startX; 77 int startY; 78 public boolean onTouch(View v, MotionEvent event) { 79 switch (event.getAction()) { 80 case MotionEvent.ACTION_DOWN://手指按下 81 startX = (int) event.getX(); 82 startY = (int) event.getY(); 83 break; 84 case MotionEvent.ACTION_MOVE://手指滑动 85 int newX = (int) event.getX(); 86 int newY = (int) event.getY(); 87 canvas.drawLine(startX, startY, newX, newY, paint); 88 //重新更新UI 89 iv.setImageBitmap(bitmap); 90 //很重要,重新给开始坐标赋值 91 startX = (int) event.getX(); 92 startY = (int) event.getY(); 93 break; 94 case MotionEvent.ACTION_UP://手指离开屏幕 95 break; 96 } 97 98 return true ;//true ---表示监听事件处理完了, false---表示没有出来完监听事件 99 } 100 }); 101 } 102 public void onClick(View v) { 103 switch (v.getId()) { 104 case R.id.red: 105 paint.setColor(Color.RED); 106 Toast.makeText(this, "设置画笔颜色为红色", 0).show(); 107 break; 108 case R.id.green: 109 paint.setColor(Color.GREEN); 110 Toast.makeText(this, "设置画笔颜色为绿色", 0).show(); 111 break; 112 case R.id.blue: 113 paint.setColor(Color.BLUE); 114 Toast.makeText(this, "设置画笔颜色为蓝色", 0).show(); 115 break; 116 default: 117 break; 118 } 119 } 120 121 //保存图片 122 public void save(View view) { 123 try { 124 File file = new File(Environment.getExternalStorageDirectory(),SystemClock.uptimeMillis()+".png"); 125 FileOutputStream stream = new FileOutputStream(file); 126 //第一个参数是保存的图片类型;第二个参数是画质(100是完美画质),第三个参数是输出流 127 //保存图片类型为PNG支持透明度 128 bitmap.compress(CompressFormat.PNG, 100, stream); 129 stream.close(); 130 Toast.makeText(this, "保存成功,文件路径为:"+file.getAbsolutePath(), 0).show(); 131 132 //Android手机系统自带"图库",里面只有开机的时候 或者是 插入SD卡时候才会扫描里面的资源,这里我们可以欺骗系统,模拟发送SD插入的广播给系统 133 Intent intent = new Intent(); 134 intent.setAction(Intent.ACTION_MEDIA_MOUNTED); 135 intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory())); 136 sendBroadcast(intent); 137 } catch (Exception e) { 138 // TODO 自动生成的 catch 块 139 e.printStackTrace(); 140 Toast.makeText(this, "保存失败,请检查路径", 0).show(); 141 } 142 } 143 }
运行结果如下:
保存图片:
SD保存数据如下:
导出图片1244274.png到桌面上,如下: