Android简易实战教程--第二十四话《画画板》
今天完成一个画画板。
首先来个布局:
<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简易实战教程--第二十四话《画画板》的更多相关文章
- Android简易实战教程--第二十九话《创建图片副本》
承接第二十八话加载大图片,本篇介绍如何创建一个图片的副本. 安卓中加载的原图是无法对其修改的,因为默认权限是只读的.但是通过创建副本,就可以对其做一些修改,绘制等了. 首先创建一个简单的布局.一个放原 ...
- Android简易实战教程--第二十六话《网络图片查看器在本地缓存》
本篇接第二十五话 点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52389856 上一篇已经把王略中的图片获取到了.生活中有这么 ...
- Android简易实战教程--第二十八话《加载大图片》
Android系统以ARGB表示每个像素,所以每个像素占用4个字节,很容易内存溢出.假设手机内存比较小,而要去加载一张像素很高的图片的时候,就会因为内存不足导致崩溃.这种异常是无法捕获的 内存不足并不 ...
- Android简易实战教程--第二十五话《网络图片查看器》
访问网络已经有了很成熟的框架.这一篇只是介绍一下HttpURLConnection的简单用法,以及里面的"注意点".这一篇可以复习或者学习HttpURLConnection.han ...
- Android简易实战教程--第十四话《模仿金山助手创建桌面Widget小部件》
打开谷歌api,对widget小部件做如下说明: App Widgets are miniature application views that can be embedded in otherap ...
- Android简易实战教程--第十六话《SharedPreferences保存用户名和密码》
之前在Android简易实战教程--第七话<在内存中存储用户名和密码> 那里是把用户名和密码保存到了内存中,这一篇把用户名和密码保存至SharedPreferences文件.为了引起误导, ...
- Android简易实战教程--第十五话《在外部存储中读写文件》
第七话里面介绍了在内部存储读写文件 点击打开链接. 这样有一个比较打的问题,假设系统内存不够用,杀本应用无法执行,或者本应用被用户卸载重新安装后.以前保存的用户名和密码都不会得到回显.所以,有必要注意 ...
- Android简易实战教程--第二十话《通过广播接收者,对拨打电话外加ip号》
没睡着觉,起来更篇文章吧哈哈!首先祝贺李宗伟击败我丹,虽然我是支持我丹的,但是他也不容易哈哈,值得尊敬的人!切入正题:这一篇来介绍个自定义广播接收者. 通常我们在外拨电话的时候,一般为使用网络电话.如 ...
- Android简易实战教程--第二十二话《自定义组合控件模拟qq登录下拉框和其中的一些”小技巧”》
转载此文章请注明出处:点击打开链接 http://blog.csdn.net/qq_32059827/article/details/52313516 首先,很荣幸此专栏能被CSDN推荐到主页.荣 ...
随机推荐
- UVA 3485 Bridge
题目大意 你的任务是修建一座大桥.桥上等距地摆放着若干个塔,塔高为H,宽度忽略不计.相邻两座塔之间的距离不能超过D.塔之间的绳索形成全等的对称抛物线.桥长度为B,绳索总长为L,如下图所示求建最少的塔时 ...
- [HNOI2015]实验比较
Description 小D 被邀请到实验室,做一个跟图片质量评价相关的主观实验.实验用到的图片集一共有 N 张图片,编号为 1 到 N.实验分若干轮进行,在每轮实验中,小 D会被要求观看某两张随机选 ...
- 2015 多校联赛 ——HDU5316(线段树)
Fantasy magicians usually gain their ability through one of three usual methods: possessing it as an ...
- SPFA小总结
关于spfa 知识点 原始版 ---裸 应用: 一.判负环 两种方法 1.跑单源点bfs,如果某一个点入队了n-1次,存在 2.对于每个点dfs,如果此源点反被其他点更新,存在 证明:点i作为源点,d ...
- BZOJ1187 [HNOI2007]神奇游乐园(插头dp)
麻麻我会写插头dp了! 推荐陈丹琦论文:https://wenku.baidu.com/view/3e90d32b453610661ed9f4bd.html 破题调一年 #include <cs ...
- 在QEMU中调试ARM程序【转】
转自:http://linuxeden.com/html/develop/20100820/104409.html 最近我想调试一个运行在QEMU模拟ARM系统中的Linux程序.我碰到过一些麻烦,因 ...
- jQuery Datetable
先来个官网可以直接看官网 https://www.datatables.net/manual/data/ 安装 DataTables是一个功能强大的Javascript库,用于为HTML表格添加交互 ...
- 剖析Vue原理&实现双向绑定MVVM
转自:http://www.w3cmark.com/2016/496.html 本文能帮你做什么? 1.了解vue的双向数据绑定原理以及核心代码模块 2.缓解好奇心的同时了解如何实现双向绑定 为了便于 ...
- 在vue生命周期中及时销毁全局作用的代码
一.纯客户端中 对于全局的代码,比如定时器等,在 beforeDestroy或 destroyed 生命周期时将其销毁.如果在跳转路由时候,组件销毁了,全局的定时器却没有销毁,这会使得页面产生卡顿. ...
- 导出数据子集:带where条件的exp导出
举个例子:用select * from all_objects创建了一张表T.想要导出object_id小于5000的所有行.(1)windows下: exp userid=cms0929/cms09 ...