今天完成一个画画板。

首先来个布局:

<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <ImageView
android:id="@+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_alignParentBottom="true"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="红色"
android:onClick="red"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绿色"
android:onClick="green"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="刷子"
android:onClick="brush"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="保存"
android:onClick="save"
/>
</LinearLayout>
</RelativeLayout>

可见,要分红绿色,而且还要保存最后画的图片。

看一下主活动代码:

package com.itydl.paintban;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView; public class MainActivity extends Activity { private ImageView iv; int startX;
int startY; private Canvas canvas; private Paint paint; private Bitmap bmCopy;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //加载画画板的背景图
Bitmap bmSrc = BitmapFactory.decodeResource(getResources(), R.drawable.bg); bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());
paint = new Paint();
canvas = new Canvas(bmCopy);
//绘制
canvas.drawBitmap(bmSrc, new Matrix(), paint); iv = (ImageView) findViewById(R.id.iv);
iv.setImageBitmap(bmCopy); //设置触摸侦听
iv.setOnTouchListener(new OnTouchListener() { //触摸屏幕时,触摸事件产生时,此方法调用
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
//用户手指摸到屏幕
case MotionEvent.ACTION_DOWN:
startX = (int) event.getX();
startY = (int) event.getY();
break;
//用户手指正在滑动
case MotionEvent.ACTION_MOVE:
int x = (int) event.getX();
int y = (int) event.getY();
canvas.drawLine(startX, startY, x, y, paint);
//每次绘制完毕之后,本次绘制的结束坐标变成下一次绘制的初始坐标
startX = x;
startY = y;
iv.setImageBitmap(bmCopy);
break;
//用户手指离开屏幕
case MotionEvent.ACTION_UP:
break; }
//true:告诉系统,这个触摸事件由我来处理
//false:告诉系统,这个触摸事件我不处理,这时系统会把触摸事件传递给imageview的父节点
return true;
}
}); } public void red(View v){
paint.setColor(Color.RED);
}
public void green(View v){
paint.setColor(Color.GREEN);
}
public void brush(View v){
paint.setStrokeWidth(7);
}
public void save(View v){
File file = new File("sdcard/dazuo.png");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bmCopy.compress(CompressFormat.PNG, 100, fos); //发送sd卡就绪广播
Intent intent = new Intent();
intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
sendBroadcast(intent);
}
}

运行看一下结果:

画了个绿帽子,哈哈。欢迎关注本博客点击打开链接  http://blog.csdn.net/qq_32059827,每天花上5分钟,阅读一篇有趣的安卓小文哦。

