public class MainActivity extends Activity
{
int width,height;
private GameView gameview;
private Canvas canvas;
private Bitmap map;
private Paint paint;
public Path path;
private int color,pen;
private boolean isclear=true;
@SuppressWarnings("deprecation")
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); //获得手机屏幕的宽度和高度
width=getWindowManager().getDefaultDisplay().getWidth();
height=getWindowManager().getDefaultDisplay().getHeight(); //设置手机为全屏模式
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); gameview=new GameView(this, width, height); setContentView(gameview);
canvas=gameview.canvas;
map=gameview.map;
paint=gameview.paint;
path=gameview.dpath;
color=gameview.color;
} //创建菜单
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
} //添加菜单事件监听
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.save:
try
{
Random random=new Random();
int a=random.nextInt(100);//产生100以内的数据
File f=new File(Environment.getExternalStorageDirectory().getPath()+"/bitmap");
f.mkdir();
File file=new File(f,a+".jpg");
FileOutputStream outstream=new FileOutputStream(file); map.compress(Bitmap.CompressFormat.PNG, 90, outstream);
//把bitmap对象保存一张jpg的图片 Toast.makeText(this, "保存成功!", Toast.LENGTH_LONG).show();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
break;
case R.id.Color:
if(path!=null)
{
canvas.drawPath(path, paint);
gameview.invalidate();
}
Builder dialog=new AlertDialog.Builder(this);
dialog.setSingleChoiceItems(new String[]{"红色","绿色","黄色","粉色"}, 0, new OnClickListener()
{
public void onClick(DialogInterface arg0, int arg1) {
switch (arg1)
{
case 0:
paint.setColor(Color.RED);
break;
case 1:
paint.setColor(Color.GREEN);
break;
case 2:
paint.setColor(Color.YELLOW);
break;
case 3:
paint.setColor(Color.MAGENTA);
break;
}
pen=paint.getColor();
}
});
dialog.setPositiveButton("确定", null).create();
dialog.show();
gameview.invalidate();
break;
case R.id.Paintsize:
paint.setStrokeWidth(5);
gameview.invalidate();
break;
case R.id.background:
canvas.drawColor(Color.DKGRAY);
color=Color.CYAN;
gameview.invalidate();
break;
case R.id.clear:
path=new Path();
gameview.invalidate();
break;
}
return super.onOptionsItemSelected(item);
} } 2.绘图操作的GameView类 public class GameView extends View implements OnTouchListener {
private float mx,my;//用来存手指移动后的坐标
public Bitmap map;//对图像的一些操作
public Canvas canvas;
public Path dpath;//主要用来绘制图像的对象,他会把所有绘制的图像保存到path里面
public Paint paint;//画笔
public int color;
public GameView(Context context,int width,int height) {
super(context);
map=Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_4444);//绘制一个与手机屏幕大小的BitMap对象
canvas=new Canvas(map);
paint=new Paint();
paint.setAntiAlias(true);//消除锯齿
paint.setStyle(Style.STROKE);//设置画笔结尾时的样式为圆润
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.SQUARE);
paint.setColor(Color.MAGENTA);
paint.setStrokeWidth(3); this.setOnTouchListener(this);//添加触屏操作
} public void draw(Canvas canvas) {
super.draw(canvas);
canvas.drawColor(Color.WHITE);//这里具有清屏的意思
color=Color.DKGRAY;
canvas.drawBitmap(map, 0,0, paint);//从 0 0开始到map中的width,height的一块画布,也就是全屏幕的一块画布 //保存上次绘制的路径,只要他不为空就绘制出上次绘制的图形
if(dpath!=null)
{
canvas.drawPath(dpath, paint);
}
} public void touch_start(float x,float y)
{
dpath.moveTo(x, y);//设置绘制图形的起始点
}
public void touch_move(float x,float y)
{
// 从x1,y1到x2,y2画一条贝塞尔曲线,更平滑(直接用mPath.lineTo也是可以的)
dpath.lineTo(x,y);
mx = x;//把手指移动后的坐标存放到mx,my中,
my = y;
}
public void touch_up()
{
dpath.lineTo(mx, my);//设置手指从按下到移动过后之间绘制一条线存放到path中,之后通过下面的方法绘制到屏幕上
canvas.drawPath(dpath, paint);
}
public boolean onTouch(View arg0, MotionEvent event)
{
float x = event.getX()获得手指放下的坐标
float y = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
// 每次down下去重新new一个Path,这是一个要注意的地方,每一次手指从触摸屏幕到离开屏幕,都是一次新的path路径,所以要重新绘制一个新的Path对象
dpath = new Path();
touch_start(x, y);//设置起始点
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
//invalidate();
break;
}
return true;
} }

