【Android】用Android写个自己的画板APP

Android Studio 实现的画板App 基于Android Studio 实现的画板App ** 1.实现目标** 随着科技的不断发展和社会的不断进步,手机越来越流行,成为了人们日常生活和学习的必要工具,人们越来越离不开手机,还在几年前手机仅仅是一个打电话和发短信的工具,但在地球村的今天,手机无论除了可以满足基木的通讯作用以外,还成为了人们办公和娱乐的必不可少的工具。当然手机画板也成为了手机的一个基木的app软件,以前人们想画画必须在纸上或者自己携带的画板上,对于现在人们快节奏的生活不是非常方便。而手机画板的出现打破了这个固有的僵局,它可以满足人 阅读详情

1.常规操作,创建项目

[外

2.清单文件给权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.canvas">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Map">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qvtFTYIc-1652364651356)(https://juejin.cn/ “点击并拖拽以移动”)]

3.布局文件

<LinearLayout 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:orientation="vertical"
    android:paddingLeft="5dp"
    android:paddingTop="5dp"
    android:paddingRight="5dp"
    android:paddingBottom="5dp"
    tools:context=".MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <Button
            android:id="@+id/btn_resume"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="重新画图" />
        <Button
            android:id="@+id/btn_save"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="保存图片" />
    </LinearLayout>
    <ImageView
        android:id="@+id/iv_canvas"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

4.主活动

package com.example.canvas;

import androidx.appcompat.app.AppCompatActivity;

import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.File;
import java.io.FileOutputStream;

public class MainActivity extends AppCompatActivity {
    private Button btn_save,btn_resume;
    private ImageView iv_canvas;
    private Bitmap baseBitmap;
    private Canvas canvas;
    private Paint paint;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //初始化画笔
        paint = new Paint();
        paint.setStrokeWidth(5);
        paint.setColor(Color.RED);

        iv_canvas = findViewById(R.id.iv_canvas);
        btn_save = findViewById(R.id.btn_save);
        btn_resume = findViewById(R.id.btn_resume);

        btn_save.setOnClickListener(click);
        btn_resume.setOnClickListener(click);
        iv_canvas.setOnTouchListener(touch);//屏幕触摸事件监听器
    }
    private View.OnClickListener click = new View.OnClickListener(){

        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_save:
                    saveBitmap();
                    break;
                case R.id.btn_resume:
                    resumeCanvas();
                    break;
                default:
                    break;
            }
        }
    };
    private View.OnTouchListener touch = new View.OnTouchListener() {
        //定义手指开始触屏的坐标
        float startX;
        float startY;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()){
                case MotionEvent.ACTION_DOWN:
                    if(baseBitmap==null){
                        baseBitmap = Bitmap.createBitmap(iv_canvas.getWidth(),iv_canvas.getHeight(),Bitmap.Config.ARGB_8888);
                        canvas = new Canvas(baseBitmap);
                        canvas.drawColor(Color.WHITE);
                    }
                    startX = event.getX();
                    startY = event.getY();
                    break;
                //手指在屏幕上移动的动作
                case MotionEvent.ACTION_MOVE:
                    //记录移动位置上移动的动作
                    float stopX = event.getX();
                    float stopY = event.getY();
                    //根据两点坐标,绘制连线
                    canvas.drawLine(startX,startY,stopX,stopY,paint);
                    //更新开始点的位置
                    startX = event.getX();
                    startY = event.getY();
                    //把图片展示到ImageView中
                    iv_canvas.setImageBitmap(baseBitmap);
                    break;
                case MotionEvent.ACTION_UP:
                    break;
                default:
                    break;
            }
            return true;
        }
    };


    //保存到SD卡
    protected  void saveBitmap(){
        try{
        File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis() + ".png");
         FileOutputStream stream = new FileOutputStream(file);
         baseBitmap.compress(Bitmap.CompressFormat.PNG,100,stream);
            Toast.makeText(MainActivity.this, "保存图片成功", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent();
            intent.setAction(Intent.ACTION_MEDIA_MOUNTED);
            intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
            sendBroadcast(intent);
        }catch (Exception e){
            Toast.makeText(MainActivity.this, "保存图片失败", Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }
    protected void resumeCanvas(){
        if(baseBitmap != null){
            baseBitmap = Bitmap.createBitmap(iv_canvas.getWidth(),iv_canvas.getHeight(),Bitmap.Config.ARGB_8888);
            canvas = new Canvas(baseBitmap);
            canvas.drawColor(Color.WHITE);
            iv_canvas.setImageBitmap(baseBitmap);
            Toast.makeText(MainActivity.this, "清除画板成功 重新绘画", Toast.LENGTH_SHORT).show();
        }
    }
}

5.运行,记得在虚拟机给应用权限


6.可以使用你自己的应用了


​

Android & Kotlin:通过实现画板App学习onTouchEvent 之前几个例子中经常使用到onClick,今天学习一下onTouchEvent。onTouchEvent和onClick是不同的事件,click只是点击一次,onTouchEvent是观察整个touch过程。 0.效果展示 1. 布局 1.1 RelativeLayout 之前都是使用LinearLayout进行布局,还有一种布局使用也挺多的:RelativeLayout,可以通过相对定位的方式让控件出现在布局的任何位置。 通过描述跟父组建或是其他组建关系进行布局,如下为布局使用设置: layout 阅读详情

相关推荐

Android studio 学习3:实现倒计时、画板

Android studio 学习:实战简单倒计时APP、画板APP 1、倒计时APP 运行图示: xml代码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http...

tiganzhesuiyue的博客 1330

【Android入门03】从0开发一个绘画板

前言 前2章我们已经学习了如何制作一个计算器,如何制作一个手势解锁页面。不过这些都只是开胃菜,并不能算一个比较完整的程序。今天我们就来学习一下如何开发一个较为完整的应用——绘画板。本文主要分为界面搭建和实现逻辑两个部分。 需求分析 在进行程序开发之前,我们首先需要明确这个应用应该具备什么功能。一个合格的绘画板,首先应该具有如下功能: 1.调节画笔粗细,画笔颜色功能 2.橡皮擦功能 3.撤销功能 在实现了基本功能后,你还可以选择对功能进行扩充,如: 1.将作品保存到本地,并进行分享 2.从本地相册选择图片,

n0ahmayberry的博客 1660

android简单调色画板

这次是基于调色板上改的画板,上面的---------1.---------------2.------------------3.-------------------4是相互对应的,方便看主要代码: (MainActivity.java) package com.example.color; import java.io.File; import java.io.FileOutputSt

hanhandann的博客 1279

Android 画板小工具

这个demo的功能还是相对比较简单的,然后没有什么好讲的,只不过这个demo中有涉及到Android 的运行时权限申请,兼容Android13的,可以重点关注一下,其他的都是UI层的东西,基本上把代码复制过去,就可以用了,真的有什么问题了,评论区留言。先看一下效果,吐槽一下csdn的视频上传,质量压缩的比较厉害,然后比例也发生变化了,反正是大家凑合看吧,文末会放源码(我的所有demo的源码都是不需要积分的)1.自定义画板SignatureView。Android画板小工具测试视频。我主要放一下关键代码吧。

邵旺运的博客 706

Android实现画板工具 (实现涂写、清除、擦除、保存功能)

一. 效果预览: 二. 实现代码: 1. MyPaintToolsActivity: 自定义一个空的Activity为MyPaintToolsActivity,写入下面代码: package com.example.draw; import androidx.appcompat.app.AppCompatActivity; import android.annotation.SuppressLint; import android.content.Intent; import android.gra

go 6136

浙政钉(专有钉钉)门户免登(超详细)

钉钉家族 介绍浙政钉门户免登之前,首先搞清楚几个软件的关系,软件分别是:钉钉,专有钉钉,浙政钉 钉钉 是阿里巴巴集团专为中小企业打造的沟通和协同的多端平台。 专有钉钉 原名 政务钉钉,有更开放的设计能力、集成能力、更结构化协同产品、更定制化开发平台。支持专有化部署,数据落本地,更安全、客户可对该产品持牌运营、结构化编排,协助构建本地应用中心、提供移动应用全面安全保障体系。 浙政钉 为规范浙政钉整体架构体系,按照统分结合原则,由省政府办公厅统一设计整体工作界面和系统框架,统筹指导全省统建应用建设,各单

一缕南风的博客 2万+

Android 自定义画板

自定义画板 电子签名

qq_57197323的博客 734

硅纪元应用测评 | AI搜索引擎大比拼:360AI搜索、秘塔搜索、GenSpark AI和天工AI对比评测

搜索引擎输出的每个段落都有对应的出处,如果有错误,也是信息源的问题,从普通用户的角度来看,这与AI搜索的产品关系不大,能让用户对AI搜索的服务和得到的信息有一个隔离。同时,提供更多的定制选项,允许用户根据自己的偏好调整搜索结果的权重和排序,将使得搜索体验更加个性化和满足用户的具体需求。此外,大部分搜索工具还提供了一个无广告的搜索环境(360AI搜索部分内容会有广告),极大地提升了用户的搜索体验。AI搜索的本质依然是搜索,但它通过AI的逻辑分析和语言重新组织,使用户能够快速得到想要的信息。

guijiyuantech的博客 2013

Android如何实现画板功能?

Android实现画板主要有2种方式,一种是用自定义View实现,另一种是通过Canvas类实现。当然自定义View内部也是用的Canvas。本文将分析两种方法,第一种就是用SurfaceView来实现,在这里介绍一下关于SurfaceView的知识:SurfaceView继承自View,两者都可以实现绘图功能,那么他们有什么不同呢? 先说下Android绘制视图的原理——View通过刷新来绘制视图,Android系统则通过发出VSYNC信号进行屏幕绘制,玩游戏的朋友都应该知道"垂直同步",VSYNC就是垂

大模型学习路线 1536

给STM32F4装上耳朵:用麦克风模块和Keil MDK实现你的第一个语音指令(附完整代码)

本文详细介绍了如何使用STM32F4开发板和麦克风模块实现简单的语音指令识别系统。通过Keil MDK开发环境配置、ADC音频采样、语音活动检测和模板匹配算法,开发者可以快速构建响应'开灯'、'关灯'等基础指令的语音交互方案。文章包含完整代码实现和调试技巧,特别适合STM32初学者入门语音识别领域。

weixin_29171087的博客 436

零基础小白Coze知识普及【新手必备资料!!】

AI智能体|扣子(Coze)工作流搭建【零基础小白Coze知识普及】 1、领取100+工作流源码!复制到扣子即可直接使用 2、AI认知+9节商业智能体拆解 3、500+各行业高质量提示词 4、超低价格使用即梦文生图图生视频和banana生图

Zhima0522的博客 3254

【安卓】自定义View实现画板涂鸦等功能

绘制主要用到Paint和Path,大体思路都是监听OnTouchEvent事件,绘制路径或者其他图案,开发这个项目用时一周。

小李不背锅的博客 2030

XGBoost详解(原理篇)

XGBoost全称为eXtreme Gradient Boosting,即极致梯度提升树。XGBoost是Boosting算法的其中一种,Boosting算法的思想是将许多弱分类器集成在一起,形成一个强分类器(个体学习器间存在强依赖关系,必须串行生成的序列化方法)。Note:关于Boosting算法详见博文集成学习详解_tt丫的博客-优快云博客XGBoost是一种提升树模型,即它将许多树模型集成在一起,形成一个很强的分类器。其中所用到的树模型则是CART回归树模型。

tt丫的博客 7万+

uniapp-原生地图截屏返回base64-进行画板编辑功能

1. 由 原生地图nvue部分,回调返回 地图截屏生成的base64 数据 2. 通过 uni插件市场image-tools 插件base64ToPath方法,将base64数据 转成文件路径 3. 通过 uni -API-uni.createCanvasContext() 、ctx.createPattern() 方法,将 图片数据创建绘图对象 4. 通过 uni -movable-area+movable-view 控制画布缩放 5. 通过canvas@touchmove等实现画布画线

徐子厚的博客 1716

R语言dplyr包recode函数、recode_factor函数数值或因子替换实战

R语言dplyr包recode函数、recode_factor函数数值或因子替换实战 目录 R语言dplyr包recode函数、recode_factor函数数值或因子替换实战 #导入dplyr包 #recode函数进行数值替换 #recode_factor函数对因子变量进行替换 #导入dplyr包 install.packages("dplyr") # Install & load dplyr library("dpl.

data+scenario+science+insight 1592

如何创建 SAP ABAP CDS View 的 Association

所以本文我们虽然学习了如何创建 SAP CDS View 的 association,知道了 association 是用来在 CDS View 里将两张数据库表关联起来,但根本不知道怎么使用这个 association. 而且从 association 的写法来看,似乎和本教程之前介绍 inner join,left join 这些数据库表的连接操作没什么区别,都是根据两张表的 carrid 和 connid 字段相同进行的连接。只看到了我们在 CDS View 源代码实现里,放出来的四个字段。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 904

初探安卓画板

在java学习使用画板到现在貌似都快半年了,初探安卓的自定义组件使用到画板感觉非常不适用的样子。 在java使用的画板跟安卓的画板是有挺大的区别,下面记录一下学校安卓的画板的使用  在java当中,话矩形圆形都是空心的,而在安卓默认却是填满的 java当中使用Graphcs.draw--   而在安卓却是吧画布当作参数放在后面…… package com.example.gaosi.ble

gaosililin的专栏 705

C#函数返回多个值实现实例

本文实例讲解C#函数返回多个值多种实现方法。

qq_30725967的博客 1170

Android 实现一个简单的画板功能

一.效果图: 二.快速实现: 支持撤销(undo); 支持反撤销(redo); 支持橡皮擦(eraser); 支持清除功能(clear); 支持保存为图像(save) 1.主函数代码: import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.net.

shenggaofei的博客 3483

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android简单画板的实现

画板主要功能的实现需要3步: 1、创建画板; 2、添加画笔及绘制; 3、清除画板。 主活动部分代码: import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.View; im

我真的好老实 2752

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Android画板

Android画板: 本案例是一个简单的Android小应用,仅供大家学习 MyView.java package com.example.drawboard; import android.R.color; import android.content.Context; import android.graphics.Canvas; import android.graphics.Col

wszsj的博客 935

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

【安卓开发】Android实现画板

画板,手写板的实现

我们都有光明的未来 1570

Android画板(三):WhiteBoard画板开源库

SketchBoard项目简介 SketchBoard是一个可涂鸦、绘图、添加文字、图像(可旋转缩放)、背景的Fragment,其中主要由SketchView利用matrix完成所有图形绘制操作。 tips:图像旋转缩放高仿美图APP的操作方式 tips: 感谢

qq_32138419的博客 3467

android 绘画开源,Android 开源可缩放平移的绘画板

ScaleSketchPadDemo此项目包含两个模块app1 为普通绘画板app2 为可所发的绘画板方便各位Android 开发者理解和使用用法:clone or download 项目到本地,打开Android Studio—>file—>new—>import new moudle—>选中本地的app或aap2项目简介普通绘画板可缩放平移绘画板效果图事件图uml图普通...

weixin_35604021的博客 1098
上一篇: 解密Kotlin 1.6.20 新功能 Context Receivers
下一篇: Android Studio3.4新功能和改进
不秃头de程序猿
博客等级 码龄5年 4089粉丝 1478原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值