Android简易实战教程--第二十四话《画画板》的更多相关文章

  1. Android简易实战教程--第二十九话《创建图片副本》

    承接第二十八话加载大图片,本篇介绍如何创建一个图片的副本. 安卓中加载的原图是无法对其修改的,因为默认权限是只读的.但是通过创建副本,就可以对其做一些修改,绘制等了. 首先创建一个简单的布局.一个放原 ...

  2. Android简易实战教程--第二十六话《网络图片查看器在本地缓存》

    本篇接第二十五话  点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52389856 上一篇已经把王略中的图片获取到了.生活中有这么 ...

  3. Android简易实战教程--第二十八话《加载大图片》

    Android系统以ARGB表示每个像素,所以每个像素占用4个字节,很容易内存溢出.假设手机内存比较小,而要去加载一张像素很高的图片的时候,就会因为内存不足导致崩溃.这种异常是无法捕获的 内存不足并不 ...

  4. Android简易实战教程--第二十五话《网络图片查看器》

    访问网络已经有了很成熟的框架.这一篇只是介绍一下HttpURLConnection的简单用法,以及里面的"注意点".这一篇可以复习或者学习HttpURLConnection.han ...

  5. Android简易实战教程--第十四话《模仿金山助手创建桌面Widget小部件》

    打开谷歌api,对widget小部件做如下说明: App Widgets are miniature application views that can be embedded in otherap ...

  6. Android简易实战教程--第十六话《SharedPreferences保存用户名和密码》

    之前在Android简易实战教程--第七话<在内存中存储用户名和密码> 那里是把用户名和密码保存到了内存中,这一篇把用户名和密码保存至SharedPreferences文件.为了引起误导, ...

  7. Android简易实战教程--第十五话《在外部存储中读写文件》

    第七话里面介绍了在内部存储读写文件 点击打开链接. 这样有一个比较打的问题,假设系统内存不够用,杀本应用无法执行,或者本应用被用户卸载重新安装后.以前保存的用户名和密码都不会得到回显.所以,有必要注意 ...

  8. Android简易实战教程--第二十话《通过广播接收者,对拨打电话外加ip号》

    没睡着觉,起来更篇文章吧哈哈!首先祝贺李宗伟击败我丹,虽然我是支持我丹的,但是他也不容易哈哈,值得尊敬的人!切入正题:这一篇来介绍个自定义广播接收者. 通常我们在外拨电话的时候,一般为使用网络电话.如 ...

  9. Android简易实战教程--第二十二话《自定义组合控件模拟qq登录下拉框和其中的一些”小技巧”》

    转载此文章请注明出处:点击打开链接   http://blog.csdn.net/qq_32059827/article/details/52313516 首先,很荣幸此专栏能被CSDN推荐到主页.荣 ...

随机推荐

  1. POJ 3261 可重叠k次最长重复子串

    Milk Patterns Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 13127   Accepted: 5842 Ca ...

  2. 后缀自动机模板(SPOJ1811)

    用后缀自动机实现求两个串的最长公共子串. #include <cstdio> #include <algorithm> ; char s[N]; ]; int main() { ...

  3. SpringBoot学习之SpringBoot执行器

    在以往的分布式开发当中,各个服务节点的监控必不可少.监控包含有很多方面,比如说:内存占用情况,节点是否健康等.在spring-boot会给我们提供相关资源监控叫做spring-boot-actuato ...

  4. 华科机考:a+b

    时间限制:1秒     空间限制:32768K 题目描述 实现一个加法器,使其能够输出a+b的值. 输入描述: 输入包括两个数a和b,其中a和b的位数不超过1000位. 输出描述: 可能有多组测试数据 ...

  5. 华科机考:IP地址

    时间限制:1秒  空间限制:32768K 题目描述 输入一个ip地址串,判断是否合法. 输入描述: 输入的第一行包括一个整数n(1<=n<=500),代表下面会出现的IP地址的个数. 接下 ...

  6. java中如何在代码中判断时间是否过了10秒

    long previous = 0L; ... { Calendar c = Calendar.getInstance(); long now = c.getTimeInMillis(); //获取当 ...

  7. ios html5 audio 不能自动播放

    //修复ios 浏览器不能自动播放音频的问题 在加载时创建新的audio 用的时候更换src即可 Xut.fix = Xut.fix||{}; if (Xut.plat.isBrowser & ...

  8. web性能优化之--合理使用http缓存和localStorage做资源缓存

    一.前言 开始先扯点别的: 估计很多前端er的同学应该遇到过:在旧项目中添加新的功能模块.或者修改一些静态文件时候,当代码部署到线上之后,需求方验收OK,此时你送了一口气,当你准备开始得意于自己的ma ...

  9. --save-dev 和 --save的区别

    1. 我们在使用npm install xx --save-dev / --save安装模块或插件的时候,会将他们写入到 package.json 文件,那到底有什么区别呢? --save-dev:会 ...

  10. 浅析JS异步执行机制

    前言 JS异步执行机制具有非常重要的地位,尤其体现在回调函数和事件等方面.本文将针对JS异步执行机制进行一个简单的分析. 从一份代码讲起 下面是两个经典的JS定时执行函数,这两个函数的区别相信对JS有 ...