Andoid实现手动绘图的更多相关文章

  1. winform的扩展的带有截图功能picturebox

    using System; using System.ComponentModel; using System.Diagnostics; using System.Drawing; using Sys ...

  2. css切背景图片(background-position)

    给元素添加背景图片的方式有很多,个人总结的有: 用img插入图片: css3的方式手动绘图: 单独用background-image单独插入图片: 其中用background-image有两种方法,一 ...

  3. 【深度学习系列】PaddlePaddle可视化之VisualDL

    上篇文章我们讲了如何对模型进行可视化,用的keras手动绘图输出CNN训练的中途结果,本篇文章将讲述如何用PaddlePaddle新开源的VisualDL来进行可视化.在讲VisualDL之前,我们先 ...

  4. AT2165 Median Pyramid Hard

    题目链接:戳我 一看范围1e5,往二分上想. 可是再怎么也没有想到这个神仙的二分答案qwq 我们二分一个数x,设比他大的数为1,小于等于他的数为0.那么我们就可以把原来的那个转化成一个01塔. 然后我 ...

  5. matplotlib 可视化 —— 移动坐标轴(中心位置)

    通常软件绘图,包括 matlab.python 的 matplotlib,默认都是将坐标轴置于画布(figure)的最下侧(x 轴),最左侧(y 轴),也即将坐标原点置于左下角.而我们自己理解数学,以 ...

  6. DNN的BP算法Python简单实现

    BP算法是神经网络的基础,也是最重要的部分.由于误差反向传播的过程中,可能会出现梯度消失或者爆炸,所以需要调整损失函数.在LSTM中,通过sigmoid来实现三个门来解决记忆问题,用tensorflo ...

  7. 浅谈 UNIX、Linux、ios、android 他们之间的关系

    开源Linux 一个执着于技术的公众号 Unix, 简化形成了Linux,Linux则是Android的内核,而苹果则是使用unix系统作为ios和macos的内核. 几个系统出现的时间 UNIX系统 ...

  8. VC++大数据量绘图时无闪烁刷屏技术实现(我的理解是,在内存上作画,然后手动显示,而不再直接需要经过WM_PAINT来处理了)

    http://hantayi.blog.51cto.com/1100843/383578 引言 当我们需要在用户区显示一些图形时,先把图形在客户区画上,虽然已经画好但此时我们还无法看到,还要通过 程序 ...

  9. 第十篇:扩展SOUI的控件及绘图对象(ISkinObj)

    尽管SOUI已经内置了大部分常用的控件,很显然内置控件很难满足各种应用的形式各异的需求. 因此只有提供足够的扩展性才能满足真实应用场景. 除了将系统尽可能的组件化外,SOUI在控件自绘(SWindow ...

随机推荐

  1. LaTex希腊字母

    Name Symbol Command Alpha $\alpha$ $A$ \alpha A Beta $\beta$ $B$ \beta B Gamma $\gamma$ $\Gamma$ \ga ...

  2. oracle中LAG()和LEAD()等分析统计函数的使用方法(统计月增长率)

    LAG()和LEAD()统计函数能够在一次查询中取出同一字段的前N行的数据和后N行的值.这样的操作能够使用对同样表的表连接来实现,只是使用LAG和 LEAD有更高的效率.下面整理的LAG()和LEAD ...

  3. 灵活性比Listview更好的RecycleView

    RecycleView:是Android L版本中新添加的一个用来取代ListView的SDK,它的灵活性与可替代性比listview更好. RecyclerView与ListView原理是类似的:都 ...

  4. EventBus 事件总线 案例

    简介 地址:https://github.com/greenrobot/EventBus EventBus是一个[发布 / 订阅]的事件总线.简单点说,就是两人[约定]好怎么通信,一人发布消息,另外一 ...

  5. EF code first 生成edmx文件

    通过下面的代码,你就可以拿到EF心中的地图 —— edmx文件. using (var context = new Context()) { XmlWriterSettings settings = ...

  6. CSS中伪类的使用

    原文:http://www.cnblogs.com/guopei/archive/2011/04/16/2017627.html 何为伪类? 也就是实际实现了类的效果,但是并没有实际添加到标签中的类, ...

  7. BIOS+MBR模式 VS UEFI+GPT模式

     EFI与MBR启动的区别 大硬盘和WIN8系统,让我们从传统的BIOS+MBR模式升级到UEFI+GPT模式,现在购买的主流电脑,都是预装WIN8系统,为了更好的支持2TB硬盘 ,更快速的启动win ...

  8. react-redux源码解析

    有理解不对的地方,欢迎大家指正!!! react为什么需要redux辅助???react是view层的单向数据流框架,数据需要一层一层往子组件传递(子组件并不会自动继承).子组件需要操作父组件的数据时 ...

  9. [转]C++堆和栈的区别

    一.预备知识―程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)― 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. ...

  10. Windows 批处理文件

    窗口自动关闭:批处理文件执行完之后,窗口会自动关闭,若想执行完之后,窗口不自动关闭的话,在文件末尾添加1. 批处理文件执行完之后,窗口会自动关闭2. 若想执行完之后,窗口不自动关闭的话,在文件末尾添加 ...