В этом примере мы покажем вам, как создать простое приложение для рисования в Android. Вы можете изменить стиль и цвет пера в приложении. Вы также можете сохранить свой рисунок после покраски. Приложение в основном использует пакет android.graphics . Мы можем увидеть снимок экрана и исходный код здесь:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.easyinfogeek.drawingpad"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.easyinfogeek.drawingpad.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Класс активности и класс представления
MainActivity.java
package com.easyinfogeek.drawingpad;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Color;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.view.Window;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
private DrawPadView hbView;
private AlertDialog dialog;
private View dialogView;
private TextView shouWidth;
private SeekBar widthSb;
private int paintWidth;
private void initView(){
dialogView = getLayoutInflater().inflate(R.layout.dialog_width_set, null);
shouWidth = (TextView) dialogView.findViewById(R.id.textView1);
widthSb = (SeekBar) dialogView.findViewById(R.id.seekBar1);
widthSb.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
shouWidth.setText("Current Width:"+(progress+1));
paintWidth = progress+1;
}
});
hbView = (DrawPadView)findViewById(R.id.drawPadView1);
dialog = new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_info).setTitle("Set the size of your Pen").
setView(dialogView).setPositiveButton("Confirm", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
hbView.setPaintWidth(paintWidth);
}
}).setNegativeButton("Cancel", null).create();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
initView();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu colorSm = menu.addSubMenu(1, 1, 1, "Select Pen color");
colorSm.add(2, 200, 200, "red");
colorSm.add(2, 210, 210, "green");
colorSm.add(2, 220, 220, "blue");
colorSm.add(2, 230, 230, "purple");
colorSm.add(2, 240, 240, "yellow");
colorSm.add(2, 250, 250, "black");
menu.add(1, 2, 2, "Set pen size");
SubMenu widthSm = menu.addSubMenu(1, 3, 3, "Set Pen style");
widthSm.add(3, 300, 300, "Stoke");
widthSm.add(3, 301, 301, "Fill ");
menu.add(1, 4, 4, "Clear Drawing");
menu.add(1, 5, 5, "Save drawing");
menu.add(1, 6, 6, "Exit");
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int index = item.getItemId();
switch(index){
case 200:
hbView.setColor(Color.RED);
break;
case 210:
hbView.setColor(Color.GREEN);
break;
case 220:
hbView.setColor(Color.BLUE);
break;
case 230:
hbView.setColor(Color.MAGENTA);
break;
case 240:
hbView.setColor(Color.YELLOW);
break;
case 250:
hbView.setColor(Color.BLACK);
break;
case 2:
dialog.show();
break;
case 300:
hbView.setStyle(DrawPadView.PEN);
break;
case 301:
hbView.setStyle(DrawPadView.PAIL);
break;
case 4:
hbView.clearScreen();
break;
case 5:
if(SaveViewUtil.saveScreen(hbView)){
Toast.makeText(this, "Save drawing succeed!", 0).show();
}else{
Toast.makeText(this, "Save drawing fail. Please check your SD card", 0).show();
}
break;
case 6:
finish();
break;
}
return true;
}
}
DrawPadView.java
package com.easyinfogeek.drawingpad;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class DrawPadView extends View {
private Bitmap cacheBitmap;
private Canvas cacheCanvas;
private Paint paint;
private Paint BitmapPaint;
private Path path;
private int height;
private int width;
/** Last saved X-coordinate */
private float pX;
/** Last saved Y-coordinate*/
private float pY;
/** Initial color */
private int paintColor = Color.RED;
private static Paint.Style paintStyle = Paint.Style.STROKE;
/** Paint Point size */
private static int paintWidth = 3;
private Canvas canvas;
/** get the height and width */
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
height = h;
width = w;
init();
}
private void init(){
cacheBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
cacheCanvas = new Canvas(cacheBitmap);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
path = new Path();
BitmapPaint = new Paint();
updatePaint();
}
private void updatePaint(){
paint.setColor(paintColor);
paint.setStyle(paintStyle);
paint.setStrokeWidth(paintWidth);
}
public DrawPadView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DrawPadView(Context context){
super(context);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getX(), event.getY());
pX = event.getX();
pY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
path.quadTo(pX, pY, event.getX(), event.getY());
pX = event.getX();
pY = event.getY();
break;
case MotionEvent.ACTION_UP:
cacheCanvas.drawPath(path, paint);
path.reset();
break;
}
invalidate();
return true;
}
@Override
protected void onDraw(Canvas canvas) {
this.canvas = canvas;
BitmapPaint = new Paint();
canvas.drawBitmap(cacheBitmap, 0,0, BitmapPaint);
canvas.drawPath(path, paint);
}
public void setColor(int color){
paintColor = color;
updatePaint();
}
public void setPaintWidth(int width){
paintWidth = width;
updatePaint();
}
public static final int PEN = 1;
public static final int PAIL = 2;
public void setStyle(int style){
switch(style){
case PEN:
paintStyle = Paint.Style.STROKE;
break;
case PAIL:
paintStyle = Paint.Style.FILL;
break;
}
updatePaint();
}
/** clear your drawing*/
public void clearScreen(){
if(canvas != null){
Paint backPaint = new Paint();
backPaint.setColor(Color.WHITE);
canvas.drawRect(new Rect(0, 0, width, height), backPaint);
cacheCanvas.drawRect(new Rect(0, 0, width, height), backPaint);
}
invalidate();
}
}
Другой XML-файл для макета:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<com.example.huatuban.DrawPadView
android:id="@+id/drawPadView1"
android:background="#ffffffff"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="setColor" />
<RadioButton
android:id="@+id/radioButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="blue"
android:button="@null"
android:background="@drawable/selector_blueselector"
/>
<Button android:background="@drawable/menu_blue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hehe"/>
</LinearLayout>
dialog_width_set.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Set the width" />
<SeekBar
android:id="@+id/seekBar1"
android:layout_width="match_parent"
android:max="9"
android:progress="2"
android:layout_height="wrap_content" />
</LinearLayout>
Класс
утилит для сохранения изображения SaveViewUtil.java
package com.easyinfogeek.drawingpad;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.os.Environment;
import android.view.View;
public class SaveViewUtil {
private static final File rootDir = new File(Environment.getExternalStorageDirectory()+File.separator+"huaban/");
/** Save picture to file */
public static boolean saveScreen(View view){
//determine if SDCARD is available
if(!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
return false;
}
if(!rootDir.exists()){
rootDir.mkdir();
}
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
try {
bitmap.compress(CompressFormat.JPEG, 100, new FileOutputStream(new File(rootDir,System.currentTimeMillis()+".jpg")));
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}finally{
view.setDrawingCacheEnabled(false);
bitmap = null;
}
}
}